Spring boot With Querydsl 옛날부터 꼭 올려야 된다 생각하였지만….. 그렇게 하면… 너무 많아서 잠을 잘수가 없다..
코틀린 with QueryDsl 과거 코틀린편은 올렸으나 자바로 한 적이 없어서…. 이글을 쓴다.
1. Why QueryDsl
Type-check가 불가능하다. -> SQL, JPQL은 문자열임
컴파일 시점에… 알수가 없다.
쿼리 실행이 어플리케이션에 실행되었을 때 아이고 저런.. 하며 후회한다.
그럼 어찌해야하느냐!! -> QueryDsl 또는 Jooq를 쓰자
QueryDsl -> 쓰면서 느끼는 점
Sql이 클래스처럼 Type이 있어 type-safe 하다
다이나미쿼리 (동적쿼리)를 짜기 편하다.
Jooq가 QueryDsl보다 편하지만 아직은 대중적이지 않다. 개인적으로 Jooq는 rdb로 통계쿼리 뽑아내는 부분은 짱이다.
2. 바로 실습
build.gradle (메이븐일 경우 다른데곳에서 찾아서….하시길..)
대충 아래처럼 추가라고 말했지만.. 이기준은 gradle 5이상에서의 셋팅이다.. 아.. 5버젼에서 처음 셋팅하느라 고생을 ….하였다. 빨리하고 자려고 했는데..
build.gradle
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 plugins { id 'org.springframework.boot' version '2.1.5.RELEASE' id 'java' id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" } dependencies { 중략 ... compile("com.querydsl:querydsl-jpa" ) compile("com.querydsl:querydsl-apt" ) runtimeOnly 'mysql:mysql-connector-java' compile('org.springframework.boot:spring-boot-starter-data-jpa' ) ... 중략 } def querydslSrcDir = 'src/main/generated' querydsl { library = "com.querydsl:querydsl-apt" jpa = true querydslSourcesDir = querydslSrcDir } compileQuerydsl{ options.annotationProcessorPath = configurations.querydsl } configurations { querydsl.extendsFrom compileClasspath } sourceSets { main { java { srcDirs = ['src/main/java' , querydslSrcDir] } } }
application.yml
ddl 트루로 하자 구찮다.
1 2 3 4 5 6 7 8 9 10 spring: datasource: url: jdbc:mysql://localhost:3306/study username: root password: password jpa: generate-ddl: true hibernate.ddl-auto: create-drop
UserEntity.class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 @Data @Entity (name = "users" )public class UserEntity { @Id @GeneratedValue (strategy = GenerationType.IDENTITY) private long id; private String userId; private String name; private int age; @Builder public UserEntity (String userId, String name, int age) { this .userId = userId; this .name = name; this .age = age; } }
3. gradle build 아래와 같은 QClass가 위에서 명시한 src/main/generate아래에 생성되어진다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 import static com.querydsl.core.types.PathMetadataFactory.*;import com.querydsl.core.types.dsl.*;import com.querydsl.core.types.PathMetadata;import javax.annotation.Generated;import com.querydsl.core.types.Path;@Generated ("com.querydsl.codegen.EntitySerializer" )public class QUserEntity extends EntityPathBase <UserEntity > { private static final long serialVersionUID = 1472300146L ; public static final QUserEntity userEntity = new QUserEntity("userEntity" ); public final StringPath age = createString("age" ); public final NumberPath<Long> id = createNumber("id" , Long.class); public final StringPath name = createString("name" ); public final StringPath userId = createString("userId" ); public QUserEntity (String variable) { super (UserEntity.class, forVariable(variable)); } public QUserEntity (Path<? extends UserEntity> path) { super (path.getType(), path.getMetadata()); } public QUserEntity (PathMetadata metadata) { super (UserEntity.class, metadata); } }
4. repository 아래의 설명을 읽어야하는이유! ( you must )
you must first define a fragment interface and an implementation for the custom functionality, as shown in the following example:
https://docs.spring.io/spring-data/jpa/docs/2.1.3.RELEASE/reference/html/#repositories.custom-implementations
참고하면 좋을 사항https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl