본문 바로가기

Spring Boot

(33)
queryDsl) subquery limit 1 시작하기 전 아쉽게도 (querydsl) 서브쿼리에서 limit 옵션은 동작하지 않는다 정확한 이유는 잘 모르겠지만 쿼리가 실행될때 JPQLSerializer를 사용하여 싱글쿼리 문자열이 빌드된다. 이 과정에서 sub query limit가 적용되지 않는 것 같다 (jpql는 limit 옵션을 지원하지 않는다) 그렇다면 서브쿼리에서 limit처럼 동작하게 하는법은 무엇이 있을까? 아래와 같은 예제가 있다. (App 과 Version 은 일대 다 관계이다) // 부모 @Entity public class App { @Id @Column(name = "APP_NUM", nullable = false) private Long Id; @Column(name = "APP_NM") private String app..
querydsl 에서 case문 사용하기 query에서 case when문을 사용하는 것보다 어플리케이션에서 비즈니스 로직으로 처리되는 것이 권장되는 방법이다. query dsl 에서 case문은 select절, where절에서 사용이 가능하다. 아래는 간단한 사용법이다 case builder query dsl 에서 제공하는 case문으로 주로 when절에 복잡한 조건이 들어올때 사용된다. > 간단한 case문 (when(조건).then(값)) 으로 처리가 힘들 때 new caseBuilder().when(조건) .then(값).otherwise(값) 조건이 참일때 then 값이 거짓일때 otherwise 값이 적용된다. @Override public List findColorCat(String 원하는색) { return jpaQueryFact..
QueryDsl) BooleanExpression BooleanBuilder와 BooleanExpression 모두 Querydsl 라이브러리에서 제공하는 기능으로, 쿼리를 동적으로 생성하기 위해 사용한다. // booleanBuilder QMember member = new QMember("member"); public List findAllMember(Integer class, String name) { BooleanBuilder builder = new BooleanBuilder(); if (!StringUtils.isEmpty(name)) { builder.and(member.name.eq(name)); } if (class != null) { builder.and(member.class.id.eq(class)); } return jpaQuery..
queryDsl 정리 및 예제 spring boot jpa를 사용하다보면 jpa에서 지원하는 기본적인 메서드 만으로 원하는 데이터를 못 들고 오는 경우가 빈번하게 있었을 것이다. (복잡한 쿼리문) 따라서 jpql을 필연적으로 사용할 수 밖에 없는데 jpql 특성상 복잡도가 올라가면 오타 및 오탈자가 발생하기 쉽다. 문제는 동적 쿼리의 경우 이를 어플리케이션 로딩 시점에서 잡아내지 못하고 런타임 도중 에러가 발생한다. // jpql 예시 @Query("select p from Post p join fetch p.user u " + "where u in " + "(select t from Follow f inner join f.target t on f.source = :user) " + "or u = :user " + "order by ..
JPA) JPA Auditing으로 자동화 JPA Auditing 이란 Spring boot JPA 에서 지원하는 기능 중 하나인 Auditing은 뜻 그대로 엔티티가 생성되고 수정되는 시점을 감시하여 생성일, 생성자, 수정일, 수정자 를 자동으로 기록할 수 있다. 생성일 ~ 수정자는 모든 엔티티들이 공통적으로 가지고 있는 컬럼이므로 중복되는 코드를 줄이기 위해 BaseEntity 로 분리하여 여러 방법으로 Auditing을 구현해보자. BaseEntity @Getter @MappedSuperclass @EntityListeners(AuditingEntityListener.class) public abstract class BaseEntity implements Serializable { @CreatedDate @Column(updatable =..
QueryDSL) From 절 SubQuery를 쓰고싶어 querydsl은 from절 서브쿼리를 지원하지 않아 답답한 적이 많았는데 다음 방법으로 from절 서브쿼리를 사용해보자. 하이버네이트 @Subselect를 이용해서 서브 쿼리로 사용할 엔티티에 가상 view 처럼 사용하는 것이다. 그렇게 되면 native query로 작성하는 것처럼 사용이 가능하다. 아래는 @Subselect 사용예제이다 subquery용 entity생성 @Entity @Subselect( "select * " + "from VERSION " + "where VERSION_ID in " + "( " + "select max(SW_RELS_NUM) " + "from VERSION " + "where CRT_DT in " + "( " + "select max(CRT_DT) " + "fro..
JPA) Entity Graph 로 N+1 이슈 해결하기 오직 Spring-Data-JPA 만 사용하며 N+1을 최소화하고 연관된 데이터들을 한번에 조회하고 싶을때가 있다 여러가지 해결방법 중 Entity Graph를 사용하는 방법을 다뤄본다. Entity Graph를 사용하여 FetchType이 Lazy 인 연관관계 엔티티들을 한번에 (Left Join 으로) 조회할 수 있다. (fetch join을 사용하고 싶으면 JPQL을 사용하여 fetch join 을 직접 사용하자.) @EntityGraph 사용 간단한 연관관계는 다음과 같이 Repository 에서 @EntityGraph 를 사용하여 사용이 가능하다. // 부모 Entity @Entity ... public class Parent { @Id @GeneratedValue(strategy = Gener..
Spring boot JPA : Delete In @Transactional @Modifying void deleteCartsByCartIdIn(List cartArr); 위 코드는 Book Store의 장바구니 의 책들을 삭제하는 CartRepository의 JPA코드이다 저장된 두 권의 책을 삭제하고싶어서 delete in을 사용하여 리스트를 제거하였는데 select쿼리 한번과 delete쿼리 두번이 발생하였다. (초록색 괄호부분 // 해당 장바구니의 책이 사용자의 장바구니 책이 맞는지 검증하는 코드이다 멤버id를 찾는 쿼리는 두번이나 조회할 필요가 없어서 코드의 맨 위에서 한번만 조회하도록 변경하였다 위 사진은 변경 전에 동작한 사진이라 select문이 여러번 발생했지만 아래 코드에서는 하번만 수행된다) 아래 붉은색 괄호부분 아래의 3개의 코드가 ..