컴퓨터 프로그래밍/Spring

[Spring] [Memo] 메서드, 변수 명 선택, 중복된 @Transactional 처리, Pagenation 시 추가 데이터 압축 등 추가 Tips

한33 2024. 8. 30. 02:41

메서드 명 선택

// 일정 전체 조회 ( 페이지네이션 )
@GetMapping("/todos")
public List<InquiryTodosResDto> getTodos(@RequestParam(value = "page") int page,
                                         @RequestParam(value = "size", defaultValue = "10") int size) {
    // 응답 보내기
    return todoService.getTodos(page-1, size);
}

메서드명 선언 시에 getTodos 보다 getTodoList 가 더 좋다
나중에 보면 무작정 다 가져오는 건 거의 없고 보통 특정 조건이 하나 붙는 경우가 있다.


객체를 만들 때 목적에 맞게 메서드 새로 생성

Comment comment = new Comment(requestDto, user.getUserName());
public Comment(RegistCommentReqDto requestDto, String userName) {
    this.commentContent = requestDto.getCommentContent();
    this.userName = userName;
}

 

기존 방식에서는 기존 Comment 생성자를 생성하고 데이터를 넣어줄 때 어떤 용도로 만든 생성자더라도 동일하게 위 처럼 Comment 객체를 만들어서 데이터를 넣어줬었다.

Comment comment = Comment.addComment(requestDto, user.getUserName());
public Comment(RegistCommentReqDto requestDto, String userName) {
    this.commentContent = requestDto.getCommentContent();
    this.userName = userName;
}

public static Comment addComment(RegistCommentReqDto requestDto, String userName) {
    return new Comment(requestDto, userName);
}

 

변경된 방식에서는 위처럼 이름을 따로 선언해서 선언한 목적에 맞게 메서드를 만들어서 객체를 만들고 데이터를 넘겨주었다.


중복된 @Transactional 처리

@Transactional
public RegistTodoResDto createTodo(RegistTodoReqDto requestDto) {
@Transactional
public InquiryTodoResDto getTodo(Long id) {

위 처럼 같은 클래스 내에 모든 메서드에 @Transactional 이 붙어있다면 이를 클래스 위로 올려 아래와 같이 한 번에 처리할 수 있다.

@Transactional
public class TodoServiceImpl implements TodoService {


그래서 클래스위에 @Transactional(readOnly=true) 가 있지만 메소드 위에는 @Transactional(readOnly=false) 로 있다면 
가장 가까운 False 로 적용된다.


데이터를 업데이트하거나 등록하는 메서드가 아닌 출력하는 용도의 메서드에 readOnly=true 를 붙여줄 수 있다.


클래스, 변수 명 선언 시 약어 사용 자제

위 처럼 Request, Response 를 Req, Res 약자를 사용하지 말고 클래스명이나 변수명을 선언할 때에는 약어를 웬만하면 사용하지 말자.


DELETE 요청 시 안내 문구 반환

@DeleteMapping("/todo/{id}")
public ResponseEntity<Void> deleteTodo(@PathVariable Long id) {
    todoService.deleteTodo(id);
    return ResponseEntity.noContent().build();
}

DELETE 요청을 통해 삭제할 때 void 로 반환하기보다 뭐가 삭제되었는지 알려주는 것도 좋다.

기존에는 위처럼 삭제가 되면 그냥 아무런 값도 반환하지 않았는데, 프론트엔드 쪽에서 < 삭제가 완료되었습니다. > 와 같은 안내 팝업이 나오는 경우가 많다.


반복되는 문자열 변수 선언하기

예를 들면 "유저를 찾을 수 없습니다" 과 같은 문구가 반복적으로 사용된다면 계속해서 문자열 그대로 타이핑하기 보다

final static String errorMessageNotFoundComment= "유저를 찾을 수 없습니다.";


이런 느낌으로 따로 변수로 선언을 해서 사용하는 것이 이후에 관리하기에도 좋고 오타도 방지할 수 있다.


Entity 에 @Setter 제거 추천

Entity 는 데이터베이스와 다이렉트로 연결되어있기 때문에 예민하다.

특히 Service Layer 에서 메서드에 @Transactional 이 걸려있으면 save 메서드와 같은 안써도 변경감지 기능을 통해 자동으로 데이터베이스에 저장이 된다.
따라서 웬만하면 Setter 을 쓰지말고 메서드로 관리하면 좋다


id 값 원시타입으로 선언하기

@PathVariable Long id

PathVariable 로 받은 id 값 같은 경우는 null 이 발생할 수가 없다.

그런데 굳이 null 을 처리할 수 있는 참조형 변수인 Long 타입으로 선언을 하기 보다 원시타입인 long 으로 작성하면 프로젝트가 더 견고해진다.


 

Pagenation 시 추가 데이터 압축

@EnableSpringDataWebSupport(pageSerializationMode = EnableSpringDataWebSupport.PageSerializationMode.VIA_DTO)
public class SpringToDoProgramApplication {


pagenation 을 쓸 때 main Application class 선언 위에 위처럼 코드를 써서 아래에 같이 딸려오는  복잡한 json 형식의 데이터를 최대한 간단하게 출력시킬 수 있다.


filter 통과에 실패하면 기록이 남을 게 없으니 log 를 찍어줘서 확인하는 방법도 좋다.


@ManyToOne 의 FetchType default 값은 EAGER
@OneToMany 의 FetchType default 값은 LAZY


Dto 안에는 Entity 를 넣지 않는 것이 좋다.
무한루프가 될 수도 있고 Controller 가 Entity 를 알게하지 않는 것이 좋다.
Entity 를 Dton 안에 넣고 또 Dto 안에 넣는 식으로 하자.