본문 바로가기

Advance I/Querydsl

22.07.18

SQL function 호출하기

JPA는 Dialect에 등록된 SQL function만 호출할 수 있다.

새로운 함수 정의 -> JPA 기본편 참고

 

ex)

Expressions.stringTemplate("function('replace', {0}, {1}, {2})", member.username, "member", "M")

: 함수 이름, 파라미터 바인딩(?0, ?1, ?2). member.username에서 "member"->"M"로 replace

 

ansi 표준 함수들은 querydsl이 상당부분 내장하고 있다. 이 경우 DB에 의존적인 함수를 사용하지 않아도 된다.

 

ex)

Expressions.stringTemplate("function('lower', {0})", member.username))

-> member.username.lower()

 

실무 활용 - 순수 JPA와 Querydsl

순수 JPA 리포지토리와 Querydsl

JPAQueryFactory 생성 방법

둘 중 택1

1. 리포지토리 생성자에서 인젝션 된 EntityManager를 받아 new 연산자로 직접 생성

2. JPAQueryFactory를 스프링 빈으로 등록하여 EntityManager과 함께 인젝션 받는다.

   (@RequiredArgsConstructor 사용 가능. 대신 주입 받아야 하는 것이 2개이기 때문에 테스트 시 귀찮)

 

참고: 스프링 빈은 싱글톤 방식으로 작동하나, 동시성 문제는 걱정하지 않아도 된다. 왜냐하면 여기서 스프링이 주입해주는 엔티티 매니저는 실제 동작 시점에 진짜 엔티티 매니저를 찾아주는 프록시용 가짜 엔티티 매니저이다. 이 가짜 엔티티 매니저는 실제 사용 시점에 트랜잭션 단위로 실제 엔티티 매니저(영속성 컨텍스트)를 할당해준다.

더 자세한 내용은 자바 ORM 표준 JPA 책 13.1 트랜잭션 범위의 영속성 컨텍스트를 참고하자

동적 쿼리와 성능 최적화 조회

회원과 팀의 정보를 하나의 DTO로 원하는 데이터만 조회하는 예제

Builder 사용

검색 조건 필드만 정의된 SearchCondition 클래스 생성

StringUtils.hasText(string): string이 null이나 ""이 아닐 때 true

builder에 and 메서드로 where()에 들어갈 검색 조건 추가 -> where(builer)

 

검색 조건이 없으면(모든 필드가 null) 모든 데이터를 조회 -> 데이터가 많을 경우 성능 저하 유발

최소한 기본 조건이나 페이징이 필요하다.

Where절 파라미터 사용

BooleanExpression을 반환하는 조건 메서드 생성

BooleanExpression: Predicate의 구현체. and(), or() 로 조합 가능. null 반환시 where 절에서 해당 조건 무시

select 프로젝션이 달라져도 where 절은 변화 없음. select 절과는 무관하게 from 절과 검색 조건 객체에 의존

조회 API 컨트롤러 개발

편리한 데이터 확인을 위해 샘플 데이터를 추가하자.

 

샘플 데이터 초기화 작업 중 주의할 점

@PostConstruct와 @Transaction은 같은 컴포넌트 안에서 실행 불가.

스프링 라이프사이클로 인해 @PostConstruct와 @Transactional AOP가 적용되는 시점이 다르기 때문

@Transaction을 담당할 컴포넌트를 따로 등록하고 @PostConstuct 내에서 해당 컴포넌트를 호출할 것

@PostConstruct와 @Transactional 분리 - 인프런 | 질문 & 답변 (inflearn.com)

 

샘플 데이터 추가가 테스트 케이스 실행에 영향을 주지 않도록 다음과 같이 프로파일을 설정하자.

프로파일 설정

프로젝트를 진행할 때, 개발 단계(local, dev, prod...)에 따라 다른 리소스를 의존해야 할 때가 있다. DB나 환경설정 등...

소스의 변경 없이 profile을 통해 손쉽게 갈아끼울 수 있다.

 

--src/main/resources/application.yml

spring:
  config:
    activate:
      on-profile: local
      
---

spring:
  config:
    activate:
      on-profile: dev
      
---

spring:
  config:
    activate:
      on-profile: prod

스프링부트 2.4.0 이전: spring.profiles.active

 

--- 구분자

.yml 파일에서 ---을 이용하면 마치 여러 개의 .yml 파일을 생성한 것처럼 설정을 분리할 수 있다.

순서대로 공통 설정(default application.yml), dev용 설정(application-prod.yml), prod용 설정(application-prod.yml) 역할을 한다.

 

@Profile 어노테이션

프로파일 설정 : 스프링 설정 파일(config)

@Configuration
@Profile("test")
public class TestConfiguration {

    @Bean
    public BookRepository bookRepository(){
        return new TestBookRepository();
    }
}

프로파일 "test" 가 active 되었을 때, 해당 설정 파일의 스프링 빈이 컨테이너에 등록

 

프로파일 설정 : 컴포넌트 파일

@Repository
@Profile("test")
public class TestBookRepository implements BookRepository{
}

프로파일 "test" 가 active 되었을 때, 컴포넌트 스캔의 대상이 됨 (스프링 빈 등록)

 

* " " 안에 !, &, | 등 논리 연산자 사용 가능

프로파일 구동

Jar

$ java -jar -Dspring.profiles.active={profileName} {jarFileName}

// local 프로필로 구동
$ java -jar -Dspring.profiles.active=local babble.jar

// prod 프로필로 구동
$ java -jar -Dspring.profiles.active=prod babble.jar

 

IntelliJ

1. Run > Edit Configurations... 선택 

2. Spring Boot Application 선택

3. Active profiles 에서 원하는 profile 명을 입력 후 실행

 

'Advance I > Querydsl' 카테고리의 다른 글

22.07.21  (0) 2022.07.21
22.07.20  (0) 2022.07.20
22.07.14  (0) 2022.07.14
22.07.13  (0) 2022.07.13
22.07.07 :: 실전! Querydsl  (0) 2022.07.07