今天来说一说必须要使用表链接的方式查询的情况:
1、一对一外键关联时,查询未加入外键的一方
介绍下上图中两个对象的关系:
userinfo(用户)
cardinfo(门禁卡)
由于一个用户只能有一个门禁卡,一个门禁卡也只能属于一个用户,所以采用一对一关联关系。
用户可以没有卡,但是卡必须得属于一个用户,所以用户是主表,cardinfo 可以为 null 。
当查询所有无卡的用户时,需要判断 userinfo.cardinfo 是否为 null ,这种无外键在 userinfo 表中的对象关联查询,需要使用表连接查询:
select u from UserInfo u left join u.cardInfo c where c is null
但仅仅在判断 userinfo.cardinfo 是否为 null 时才需要表链接查询,匹配 cardinfo 中的其他字段无需表连接,无论是外键对象字段还是普通字段:
外键对象字段:
from UserInfo u where u.cardInfo.modifiedUser is null
普通字段:
from UserInfo u where u.cardInfo.eCardStatus = 1
2、一对多
类似上面这种面对集合对象,不管是要查询没有录入人脸记录的用户还是要匹配人脸记录表的字段,都必须采取表连接查询。
select distinct u from UserInfo u left join u.faceTemplate f where f is null
需要注意的是,这里必须加 distinct 来去重,因为一个用户会有多个人脸记录,当左连接查询时,左边的用户会根据人脸记录的个数而出现多条结果记录。
3、多对多
这个就不用说了,跟一对多的情况其实是一样的,也是面对集合对象
@ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "user_link_role", joinColumns = { @JoinColumn(name = "user_id") }, inverseJoinColumns = { @JoinColumn(name = "role_id") }) private List<Role> roles = new ArrayList<Role>();
剩下的两种情况,不需要表连接,可以直接查询,直接判断是否为 null:
1、一对一加入外键的一方
from CardInfo c where c.userInfo is null
2、多对一
from UserInfo u where u.sex is null