====== QueryDSL Native SQL ====== * [[gradle:querydsl_native_sql_codegen|Gradle 에서 Native SQL Code Generation]] ===== XxxQueryFactory 를 사용하여 쿼리를 시작하라 ===== * [[http://www.querydsl.com/static/querydsl/4.1.3/reference/html/ch02s03.html|Querying SQL]] 문서를 보면 ''SQLQueryFactory'' 로 쿼리 생성을 시작하는데 실제로는 [DBType]SQLQueryFactory 를 사용해야 각 DB별 특수 문법을 사용할 수 있다. * [[https://github.com/querydsl/querydsl/blob/master/querydsl-sql/src/main/java/com/querydsl/sql/mysql/MySQLQueryFactory.java|MySQLQueryFactory]] * [[https://github.com/querydsl/querydsl/blob/master/querydsl-sql/src/main/java/com/querydsl/sql/mssql/SQLServerQueryFactory.java|SQLServerQueryFactory]] ... * [[https://github.com/querydsl/querydsl/blob/master/querydsl-jpa/src/main/java/com/querydsl/jpa/sql/JPASQLQuery.java|JPASQLQuery]] JPA용 SQLQuery. Factory는 없음. ===== SQL 생성시 schema 이름도 함께 출력 ===== * 아래와 같이 ''printSchema()'' 를 지정해야만 ''schema.tableName'' 형태로 SQL 생성 SQLTemplates mysqlTemplates = MySQLTemplates.builder().printSchema().build(); * 단, [[database:mysql|MySQL]]의 경우 ''schema'' 개념이 없어서 코드 생성시 코드 값이 올바로 안들어간다. 따라서 Meta Class 생성시 schema name이 null로 생성된다. 아래와 같이 하면 schema 지정이 가능해진다. QUser qUser = new QUser("user_alias", "user_schema_name", "user_table_name"); ===== XXXSQLQuery의 확장 ===== * ''XXXSQLQuery'' 클래스를 확장하여 각 DB만의 특수 문법을 추가하는 것이 가능하다. * JPASQLQuery 에서 native query 추가 : ''MySQLQuery'' 같은 순수 Native SQL 용 Query 클래스를 참조하여 ''addFlag,addJoinFlag'' 등을 작성해주면 된다. 혹은 ''JPASQLQuery''를 상속하여 ''addFlag,addJoinFlag'' 등을 미리 구현해 둔 클래스를 만들어 사용하는 것도 방법이다. * [[https://gist.github.com/kwon37xi/7de8dbe1a8ac7d31995c945eee3f796d|MySQLQuery 와 JPASQLQuery 를 참조해서 만든 MySQLJPASQLQuery]] * [[http://blog.mysema.com/2011/01/querying-in-sql-with-querydsl.html|Querying in SQL with QueryDSL]] ===== 문제점 ===== * 현재 catalog 개념을 지원하지 않는다. [[:mssqlserver|MS SQL Server]] 에서 여러 카탈로그(database)에 걸친 쿼리 작성이 불가능하다. * [[database:mysql|MySQL]] 은 스키마 지정으로 가능하다. * ''SQLSerializer''를 수정하여 테이블 앞에 'catalog'.'dbo'.'tablename' 으로 붙여주면 된다. * ''SQLSerializer''는 ''AbstractSQLClause''와 ''AbstractSQLQuery'' 에서 생성된다. * 따라서 위 두 클래스를 상속하는 클래스에서 ''createSerializer'' 메소드를 오버라이드 하여 원하는 대로 수정한 ''SQLSerializer''를 생성해주면 된다. * 혹은 ''com.querydsl.sql.SQLTemplates#requiresQuotes'' 를 override 해서 schema 가 ''catalogname.dbo'' 이런식이면 ''false''를 반환해도 될 것 같다. : SQLTemplates 의 DB전용 버전을 하나만 override 하면 되기 때문에 이게 제일 좋은 방법인 듯 하다. ===== infobip-spring-data-querydsl ===== * https://github.com/infobip/infobip-spring-data-querydsl ===== 참조 ===== * [[https://github.com/eXsio/querydsl-entityql|eXsio/querydsl-entityql: QueryDSL EntityQL - Native Query builder for JPA]] * [[https://bitbucket.org/atlassian/querydsl-examples/src/master/|Atlassian querydsl-examples]]