본문 바로가기
728x90

[JAVA]/JPA35

JPA Specification을 이용하여 다중 조건 검색 로직을 구현해보자. 🤔 다중 조건 검색이란? 다중 조건 검색이란 카테고리 검색, 상세 검색 등과 같이 쇼핑몰 등에서 여러 필터 조건으로 검색된 결과를 축소시켜 사용자가 원하는 결괏값만을 도출하기 위해 사용한다. 이를 어떻게 구현할 수 있을까 고민해보면 한 가지 방법으로 귀결되는데 바로 '동적 쿼리'이다. 사용자가 원하는 필터링에 맞춰 조회 쿼리를 날려주면 되는 것인데 결국 매 요청마다 쿼리문이 달라지게 된다는 이야기이므로 Jpa에서 제공하는 기본 메서드와 같이 정해진 쿼리에 value만 다르게 보내는 것과는 다른 방법을 사용해야 한다. 📜 테스트에 사용될 View member 테이블과 team 테이블에서 추출하여 만든 view이다. view나 테이블 구조에 대해 자세히 알고 싶다면 이 글을 참고하자. 💡 대표적인 방법 세 .. 2024. 1. 31.
복합 값 타입 - @Embedded와 private static inner class를 비교해보자. 💡 Java에서 주소 정보와 같은 그룹화할 수 있는 필드를 추가할 때 보통 @Embedded 애너테이션 또는 private static 클래스를 사용한다. 두 접근 방식에는 각각 장단점이 있기 때문에 상황에 맞게 선택하는 것이 좋다. 이 글에서는 각 방식의 사용 시나리오와 그에 따른 장단점을 비교해보겠다. @Embedded 애너테이션 사용 시나리오 @Embedded 애너테이션은 주로 관계형 데이터베이스와 JPA 기반의 구현체에서 사용된다. 주소, 이름 등 공통으로 사용되는 속성을 별개의 클래스로 분리하여 코드의 재사용성과 모듈화를 증가시킬 수 있다. 예시 코드 // Member @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Document(co.. 2023. 8. 14.
Entity 클래스에서 @Builder 제대로 알고 사용하자 💡 회사에서 본격적으로 ORM을 활용하여 API를 개발하기 시작하면서 전에는 아무렇지 않게 배운 대로 따라 치던 것들이 하나하나 왜 이렇게 되는지 의심이 생기고 궁금해지기 시작했다. 그중 데이터베이스의 테이블과 매핑되는 Entity 클래스에 대해 이야기해보려고 한다. 이 글에서 정리한 Entity에 대한 정보는 과거에 내가 적은 이 글에서 그대로 가져왔다. Entity 클래스 실제 데이터베이스 테이블과 매핑되는 핵심 클래스이다. 데이터베이스의 테이블에 존재하는 칼럼들을 필드로 가지는 객체이다. 데이터베이스의 테이블과 1:1 매핑이 되므로 테이블이 가지고 있지 않는 칼럼을 필드로 가져서는 안 된다. Entity 클래스는 데이터베이스의 영속성을 목적으로 사용하는 객체이기 때문에 요청, 응답 등에 사용되어서는.. 2023. 5. 23.
JPARepository의 findAll() 호출 시 하나의 Row가 중복해서 여러 개 들어가는 경우와 특정 컬럼만 null이 들어가 있는 경우 (엔티티명과 컬럼명의 올바른 매핑 방법) 💡 JPARepository의 findAll() 메서드를 호출해서 List에 저장을 했는데 하나의 Row 값만 잔뜩 들어가 있었다. DB를 확인해 보니 맨 위 첫 번째 row 데이터였는데 테이블의 row 수만큼 데이터가 들어가 있었기 때문에 매핑에 문제가 있음을 단번에 알아챘다. 테스트를 진행해 보자. 우선 로컬 DB에 테이블을 생성한다. 칼럼명을 짓고 더미 데이터도 적당하게 넣는다. test 데이터베이스의 test 테이블에 10개의 row가 들어가 있다. 엔티티를 생성한다. 나는 두 가지를 테스트할 예정이므로 일부러 id와 name 필드명 테이블의 칼럼명과 다르게 했다. seq는 test 테이블의 ID에 해당한다. name은 test 테이블의 USER_NAME에 해당한다. 나머지 칼럼명은 필드명과 일.. 2023. 5. 19.
JPQL - 벌크 연산 재고가 10개 미만인 모든 상품의 가격을 10% 올리려면 어떻게 해야 할까? JPA 변경 감지 기능으로 실행하려면 너무 많은 SQL이 실행될 것이다. 1. 재고가 10개 미만인 상품을 리스트로 조회한다. 2. 상품 엔티티의 가격을 10% 증가한다. 3. 트랜잭션 커밋 시점에 변경 감지가 동작한다. 변경된 데이터가 100건이라면 100번의 UPDATE SQL문이 실행될 것이다. 벌크 연산 쿼리 한 번으로 여러 테이블의 로우(엔티티)를 변경한다. executeUpdate()를 사용하여 연산할 수 있다. // 모든 Member의 나이를 20살로 변경한다. int resultCount = em.createQuery("update Member m set m.age = 20") .executeUpdate(); ex.. 2023. 5. 14.
JPQL - @NamedQuery 애너테이션 @NamedQuery @Entity @NamedQuery( name = "Member.findByUsername", query = "select m from Member m where m.username = :username") public class Member{ ... } List resultList = em.createNamedQuery("Member.findByUsername", Member.class) .setParameter("username", "회원1") .getResultList(); 미리 정의해서 이름을 부여해 두고 사용하는 JPQL이다. 정적 쿼리만 가능하다. 애너테이션, XML에 정의할 수 있다. 애플리케이션 로딩 시점에 초기화 후 재사용한다. 애플리케이션 로딩 시점에 JPA나 하이.. 2023. 5. 13.
JPQL - 엔티티 직접 사용 엔티티 직접 사용 JPQL에서 엔티티를 직접 사용하면 SQL에서 해당 엔티티의 기본 키 값을 사용한다. 엔티티 직접 사용 - 기본 키 값 -- JPQL select count(m.id) from Member m -- 엔티티의 아이디를 사용 select count(m) from Member m -- 엔티티를 직접 사용 -> Member 엔티티의 기본 값인 id 값을 사용 -- SQL(위의 쿼리 둘 다 아래의 SQL이 실행된다.) SELECT COUNT(m.id) AS cnt FROM Member m 엔티티를 파라미터로 전달 String jqpl = "select m from Member m where m = :member"; List resultList = em.createQuery(jpql) .setPa.. 2023. 5. 13.
JPQL - 다형성 쿼리 TYPE 조회 대상을 특정 자식으로 한정할 수 있다. -- EX) Item 중에 Book, Movie를 조회해라. -- JQPL select i from Item i where type(i) IN (Book, Movie) -- SQL select i from i where i.DTYPE in ('B', 'M') TREAT(JPA2.1) 자바의 타입 캐스팅과 유사하다. 상속 구조에서 부모 타입을 특정 자식타입으로 다룰 때 사용한다. FROM, WHERE, SELECT(하이버네이트 지원)에서 사용할 수 있다. -- EX) 부모인 Item과 자식 Book이 있다. -- JPQL select i from Item i where treat(i as Book).auther = 'kim' -- SQL select i.. 2023. 5. 13.
728x90