groupId
도 io.github.openfeign.querydsl
로 변경되었다.// 미리 초기화를 호출하는게 좋다. packageToLoad 를 변경해준다. ClassPathUtils.scanPackage(Thread.currentThread().getContextClassLoader(), packageToLoad);
fetch()
를 사용해야 한다.from(parent).innerJoin(parent.child).fetch() ....
Parent - Child
가 1:1 관계일 때 다음과 같이 쿼리했더니 inner join과 cross join이 함께 발생했다.QParent parent = QParent.parent; QChild child = parent.child; from(parent).innerJoin(parent.child).fetch() .where(parent.something.gt(parent.child.somthing))....;
innerJoin
에 PATH를 지정했더니 cross join이 사라졌다.QParent parent = QParent.parent; QChild child = QChild.child; // 여기 달라짐 from(parent).innerJoin(parent.child, child).fetch() // as 처리가 필요함. .where(parent.something.gt(child.somthing))....;
JPAExpressions.select
를 이용하여 각종 Sub Query 생성가능.ExpressionUtils.as([subquery])
로 묶어준다.xxxTemplate
를 통해서 native 쿼리 조건을 만들어 낼 수 있다.registerFunction
)로 등록돼 있어야 한다.// MySQL의 TIMESTAMPDIFF를 Expression으로 만들기 Expressions.numberTemplate(Long.class, "TIMESTAMPDIFF(HOUR, {0}, {1})", QSomething.dateField, QOtherThing.anotherDateField); // 이것을 메소드로 빼면 다음과 같은 형태가 된다. public static NumberExpression<Long> hourDiff( Expression<? extends Date> left, Expression<? extends Date> right) { return Expressions.numberTemplate(Long.class, "TIMESTAMPDIFF(HOUR, {0}, {1})", left, right); }
Expressions.constant(객체)
는 Java 객체를 그에 맞는 JDBC 객체로 변환해준다.// 0.12 - w.totalCost 를 나타내고자 한다. Expressions.operation(Float.class, Ops.SUB, Expressions.constant(0.12f), w.totalCost) // or NumberOperation.create(Float.class, Ops.SUB, Expressions.constant(0.12f), w.totalCost)
BooleanBuilder
를 사용한다.public List<Customer> getCustomer(String... names){ QCustomer customer = QCustomer.customer; HibernateQuery qry = new HibernateQuery(session).from(customer); BooleanBuilder builder = new BoolenBuilder(); for (String name : names){ builder.or(customer.name.eq(name)); } qry.where(builder); // customer.name eq name1 OR customer.name eq name2 OR ... return qry.list(customer); }
CaseBuilder
사용.CaseBuilder
사용시 when
과, otherwise
는 ?
파라미터로 안먹고 무조건 상수로만 먹는듯 보임.when
과 otherwise
가 DB 입장에서 봤을 때 동일한 타입이 되는 상수로 맞춰줘야 한다.// registerDate 가 DATE 컬럼 일때 // newRegisterDate 는 LocalDateTime.class Expression<LocalDateTime> modifyDateTime = new CaseBuilder() .when(qUser.registerDate.eq(expectedRegisterDate)) .then(qUser.registerDate) // DB 입장에서 DATE 컬럼 .otherwise( // DB 입장에서 DATE 인 'TO_DATE' 함수를 사용해서 변경해줌. 상수값만 // 들어가기 때문에 어쩔 수 없이 문자로 모든 것을 넣어줌 Expressions.dateTimeTemplate(LocalDateTime.class, "to_date({0}, {1})", newDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), Expressions.constant("yyyy-MM-dd HH:mm:ss")) );
@Column
)이 없으면 모델 소스 (Q*) 생성시에 더 자식쪽 Embeddable의 필드에 대한 모델 소스가 올바르게 생성되지 않았다.SimpleSerializerConfig.getConfig
에서 NullPointerException
발생하는 경우가 있는데 이는 QueryDSL과 아무 상관 없는 코드 중에 의존성에 들어가지 않는 Annotation을 넣은게 있었기 때문이었다(Java 8에서는 올바른 컴파일 오류 지점이 보였음).Caused by: java.lang.NullPointerException at com.mysema.query.codegen.SimpleSerializerConfig.getConfig(SimpleSerializerConfig.java:29) at com.mysema.query.apt.DefaultConfiguration.<init>(DefaultConfiguration.java:137) at com.mysema.query.apt.jpa.JPAConfiguration.<init>(JPAConfiguration.java:54) ...