api 프로젝트때 썼던거 복붙해서 날먹하려고 했는데 jpa가 아니라 jdbc로 해야해서 처음부터 만들어야한다.(..)
일단 entity와 @id, @generatedvalue를 못 쓴다.
repository 또한 jdbc에서는 Dao가 그 역할을 하고, 직접 쿼리문을 작성해줘야 한다.
@Getter
@Setter
@ToString
@AllArgsConstructor
@EqualsAndHashCode(of = "id")
//id필드를 비교대상으로 둠.(고유성을 id로 판단, PK라는뜻)
public class Schedule {
public Schedule(){
this.id = UUID.randomUUID();
this.created = LocalDateTime.now();
this.updated = LocalDateTime.now();
}
public void updateTimestamp() {
this.updated = LocalDateTime.now();
}
public Schedule(String name, String content, String password) {
this();
this.name = name;
this.content = content;
this.password = password;
}
private UUID id;
private String name;
private String content;
private String password;
private LocalDateTime created;
private LocalDateTime updated;
}
우선 entity계층을 작성했다. @Id역할을 @EqualsAndHashCode(of = "id")가 대신한다.
UUID.randomUUID()로 객체마다 고유한 id를 생성한다.
schedule 객체가 생성될 때 id와 created, updated가 자동으로 생성되고, 클라이언트에게 값을 전달받아 name, content, password를 채운다.
@PostMapping("/{id}")
public void updateSchedule(@PathVariable UUID id, @RequestParam String password, @RequestBody ScheduleDto dto) {
scheduleService.updateSchedule(id, password, dto);
}
public ScheduleDto updateSchedule(UUID id, String password, ScheduleDto dto){
Schedule schedule = scheduleDao.findById(id);
if(schedule == null){
throw new BadInputException("오류요");
}
if (!passwordEncoder.matches(password, schedule.getPassword())) {
throw new BadInputException("오류요");
}
schedule.setName(dto.getName());
schedule.setContent(dto.getContent());
schedule.updateTimestamp();
scheduleDao.update(schedule);
return ScheduleMapper.toDto(schedule);
}
public void update(Schedule schedule){
String sql = "UPDATE Schedule SET name = ?, content = ?, password = ?, updated = ? WHERE id = ?";
try(Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
PreparedStatement pstmt = conn.prepareStatement(sql)){
pstmt.setString(1, schedule.getName());
pstmt.setString(2, schedule.getContent());
pstmt.setString(3, schedule.getPassword());
pstmt.setTimestamp(4, Timestamp.valueOf(schedule.getUpdated()));
pstmt.setString(5, schedule.getId().toString());
int rowsUpdated = pstmt.executeUpdate();
if(rowsUpdated == 0){
throw new BadInputException("오류요");
}
}catch(SQLException e){
throw new BadInputException("오류요" + e.getMessage());
}
}
public static Schedule toEntity(ScheduleDto dto, String password, UUID id) {
return new Schedule(
id != null ? id : UUID.randomUUID(),
dto.getName(),
dto.getContent(),
password,
LocalDateTime.now(),
LocalDateTime.now()
);
}
update를 할 때의 전체적인 흐름이다. jpa 그립다
쿼리 update 과정에 비밀번호가 들어가는 게 상당히 마음에 안 드는데 방법을 좀 찾아봐야할것같다..
dao 클래스도 하나로 쓰고 있어서 코드 길이가 상당히 길다. 분리하는 편이 더 깔끔할듯하다
그리고 putmapping 이나 deletemapping 에선 프론트단에서 requestbody를 못 쓴대서 delete, update 모두 post로 구현해봤다.
dto에 password까지 넣어서 requestbody로 보내는 것이 좀 더 안전할거같아서 수정 예정이다.
비밀번호는 bcrypt 알고리즘을 쓰기때문에 검증과정을 넣어줬다.
swagger에서 테스트 해보려는데 뭐야 누구세요? 난 이런페이지 만든적없어요
spring security 그냥 집어넣어서 이러는거같다;;
@Configuration
public class SecurityConfig {
@Bean
public InMemoryUserDetailsManager userDetailsService(){
UserDetails user = User.builder()
.username("cy")
.password(passwordEncoder().encode("jane"))
.roles("ROLE_ADMIN")
.build();
return new InMemoryUserDetailsManager(user);
}
//비번 bcrypt 암호화 적용
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}
bcrypt때문에 아래거만 그냥 넣었는데 위의 사용자 인증도 넣어줬다.
버그 테스트는 내일 해야겠다. 많을 것 같다. 너무 힘들다..
일단 1일차 이렇게 마무리.. 근데 커밋메세지를 그냥 lv1 lv2로 해버려서 좀 걱정이다. 어차피 도전레벨에서 구현하다보면 컨벤션 지킨 커밋이 많이 나오긴 하겠지만..
'개인 공부용 프로젝트 > schedule.jdbc.api' 카테고리의 다른 글
(도전과제 시작) author 테이블 만들기, custom exception 추가 (0) | 2024.12.05 |
---|---|
트러블슈팅 : 필수과제 버그 수정 (0) | 2024.12.05 |
일정 관리 앱 프로젝트 시작 (0) | 2024.12.04 |