CRUD
Create
Read
Update
Delete
insert
select
익셉션핸들러
밸리데이션
Ctrl + Alt + o 필요없는거 지워줌
package com.example.my.common.exception;
public class BadRequestException extends RuntimeException {
public BadRequestException(String message){
super(message); // 조상클래스 초기화?
}
public BadRequestException(){
super("잘못된 요청입니다.");
}
}
왜 500 에러 -> 상태코드 안 적어줬음.
-RestExceptionHandler.java
@RestControllerAdvice
public class RestExceptionHandler {
// Rest방식으로 에러처리
@ExceptionHandler(BadRequestException.class) // 에러가 발생했을 때 함수를 실행하겠다.(핸들링하겠다.)
public ResponseEntity<?> handleBadRequestException(Exception exception) {
return new ResponseEntity<>(
ResponseDTO.builder()
.code(1)
.message(exception.getMessage())
.build(),
HttpStatus.BAD_REQUEST);
}
}
@ExceptionHandler(Exception.class)
// 모든 에러를 처리하고 싶다.
public ResponseEntity<?> handleException(Exception exception){
return new ResponseEntity<>(
ResponseDTO.builder()
.code(1)
.message(exception.getMessage())
.build(),
HttpStatus.INTERNAL_SERVER_ERROR);
}
: 이렇게 하면 에러 찾기 힘들다.
에러 추적. (콘솔에 띄워준다)
한번에 에러처리하는게 편하긴 하지만 에러 찾아내기 힘들다
에러별로 만드는게 좋다.
테스트 성공
서비스에서 다 체크해야하는데
밸리데이션 사용하면 일이 줄어든다.
@Valid - 유효성 체크를 하겠다.
@NotBlank(message = "아이디를 입력해주세요")
// @@NotBlank : null, 빈 문자열(""), 공백(" ") 모두 허용하지 않는다.
@Size(min = 4, message = "아이디는 4자 이상 입력해주세요")
private String id;
@NotBlank(message = "비밀번호를 입력해주세요")
@Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*\\d)(?=.*[@#$%^&+=!])(?=.*[A-Z])(?=.*[a-z]).{8,16}$", message = "비밀번호는 8~16자 영문 대소문자, 숫자, 특수문자를 사용하세요")
private String password;
public class ReqJoinDTO {
@Valid
@NotNull(message = "유저 정보를 입력해주세요") // user를 입력안하면 에러터짐
private User user;
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
public static class User {
@NotBlank(message = "아이디를 입력해주세요")
// @@NotBlank : null, 빈 문자열(""), 공백(" ") 모두 허용하지 않는다.
@Size(min = 4, message = "아이디는 4자 이상 입력해주세요")
private String id;
@NotBlank(message = "비밀번호를 입력해주세요")
@Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*\\d)(?=.*[@#$%^&+=!])(?=.*[A-Z])(?=.*[a-z]).{8,16}$", message = "비밀번호는 8~16자 영문 대소문자, 숫자, 특수문자를 사용하세요")
private String password;
}
}
조건에 맞지 않아서 오류
성공
주석처리한 부분 - 지워도 됨.
밸리데이션 사용하면 서비스에서 유효성 체크 안해도 된다.
RestExceptionHandler.java
테스트
public class ReqLoginDTO {
@Valid
@NotNull(message="아이디와 비밀번호를 입력해주세요")
private User user;
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
public static class User {
@NotBlank(message = "아이디를 입력해주세요")
private String id;
@NotBlank(message = "비밀번호를 입력해주세요")
private String password;
}
}
AOP(Aspect-Oriented Programming)는 프로그래밍 패러다임 중 하나로, 관점 지향 프로그래밍이라고도 합니다. 기본적으로 객체 지향 프로그래밍(OOP)과 함께 사용되며, OOP의 한계를 보완하고 코드의 모듈성과 재사용성을 높이기 위해 도입되었습니다.
AOP는 애플리케이션의 핵심 비즈니스 로직과 부가적인 기능(로깅, 보안, 트랜잭션 처리 등)을 분리하여 개발하고, 이를 관점(Aspect)이라고 하는 모듈로 만들어 관리하는 프로그래밍 방법론입니다. 이렇게 분리된 관점들은 애플리케이션의 여러 부분에서 재사용될 수 있으며, 코드의 중복을 방지하고 유지보수를 편리하게 만들어줍니다.
select *
from todo
where user_idx =?
jpa
findByUserEntity_idx
//// 리파지토리에서 유저 기본키로 삭제되지 않은 할 일 목록 찾기
List<TodoEntity> todoEntityList = todoRepository.findByUserEntity_IdxAndDeleteDateIsNull(loginUserDTO.getUser().getIdx());
List < TodoEntity >
: TodoEntity 객체들을 담을 리스트(List) 자료구조 선언
todoRepository
: TodoEntity 객체들을 조회하기 위해 사용되는 리파지토리
findByUserEntity_IdxAndDeleteDateIsNull
: 리파지토리에서 유저 기본키로 삭제되지 않은 할 일 목록을 찾아야 하므로
todoRepository에서 정의한 메소드 중 하나로,
사용자(UserEntity)의 인덱스(Idx)와 삭제 날짜(DeleteDate)가 NULL인 TodoEntity를 조회하는 기능을 수행.
로그인한 사용자의 인덱스를 기준으로 삭제되지 않은 TodoEntity를 찾는 쿼리를 수행하는 것.
할 일 목록을 가져왔지만, todo (할 일) 과 done (한 일)을 나눠야한다. 화면에서 다 처리하기에 복잡하므로 ResTodoTableDTO.java에 따로 of 함수를 만듦.
함수이름을 of로 쓴 이유
ResTodoTableDTO.of(todoEntityList)
todoEntityList의 ResTodoTableDTO , todoEntityList로 만든 ResTodoTableDTO라는 의미를 보기 쉽게 하기 위해서
ex) 반지의 제왕 The Lord of the Rings
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
public class ResTodoTableDTO {
private List<Todo> todoList;
private List<Todo> doneList;
public static ResTodoTableDTO of(List<TodoEntity> todoEntityList) {
return ResTodoTableDTO.builder()
.todoList(
todoEntityList.stream()
.filter(todoEntity -> todoEntity.getDoneYn().equals('N'))
.map(todoEntity -> Todo.fromEntity(todoEntity))
.toList()
)
.doneList(
todoEntityList.stream()
.filter(todoEntity -> todoEntity.getDoneYn().equals('Y'))
.map(todoEntity -> Todo.fromEntity(todoEntity))
.toList()
)
.build();
}
// dto로 바꾸기
ResTodoTableDTO dto = ResTodoTableDTO.of(todoEntityList);
ResTodoTableDTO 에 있는 of 함수를 사용해서 dto에 담아준다.
dto 앞에 ResTodoTableDTO 는 타입을 적어준 것이다.
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class TodoService {
private final TodoRepository todoRepository;
public ResTodoTableDTO getTodoTableData(LoginUserDTO loginUserDTO) {
// 리파지토리에서 유저 기본키로 삭제되지 않은 할 일 목록 찾기
List<TodoEntity> todoEntityList = todoRepository.findByUserEntity_IdxAndDeleteDateIsNull(loginUserDTO.getUser().getIdx());
// dto로 바꾸기
ResTodoTableDTO dto = ResTodoTableDTO.of(todoEntityList);
// dto로 리턴
return dto;
}
}
TodoController
TodoService.java
ResTodoTableDTO.java
table.html
ch00 / Study14.java
controller
서비스님 dto 죰 주세요
service
repository
request
유저 -> 컨트롤러 -> 서비스 -> 리파지토리 -> 서비스 -> 컨트롤러
response
-> 유저