실전! 스트링 부트와 JPA 활용 2 - 다음으로

이태휘·2022년 11월 8일
0
post-custom-banner

OSIV - Open Session In View : 하이버네이트

-> 하이버네이트에서 사용했던 엔티티매니저, session
-> 이걸 알아야 장애가 났을 때 파악을 할 수 있음!

OSIV ON

JPA가 언제 DB 커넥션 가져오고 언제 반환하는지에 대한 내용
-> 데이터베이스 트랜젝션 시작할 때 JPA의 영속성 컨텍스트가 데이터베이스 커넥션을 획득해

  • JPA에 영속성 컨텍스트가 있는데 이게 데이터베이스 1대1커넥션 쓰면서 동작해야해
  • Open Session in View : 트랜젝션이 끝나도 영속성 컨텍스트를 API가 유저에 반환될 때 까지 살아있는 것을 말함
    -> 유저에 완전히 리스펀스 나갈 때 까지
    -> 이게 디폴트였어서 지금까지 지연로딩이 가능했던 것임!

너무 오랜시간 데이터베이스 커넥션 가지고있으면 실시간 트래픽이 중요한 어플리케이션에선 문제가 될 수 있어
-> 커넥션이 말라버려서!

  • 장점은 지연로딩을 적극적으로 활용할 수 있다는 점

-> 이러면 데이터베이스 커넥션 반납하고 영속성 컨텍스트도 날라가
-> 고객요청이 왓을 때 트렌젝션에서 원하는 로직 돌리고 리소스 낭비안해

스프링 데이터 JPA

QueryDSL 소개

QueryDSL 링크
-> JPQL을 자바코드로 작성할 수 있게 해줌
-> JPA Criteria 써도 되긴하는데 얘는 유지보수가 어려움

-> 동적쿼리 작성할 때 mybatis도 많이 쓴다더라!

OrderRepository를 QueryDSL로 해결해보자

  • build.gradle 수정하기
//querydsl 추가
buildscript {
	dependencies {
		classpath("gradle.plugin.com.ewerk.gradle.plugins:querydsl-plugin:1.0.10")
	}
}

plugins {
	id 'org.springframework.boot' version '2.4.1'
	id 'io.spring.dependency-management' version '1.0.10.RELEASE'
	id 'java'
}

group = 'jpabook'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

//apply plugin: 'io.spring.dependency-management'
apply plugin: "com.ewerk.gradle.plugins.querydsl"

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-validation'
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.springframework.boot:spring-boot-devtools'
	implementation 'com.fasterxml.jackson.datatype:jackson-datatype-hibernate5'
// implementation 'org.hibernate:hibernate-core:5.4.13.Final'

	implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.6'

	compileOnly 'org.projectlombok:lombok'
	runtimeOnly 'com.h2database:h2'

	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	//추가
	testImplementation("org.junit.vintage:junit-vintage-engine") {
		exclude group: "org.hamcrest", module: "hamcrest-core"
	}

	//querydsl 추가
	implementation 'com.querydsl:querydsl-jpa'
	//querydsl 추가
	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
}

-> 이러면 q로시작하는 파일들이 generated이란 파일 안에 생성돼!
-> 이걸 가지고 QueryDSL 작성하는거

generated 된 애들은 gitignore로 뺴라!

  • OrderRepository에서 사용
public List<Order> findAll(OrderSearch orderSearch){
        QOrder order = QOrder.order;
        QMember member = QMember.member;

        //이전이랑 비교안되게 JPA랑 비슷하게 직관적임!
        //컨디션도 넣을 수 있음
        //컴파일 시점에 오타가 잡힌다는 큰 장점도 있음!!
        JPAQueryFactory query = new JPAQueryFactory(em);
        return query
                .select(order)
                .from(order)
                .join(order.member, member)
                .where(statusEQ(orderSearch.getOrderStatus()), member.name.like(orderSearch.getMemberName()))
                .limit(1000)
                .fetch();
    }

    //멤버네임 동적쿼리로 짜기
    private BooleanExpression nameLike(String nameCond) {
        if (!StringUtils.hasText(nameCond)) {
            return null;
        }
        return QMember.member.name.like(nameCond);
    }

    //status 동적쿼리로 짜기
    private BooleanExpression statusEQ(OrderStatus statusCond){
        //상태가 널이면 안쓰고 버림
        if (statusCond == null){
            return null;
        }
        //아니면 스테이터스 제대로 반환
        return QOrder.order.status.eq(statusCond);
    }

-> static으로 임포트해서 사용해서 코드 줄이기도 가능

끄-읏

profile
풀스택 개발자 가보자구~
post-custom-banner

0개의 댓글