[Spring] [Memo] 메서드, 변수 명 선택, 중복된 @Transactional 처리, Pagenation 시 추가 데이터 압축 등 추가 Tips
메서드 명 선택
// 일정 전체 조회 ( 페이지네이션 )
@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 안에 넣는 식으로 하자.