JOOQ 설정

권태용·2020년 12월 8일
0

QueryDSL을 사용하다. sub query select문을 조인해야하는 상황을 마주하게 되었다. QueryDSL은 sub query select문 join을 지원하지 않는다. JPA의 방향성을 고려하여 지원하지 않는다고 한다. 그때 CTO님이 Jooq라는 라이브러리를 알려주셨다.

이번 글에선 Jooq란 무엇이고 개발환경 구성시에 내가 겪었던 시행착오(삽질)에 대해 공유하려고 한다.

Jooq란?

https://www.jooq.org 사이트에 들어가면 Jooq를 아래와 같이 설명하고 있다.

jOOQ generates Java code from your database and lets you build type safe SQL queries through its fluent API.

jooq는 데이터베이스로부터 java 코드를 생성하고 TypeSafe한 쿼리를 좋은?원만한 API를 통해 생성할 수 있다.

음 내가 볼땐 QueryDSL과 똑같아 보인다. 여기서 내가 같다고 생각하는 부분은 도메인 클래스 QClass를 생성해서 도메인 클래스를 통해 쿼리를 생성한다는 점이다.

Code Generation

내가 가장 해맸던 부분이다. 내가 기존에 생각하던 API의 개념은 라이브러리 다운로드 받아서 해당 라이브러리 소스코드를 즉 클래스, 메소드를 호출해서 사용하면 되는 개념이였다. 하지만 QueryDSL과 Jooq는 도메인 클래스를 생성하고 해당 도메인 클래스의 상속인터페이스들의 함수를 호출한다.

다만 QueryDSL의 경우 APT 플러그인을 통해 javax.persistence.Entity 애노테이션을 가진 클래스들의 Q클래스를 자동으로 생성해준다. 그래서인지 Code Generation라는 개념을 놓치고 그냥 사용하는가 보다 싶었다.

하지만 Jooq의 경우 위 과정이 QueryDSL보다 조금 불편했다.

Jooq Code Generation With gradle-jooq-plugin

https://www.jooq.org/doc/latest/manual/code-generation/codegen-configuration/

공식 페이지에선 xml, programmatic, gradle 방식으로 Jooq Code를 생성하는 방법에 대해 설명하고 있다.

하지만 위 방법은 너무 귀찮다. 마치 xml로 bean을 정의 하는 느낌이랄까 ..
https://www.jooq.org/doc/3.7/manual/code-generation/codegen-gradle 그래서 plugin이 나왔다. 위 플러그인을 통해 gradle task 를 정의하고 해당 task로 codegenerate를 할 수 있다.

Code Generator Task

내가 가장 헤맸던 부분이다. Jooq의 CodeGeneration은 디비정보를 보고 Jooq Class를 생성한다. 때문에 디비 접속 정보를 명시해주어야 한다.

내가 헷갈렸던 부분은

첫번째로 DB 연결 드라이버 였다. MySQL을 사용할려면 jdbc를 사용해서 쓰는것은 알았지만 실제 드라이버 패키지명을 몰랐다..

두번째로 jooq codegenerator DB 메타정보 클래스 였다. 나는 gradle-jooq-plugin 패키지에서 DB 메타정보 클래스를 찾고 있었다.. 플러그인에서 정의한 메타정보 클래스가 있을거라 생각했기 때문이다. 여기서 CTO님이 도움을 주셨다. 도큐먼트를 보라고;; ㅋㅋ
https://www.jooq.org/doc/latest/manual/code-generation/codegen-advanced/codegen-config-database/codegen-database-name/ 이 글을 보면 jooq에서 각 디비에 대한 메타정보를 담고 있는 클래스 이름들이 나온다. 여기서 내가 사용하는 디비를 선택하면 된다.

나머지는 plugin의 READEME를 보면 어느정도 알 수 있다. 어떤 디비 스키마를 generate할 것인지, 제외할 테이블은 어떤 것인지, 생성 코드의 위치는 어디로 할 것인지 기타 등등의 설정 값들이 있다.

jooq {
    // use jOOQ version defined in Spring Boot
    version = dependencyManagement.importedProperties['jooq.version']
    edition = JooqEdition.OSS

    configurations {
        main {
            generationTool {
                logging = org.jooq.meta.jaxb.Logging.WARN
                jdbc {
                // DB 연결 드라이버
                    driver = 'com.mysql.cj.jdbc.Driver'
                    url = 'jdbc:mysql://localhost/db_name?serverTimezone=UTC'
                    user = 'root'
                    password = ''
                    properties {
                        property {
                            key = 'PAGE_SIZE'
                            value = 2048
                        }
                    }
                }
                generator {
                    name = 'org.jooq.codegen.DefaultGenerator'
                    database {
                    // jooq codegenerator 패키지의 디비 클래스
                        name = 'org.jooq.meta.mysql.MySQLDatabase'
                        inputSchema = 'db_schema_name'
                        includes = '.*'
                        excludes = 'schema_version'
                    }
                    target {
                        packageName = 'nu.studer.sample'
                        directory = 'src/main/generated'
                    }
                    strategy.name = "org.jooq.codegen.DefaultGeneratorStrategy"
                }
            }
        }
    }
}

JOOQ 사용후기

JOOQ를 효과적으로 사용하지는 못 했다. 주먹구구식으로 기존 RepoImpl클래스에 Jooq Context를 autowired로 받아 Document를 참고해가며 쿼리를 생성하고 VO클래스로 결과를 주입받아 View단위로 넘겨주기는 하였지만 QueryDSL보다 딱히 편하다는 느낌을 받지는 못 했다.

내가 아직 결과 값에대한 처리 방법을 잘 모르는 부분이 있는것이라 생각된다. 하지만 개발환경 설정 및 간단한 crud 작업에 대해서는 Hibernate가 훨씬 편하다는 생각이 들었다.

나중에 좀더 복잡한 쿼리가 필요하다면 사용성을 고려해 볼 수 있을것 같다.

profile
개발일기장

0개의 댓글