HQL连接查询和注解
HQL的连接查询
和SQL查询一样,HQL也支持各种各样的连接查询,如内连接、外连接
连接类型 | HQL语法 |
---|---|
内连接 | inner join 或 join |
迫切内连接 | inner join fetch 或 join fetch |
左外连接 | left outer join 或 left join |
迫切左外连接 | left outer join fetch 或 left join fetch |
右外连接 | right outer join 或 right join |
等值连接
-
适用于两个类之间没有定义任何关联时
-
在where子句中通过属性作为筛选条件
from Dept d,Emp e where d = e.dept
-
注意:
- 没有where条件,直接执行 ”from Dept d , Emp e“ 会返回笛卡尔积,结果没有实际意义
- 语句 from Dept d , Emp e where d.emps = e 是错误的,Set类型不能与Emp类型划等号
隐式内连接
from Emp e where e.dept.dname = 'SALES' //用于where子句
select empno,ename,dept.dname from Emp //用于selectt子句
- Hibernate会根据关联关系自动使用等值连接(等效于内连接)查询
- 允许以更加面向对象的方式编写HQL语句,跟多的依据对象间的关系,而不必考虑数据库结构
分组统计数据
-
聚合函数
函数名称 说明 count() 统计记录条数 sum() 求和 max() 求最大值 min() 求最小值 avg() 求平均值 -
子查询
-
子查询语句应用在HQL查询语句的where子句中
关键字 说明 all 返回所有记录 any 返回的任意一条记录 some 和”any“意思相同 in 与”=any“意思相同 exists 至少返回一条记录
//查询工资高于平均工资的员工 from Emp e where e.salary > (select avg(salary) from Emp) //查询所有员工工资都小于5000元的部门,包含没有员工的部门 from Dept d where 5000 > all(select e.salary from d.emps e) //查询所有员工工资都小于5000元的部门,不包含没有员工的部门 from Dept d where 5000 > all(select e.salary from d.emps e) and d.emps.size > 0 //查询至少有一位员工工资低于5000元的部门 form Dept d where 5000 > any(select e.salary from d.emps e) //查询员工工资正好是5000元的部门 form Dept d where 5000 = some(select e.salary from d.emps e) form Dept d where 5000 in (select e.salary from d.emps e) //查询至少有一位员工的部门 from Dept d where exists (from d.emps) //查询指定员工所在部门 from Dept d where ? in elements(d.emps) //查询员工个数大于X的部门(例:X=5) from Dept d where d.emps.size > 5
函数或属性 说明 size() 或 size 获取集合中元素的数目 minIndex()或minIndex 对于建立了索引的集合,获取最小的索引 maxIndex()或maxIndex 对于建立了索引的集合,获取最大的索引 minElement()或minElement 对于包含基本类型元素的集合,获取最小元素 maxElement()或maxElement 对于包含基本类型元素的集合,获取最大元素 elements() 获取集合中所有元素 -
查询性能优化
- Hibernate查询优化策略
- 使用延迟加载等方式避免加载多余数据
- 通过使用连接查询,配置二级缓存、查询缓存等方式减少select语句数目
- 结合缓存机制,使用iterate()方法减少查询字段数及数据库访问次数
- HQL优化
- 注意避免or、not、like使用不当导致的索引失效
- 注意避免having子句、distinct导致的开销
- 注意避免对索引字段使用函数或进行计算导致的索引失效
在Hibernate中使用注解
-
代替XXX.hbm.xml文件完成对象-关系映射
-
使用步骤如下:
-
使用注解配置持久化类以及对象关系
-
注解配置持久化类
注解 含义和作用 @Entity 将一个类声明为一个持久化类 @Table 为持久化类映射指定表 @Id 声明了持久化类的标识属性 @GeneratedValeu 定义标识属性值的生成策略 @SequenceGenerater 定义序列生产器 @Column 将属性映射到列(字段) @Transient 将忽略这些属性 -
注解配置关联关系
注解 含义和作用 @OneToOne 建立持久化类之间的一对一关联关系 @OneToMany 建立持久化类之间的一对多关联关系 @ManyToOne 建立持久化类之间的多对一关联关系 @JoinColumn 和@ManyToOne配合,指定外键列 @ManyToMant 建立持久化类之间的多对多关联关系
@Entity @Table(name = "`DEPT`") public class Dept implements Serializable{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer deptNo; @Column(name = "deptName") private String deptName; @OneToMany(mappedBy = "dept", cascade = {CascadeType.ALL}) private Set<Emp> emps = new HashSet<Emp>(); //省略getter、setter访问器 }
@Entity @Table(name = "`EMP`") public class Emp implements Serializable{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer empNo; @Column(name = "deptName") private String empName; @ManyToOne @JoinColumn(name = "deptNo") private Dept dept; //省略getter、setter访问器 }
-
-
在Hibernate配置文件(hibernate.cfg.xml)中声明持久化类
- < mapping class=“持久化类完整限定名” />
-