我的规范化架构中有一些实体
@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选择将是最有效的方式。