본문 바로가기

전체 글53

[JPA] Hibernate 6.1 @OneToMany 일대다 조회 시 DISTINCT 자동 적용 배경 스프링 부트 3.0 부터 Hibernate 6.1로 기준이 되어 해당 버전을 사용하고 있었다. 일대다에서 fetch join을 하면 중복 row(영한님 말로 - 뻥튀기)가 생긴다. 해결책으로 JSQL의 distinct를 적용하게되는데 SQL distinct와는 다르다. SQL의 distinct는 row의 값이 모두 일치해야 제거가 된다. JPQL에서 distinct를 하면 SQL distinct 기능 + 중복 엔티티 제거하는 기능을 한다. 하지만 Hibernate 6.0부터는 HQL(JPQL의 구현체)에 DISTINCT가 자동 적용된다. https://github.com/hibernate/hibernate-orm/blob/6.0/migration-guide.adoc#distinct 프로젝트 테스트를.. 2023. 1. 25.
1월 1월에 개인적으로 정리할 일도 있고 취업 준비도 하고 꽤 바빴다. 그래서 3주 동안 뭘 했고 무엇을 봤는지 적어보려한다. 스프링 게시판 프로젝트 게시판 프로젝트를 12월 말에 시작하여 1월 중에 끝냈다. 게시판은 JSP로 깡통만 해서 1시간만 있으면 뚝딱 만들 수 있지만 스프링으로 만들어본 것은 처음이라 시간이 더 걸렸다. 아무런 예외 처리나 유효성 검사 없는 깡통은 2일이면 금방 만들지만 오래 걸린 이유는 내가 이 게시판 프로젝트를 혼자 만들면서 기대하는 것들이 있었다. Test(JUnit5, Mock)에 대한 익숙함: 예전 JSP 웹 프로젝트를 했을 때는 테스트에 대한 이해와 이유를 몰랐다. 이후 스프링 강의를 들으면서 테스트의 중요성에 대해 알았는데, 여기서는 사용하는 것에 익숙해지려 했다. Moc.. 2023. 1. 22.
[JWT] JWT에 대해서 JWT (Json Web Token) 클라이언트와 서버간에 정보를 JSON으로 안전하게 전송하기 위한 간결하고 독립적인 방법을 정의하는 개방형 표준이다. 클라이언트가 서버에 요청할 때 토큰을 보내어 인증하는 방법에서 쓰인다. 이때 서버는 DB를 조회하지 않고 JWT가 유효한지 알 수 있기 때문에 토큰을 무상태(stateless)로 검증할 수 있다. https://jwt.io/introduction 특징 stateless 클라이언트가 로그인하면 서버는 JWT를 클라이언트에 보내고 클라이언트는 이 토큰을 저장한다. 이후 요청 시에 이 토큰을 함께 서버에 보내게 된다. 서버는 따로 토큰을 저장하지 않아도 되기때문에 무상태 stateless를 할 수 있다. 무결성 JWT가 발급되고 나서 토큰의 내용이 변경되면 .. 2023. 1. 21.
[JPA] fetch join 적용하기 게시판 프로젝트에서 홈을 요청하면 게시글 리스트를 불러온다. 문제는 쿼리인데, 페이징 할 때마다 쿼리가 3개가 나간다 select 게시글 select 회원: 닉네임 조회 게시글 count: 페이징 뷰게시판 프로젝트에서 홈 화면에서 게시글을 불러온다. 문제는 쿼리인데, 페이징 할 때마다 쿼리가 3개가 나간다. 김영한님의 JPA 강의에서 들은 fetch join을 적용해보려 한다. fetch join 여러 엔티티를 한 번의 SQL로 가져오는 것이다. 내 상황에서는 게시글을 불러오고 회원을 불러왔는데 이제 한 번에 fetch join으로 가져온다는 것이다. 이렇게 되면 쿼리 한 번에 회원이 영속성 컨테스트에 처음부터 들어있기 때문에 성능 최적화에 좋다. JPQL과 나가는 SQL 쿼리는 이렇다. JPQL: se.. 2023. 1. 19.
스프링 BindingResult 에러 메시지 JSON으로 응답하기 스프링과 Thymeleaf를 사용하는 환경에서 유효성 검사로 @Validated와 BindingResult로 손쉽게 사용할 수 있다. 바인딩할 객체에 @NotEmpty같이 설정해둔 유효성에 대한 에러메시지를 자동으로 BindingResult에 담아주고 Thymeleaf가 이것을 꺼내어 메시지를 찾아준다. 이때 아래와 같이 설정해두면 에러 메시지를 똑똑하게 찾아준다. # DTO NotEmpty.userName = 사용자 이름을 입력해주세요 NotEmpty.email = 이메일을 입력해주세요 NotEmpty.password = 비밀번호를 입력해주세요 NotEmpty.passwordConfirm = 비밀번호 확인을 입력해주세요 NotEmpty = 빈 칸을 채워주세요 손쉽게 일관적인 에러 메시지를 보낼 수 있다.. 2023. 1. 17.
스프링 Thymeleaf에서 @ExceptionHandler 활용 로그인을 처리하는데 예외처리에서 문제가 생겼다. 로그인을 하게되면 service에서 repository를 불러와 아이디를 가지고 있는 사용자인지, 비밀번호가 맞는지를 체크하고 만약 실패하면 IllegalArgumentException을 던진다. @Transactional public Member login(LoginRequestDto dto) { Member member = memberRepository.findByLoginEmail(dto.getEmail()) .orElseThrow(() -> new IllegalArgumentException("해당 사용자가 없습니다.")); if (!dto.getPassword().equals(member.getPassword())) { throw new Illeg.. 2023. 1. 17.