QueryDSL加入多个字段

时间:2018-09-28 13:10:14

标签: querydsl

我的规范化架构中有一些实体

@Entity
public class Dual {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;
  @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
  private Member member1;
  @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
  private Member member2;
  ...
}

@Entity
public class Member {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long id;
  private String name;
  @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
  private Address address;
  ...
}

@Entity
public class Address {
   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   private Long id;
   private String zip;
   ...
}

现在,用例是选择所有包含至少一个成员且地址具有特定邮政编码的Dual实体。

在纯SQL中,这意味着类似

SELECT * from DUAL d 
INNER JOIN MEMBER m on (d.member1 = m.id OR d.member2 = m.id)
INNER JOIN ADDRESS a on m.address = a.id
WHERE a.zip = '12345'

是否有机会表达这种智慧QueryDSL 4.1.3?

到目前为止,根据文档,我所能得到的是

final String zip = "12345";
final QDual qdual = QDual.dual;
final JPAQuery<Dual> dualQuery = new JPAQuery<>(em)
            .select(qdual)
            .from(qdual)
            .where(qdual.member1.address.zip.eq(zip)
               .or(qdual.member2.address.zip.eq(zip)
             ));

这会生成一个不太合适的交叉联接查询

select dual0_.id as id1_160_, 
       dual0_.member1_id as member2_160_, 
       dual0_.member2_id as member3_160_ 
from Dual dual0_ cross join 
     Member member1_ cross join 
     Address address2_ cross join 
     Member member3_ cross join 
     Address address4_ 
where dual0_.member1_id=member1_.id and 
      member1_.address_id=address2_.id and 
      dual0_.member2_id=member3_.id and 
      member3_.address_id=address4_.id and 
      (address2_.zip=? or address4_.zip=?)

在解释计划上花了一些时间,在我看来,在这种情况下,UNION选择将是最有效的方式。

0 个答案:

没有答案