본문 바로가기

Back-End/SpringBoot

[SpringBoot/Java17] Java 17 Record 활용(nested class, @Builder 사용, Class와 비교)

이번에 들어간 신규 프로젝트는 Java 17 버전을 사용하기로 했다.
사용하기 전에 java 17 새로운 기능들을 좀 찾아보니 그나마 record를 잘 활용할 수 있겠다고 생각했다.

 

Java 17 새로운 기능

https://springframework.guru/what-is-new-in-java-17/

 

What is New in Java 17? - Spring Framework Guru

A number of new features have been added to the Java programming language in the Java 17 release. In this post learn about what's new!

springframework.guru

https://e-una.tistory.com/46

 

Java 17, 무엇이 바뀌었을까?

9월 14일 오라클은 Java 17을 릴리즈했다. Java 8, 11에 이은 LTS(Long-Term Support) 버전으로 오라클은 2년마다 LTS 버전을 릴리즈하고 있다. 이번 토이 프로젝트에 사용하기 위해 몇 가지 변경 사항을 정리

e-una.tistory.com

 

 

Record 특징

- 불변 객체, 모든 필드는 final로 정의됨

- @AllAgrsContructor 어노테이션과 같은 생성자 제공

- Getter, equals, hashCode, toString 메소드 기본 제공

- class 상속 불가능, interface 구현 가능

=> 롬복 사용을 줄일 수 있음

 

 

DTO를 Record 타입으로 생성

- Java 11에서 DTO

public class MemberDTO {
    
    @Getter
    @Setter
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    public static class CreationRequest{
        
        private String name;
        
        private String email;
        
        private String password;
    }
}

- Record 사용한 DTO

public class MemberDTO {

    public record CreationRequest(

        String name,
        String email,
        String password
    ){}
}

훨씬 간결해졌다.

https://velog.io/@yhlee9753/nested-record-class-%EC%9D%98-%EB%8C%80%ED%95%9C-%EA%B3%A0%EB%AF%BC

 

nested record class 사용해도 괜찮을까?

JPA 프로젝트를 수행하는 도중 특정 Entity 에 대한 DTO 를 update, save 등의 케이스마다 클래스를 분류하면 너무 많은 클래스가 생길거란 생각이 들었다. 따라서 1개의 클래스 내부에 관련된 DTO 를 Reco

velog.io

 

 

Record @Builder 어노테이션 사용하는 법

public class MemberDTO {

    public static record CreationRequest(

        String name,
        String email,
        String password
    ){
    
    @Builder
    public CreationRequest{}
    
    }
}

static record로 변경 후 생성자를 만든 후 위에 @Builder 어노테이션을 붙인다.

https://stackoverflow.com/questions/69825016/lomboks-builder-not-detecting-fields-of-the-java-record

 

Lombok's @Builder not detecting fields of the Java Record

I am trying to implement the builder pattern using Lombok's @Builder but it does not detect any of the record fields: @Builder(builderMethodName = "internalBuilder") public record ApiError(

stackoverflow.com

 

 

Record vs Class

- record는 Entity의 역할을 하지 못한다.

https://velog.io/@power0080/java%EC%9E%90%EB%B0%94-record%EB%A5%BC-entity%EB%A1%9C

 

[Java]자바 record를 entity로?

자바 8 이후 버전에 대해 살펴보던 중 제 관심을 가져간 하나의 키워드가 있었습니다.그 녀석은 바로 record로 자바 14와 15에서 preview로 추가된 이후, 16버전에서 정식 스펙으로 당당히 올라왔습니

velog.io

 

- record에는 @Setter를 사용할 수 없기 때문에 GET의 Parameter DTO로 사용할 수 없다. ( POST의 @RequestBody로는 가능)

Parameter DTO로 사용 불가능, setter 기능이 없기 때문

    @ApiOperation("게시글 목록 조회")
    @GetMapping("/posts")
    public List<Response> getList(PostDTO.Filter filter) {
        
        ...
    }

@RequestBody로 record는 가능

    @ApiOperation("게시글 생성")
    @PostMapping("/posts")
    public void create(@RequestBody PostDTO.Request request) {
        
        ...
    }

https://stackoverflow.com/questions/73201089/how-to-use-requestparam-with-dto

 

How to use @RequestParam with DTO

I have to make GET method with a DTO. But when I code like this↓, an error occurs. org.springframework.web.bind.MissingServletRequestParameterException: Required request parameter 'param' for method

stackoverflow.com