以前用hibernate在处理连接查询都是使用创建新的映射实体来获取查询结果,效率低,使用也不方便,最近工作中查阅官方文档后发现hibernate是支持连接查询操作的。
当程序需要从多个数据表中获取数据时,Hibernate使用关联映射来处理底层数据表之间的连接,一旦我们提供了正确的关联映射后,当程序通过Hibernate进行持久化访问时,将可利用Hibernate的关联来进行连接。
hql的连接查询包括:隐式(implicit)与显式(explicit)。
隐式查询
使用"."隐式连接关联实体
隐式连接底层将转换成为SQL99的交叉连接
from person as p where p.myEvents.titile > :title
--底层转化后
select
person0_.person_id as person1_0_,
person0_.name as name_0,
person0_.age as age0_,
person0_.event_id as event4_0_
from
person person0_ cross
join
event myevent1_
where
person0_.event_id = myevent1_.event_id
and myevent1_.title > ?
显式查询
显式查询使用以下关键字
inner join(内连接) 可简写成 join
left outer join(左外连接),可简写成 left join
right outer join(右外连接),可简写成right join
full join(全连接),并不常用。
其中“with”的作用相当于SQL中的 “on”
使用显式连接时可以为相关联的实体,甚至是关联集合中的全部元素指定一个别名。
需要SQL底层的支持
from person p
inner join p.myEvent event
with p.eventId = event.id
where p.name like '%刘%'
--底层转化后
select
person0_.person_id as person1_0_,
person0_.name as name0_,
person0_.age as age0_,
person0_.event_id as event4_0_
from person person0_
left outer join
event myevent1_
on person0_.event_id = myevent1_.event_id
where
person0_.name like '%刘%'
项目中使用的情况:
//实体domain对象
public class ExpertException{
/**
* 专家ID(外键关联ExpertBasicinfo实体)
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="EXPERT_ID", referencedColumnName = "ID")
private ExpertBasicinfo expertBasicinfo;
}
//DAO中使用的sql语句,执行查询后,返回ExpertException实体的List集合
String queryString = "select e from ExpertException e " +
"left join " +
"e.expertBasicinfo i where 1=1";
/*
* ps:1、这里在ExpertException中配置了@ManyToOne(fetch = FetchType.Lazy)
* 可不必再 “left join” 后加 “fetch” 可实现懒加载的级联抓取
* 2、这里,where后面如果还要加查询条件,查询的属性不必用"object.property"的形式,直接使用属性名集合
* 但是这里的属性名字必须是@Column(name="**")中指定的名字即数据库表中名字,否则会报错
*/