
Open Session In View의 약자DB커넥션에 대한세션을View까지 유지하는 것에 대한전략기본값은true- 부르는
명칭이 조금씩 다르지만,관례상OSIV라고 부름
Hibernate:OSIV(Open Session In View)JPA:OEIV(Open EntityManage In View)- 우리는
jpa에서 적용하는sping.jpa.open-in-view속성에 대해 다룰 것
sping.jpa.open-in-view : trueDB 커넥션을사용자의 요청이끝날 때 까지 계속 유지
- 장점
DB 커넥션을계속 유지한다는 것은영속성 컨텍스트의생존범위가확장되는 것!
--> 그래서연관관계LAZY fetch 전략을서비스를 벗어난 곳에서사용 가능!- 단점
- 너무
오랜시간동안DB 커넥션을 유지하여리소스를 사용하기 때문에실시간 트래픽이 중요한 Application에서는DB 커넥션이모자랄 수 있음(장애 발생)
sping.jpa.open-in-view : falseDB 커넥션을Transaction 내부까지만 유지
(Transaction은Service에서수행되니까Service까지만 유지되는 것)
- 장점
DB 커넥션 리소스의효율적인 사용
:트랜잭션을 종료할 때영속성 컨텍스트를 닫으면서DB 커넥션을반환- 단점
모든 지연로딩을트랜잭션 안에서 처리
:지연로딩에 관한 모든 로직을Service/Repository에서해결해야 함
OSIV 전략을false로 둔 상태에서복잡성을 관리하는 방법들이 존재
1)Command와 Query를 분리
2)Service / Repotisotry 에서 모든 지연로딩을 처리
Command와Query를분리하는 방법 (김영한님 선호)
:Controller에서지연로딩을 처리해야 할 때Query용 Service를 만드는 것OrderService
OrderService
:핵심 비즈니스 로직OrderQueryService
:화면이나API에맞춘 서비스(주로읽기 전용 트랜잭션)
OSIV는DB 커넥션 리소스에 대한효율적인 사용과 관련된전략OSIV 실무 조언
고객 서비스의 실시간 API
:OSIVfalse설정ADMIN 처럼 커넥션이 많지 않은 곳
:OSIVtrue설정
- 해결방안
Service/Repository에서지연로딩을처리하는 것이너무 많아지고 복잡해지면파일로 따로 분리
JPA를 사용할 때 지루하게반복되는 코드를자동화
: 여러도메인마다save,findById이런것은반복되는 경우가 많다JpaRepository라는인터페이스를 제공하며 이것을상속받는 것 하나로기능 제공
:기본적인 CRUD기능과다양한 것들이 만들어져 있음findByName처럼특정 필드에 관한 것들도정해진 메서드 이름으로 만들면알아서 수행개발자는인터페이스만만들면된다
-->스프링 데이터 JPA가애플리케이션 실행시점에구현체를 만들어서알아서 주입!개발 생산성의 놀라운확장 가능
-->실무에서필수적으로 사용
JPQL만으로는 힘든동적쿼리를 사용하기 쉽게 제공하는오픈소스 라이브러리QueryDSL은 SQL(JPQL)과유사하여자바코드로동적 쿼리를 편리하게 생성
- 장점
직관적인문법컴파일 시점에 빠른문법 오류 발견코드 자동완성코드 재사용JPQL new 명령어와는 비교가 안될정도로 깔끔한DTO조회 지원
( build.gradle 추가 )
/* Quyery DSL */ buildscript { dependencies { classpath("gradle.plugin.com.ewerk.gradle.plugins:querydsl-plugin:1.0.10") } } ... /* Quyery DSL */ apply plugin: "com.ewerk.gradle.plugins.querydsl" ... dependencies { /* Query DSL */ implementation 'com.querydsl:querydsl-jpa' implementation 'com.querydsl:querydsl-apt' } ... //querydsl 추가 //def querydslDir = 'src/main/generated' def querydslDir = "$buildDir/generated/querydsl" querydsl { library = "com.querydsl:querydsl-apt" jpa = true querydslSourcesDir = querydslDir } sourceSets { main { java { srcDirs = ['src/main/java', querydslDir] } } } compileQuerydsl{ options.annotationProcessorPath = configurations.querydsl } configurations { querydsl.extendsFrom compileClasspath }
( compile 실행 )
( 만들어진 파일 )