사용자 도구

사이트 도구


java:querydsl

QueryDSL

Q-Types multi thread loading 시 dead lock

// 미리 초기화를 호출하는게 좋다. packageToLoad 를 변경해준다.
ClassPathUtils.scanPackage(Thread.currentThread().getContextClassLoader(), packageToLoad);

join 성능 향상

  • Join 시 그 결과로 나오는 관계 객체를 Eager Loading 하려면 fetch() 를 사용해야 한다.
from(parent).innerJoin(parent.child).fetch()
....

JPA QueryDSL Cross Join 발생

  • 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))....;

Native 조건 condition

  • ExpressionsxxxTemplate를 통해서 native 쿼리 조건을 만들어 낼 수 있다.
// 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);
}

상수가 들어가는 표현식

// 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);
    }

@Embeddable의 필드 소스 생성

  • Embeddable안에 또 다른 Embeddable이 있을 경우, 더 자식쪽 Embeddable의 경우 명시적 컬럼 매핑(@Column)이 없으면 모델 소스 (Q*) 생성시에 더 자식쪽 Embeddable의 필드에 대한 모델 소스가 올바르게 생성되지 않았다.
  • 버그로 보인다.

Metamodel 생성

  • Java 7에서 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)
    	...

참고

java/querydsl.txt · 마지막으로 수정됨: 2018/04/12 08:52 저자 kwon37xi