Hibernate第六章知识点总结——第六章--高级查询
关联映射回顾
事务管理概述
ACID/三种问题/四种隔离级别
Hibernate事务API
JDBC实现/JTA实现
锁机制
悲观锁/乐观锁
目标
熟练应用Criteria、Query
掌握Criteria查询表达式
熟练应用HQL进行各种查询
掌握分页查询方式及机制
知识点预览
Criteria、Query
Criteria查询表达式
HQL
分页查询方式
Criteria
1. Criteria
a) Criteria面向对象化查询接口,将数据查询条件封装为一个对象,可以把它看成传统SQL的对象化表示
Criteria查询表达式
1. Criteria表达式
a) Criteria本身只是个查询容器,具体的查询条件需要通过Cretiria.add方法添加到Criteria实例中。
b) Expression具体描述查询条件,针对SQL语法,Expression提供了对应的查询限定机制。
2. 查询限定机制
a) Expression各方法属性名参数,为POJO中所对应的实际库表字段属性名(
大小写敏感),而非库表中实际字段名。
3. Criteria 查询示例
a) 查询年龄大于18的用户:
Criteria c=session.createCriteria(User.class);
c.add(Expression.gt(“userAge”,18));
b) 查询年龄大于20小于30的用户:
Criteria c=session.createCriteria(User.class);
c.add(Expression.between(“userAge”,new Integer(20),new Integer(30)));
c) 或者:
c.add(Expression.gt(“userAge”,new Integer(20)));
c.add(Expression.lt(“userAge”,new Integer(30)));
4. Criteria 复合查询
User和Address属于一对多的关联关系,根据地址条件查询用户:
Criteria c=session.createCriteria(User.class);
Criteria c1=c.createCriteria(“addr”);
c1.add(Expression.like(“city”,”%shanghai%”));
SQL:
Select * from t_user user inner join t_addr addr on user.id=addr_user_id
where addr.city like ‘%shanghai%’
5. Criteria 分页和排序
a) 分页:
Criteria.setFirstResult(100);
Criteria.setMaxResults(20);
b) 排序:
Criteria.addOrder(Order.asc(“”));
Criteria.addOrder(Order.desc(“”));
6. Criteria 分组与统计
Hibernate3新引入Projections Class进行封装分组、统计表达式。
Projections.groupProperty(“age”);
Projections.avg();
Projections.count();
Projections.max();
Projections.min();
……
HQL
1. HQL概述
a) HQL(Hibernate Query Language)提供更加丰富灵活、更为强大的查询能力;
b) HQL更接近SQL语句查询语法;
[select/delete/update…][from…][where…][group by…][having…][order by…]
2. 实体查询—概述
a) 1、String hql=“from User”;
b) 2、hql=“from com.oracle.entity.User”;
Query q=session.createQuery(hql);
List userList=q.list();
c) 注意:
1、应用中存在同名类(包不同),要注意使用全类名方式
2、HQL子句本身大小写无关,但是其中出现的类名和属性名必须注意区分大小写
3. 实体查询—多态查询
a) 查询对象存在继承关系时查询
String hql=“from Account”;
b) 查询数据库中所有库表记录
String hql=“from java.lang.Object”;
4. 实体查询—where子句
a) 语法
String hql=“from User as u where u.userName like ‘z%’ ”;
as/where
b) 比较操作符
=,<>,<,>,>=,<=,between,not between,in,not in,is,like等
c) 示例
String hql=“from User u where u.userAge>20”;
String hql=“from User u where u.userAge between 12 and 30”;
String hql=“from User u where u.name is null”;
5. 属性查询
a) 语法
List list=s.createQuery(“select u.userName from User u”).list();
返回每个条目都是Obiect[ ]
b) 面向对象查询结果封装
List list=s.createQuery(“select new User(u.userName,u.userAge) from User u”).list();
返回每个条目都是User对象,但是它只是内存状态下新对象,并不是持久化对象
c) 原生SQL函数支持
String hql=“select upper(u.userName) from User u”;
String hql=“select distinct u.userName from User u ”;
6. 实体更新与删除
a) Hibernate3新功能,Hibernate2之前HQL仅用于数据查询,若想更新及删除,只能先查询出实体,在进行基于实体的操作
b) 语法
String hql=“update User set userAge=18”;
String hql=“delete User where userAge>18”;
7. 分组与排序
a) Order by
语法:String hql=“from User u order by u.userAge desc”
选项:asc/desc
b) Group by
语法:String hql=“select count(u) ,u.userAge from User u group by u.userAge”;
条件过滤:having
示例:查询超过10个人的年龄组
String hql=“select count(u),u.userAge from User u group by u.userAge having count(u)>10”
List list=s.createQuery(hql).list()
8. 参数绑定—直接书写
a) 直接写在HQL中
String hql=“from User u where u.userAge>”+age;
b) 缺点
编码凌乱,可读性低
多个可变查询参数,HQL字符串的组合拼装代码将显得无序
难以进行性能优化
JDBC每次执行SQL时,数据库将对SQL进行解析和优化,并保存在缓存中,之后参数不同、语法相同sql,则直接将此缓存加以执行,避免SQL分析及优化开销,如果把参数直接写到SQL中,导致每次都是不同的SQL,增加数据库性能开销
安全风险(SQL Injection)
from User where name=‘zz’ or ‘x’=‘x’ and pwd=‘123’
9. 参数绑定—占位符
a) 顺序占位符
Session方法填充
Query接口填充
b) 示例
s.find(“from User u where u.userName=?”,”zz”,Hibernate.STRING)
Query q=s.createQuery(“from User u where u.userName=? And u.userAge=?”);
q.setString(0,”zz”);
q.setInteger(1,21);
c) 引用占位符
Query接口填充
javaBean封装查询参数
d) 示例
Query q=s.createQuery(“from User u where u.userName=:name ”);
q.setString(“name”,”zz”);
Query q=s.createQuery(“from User u where u.userName=:name and u.userAge=:age”);
user.setUserName();user.setuserAge();
q.setProperties(user);
10. 参数绑定—动态绑定优点
a) 性能优化
参数单独绑定,使得查询语法与参数数值相互独立
b) 安全优化
有效避免SQL注入
11. 引用查询—概述
a) SQL语句混在代码中将破坏代码可读性,使得系统的可维护性降低
b) 实现SQL可配置化操作
12. 引用查询—配置文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.oracle.entity.User" table="T_USER“ >
<id name="userId" type="java.lang.Integer">
<generator class="native" />
</id>
<property name="userName" type="java.lang.String"></property>
<property name="userAddress" type="java.lang.String"></property>
<property name="userAge" type="java.lang.Integer"></property>
</class>
<query name="queryByName">
<![CDATA[
from User u where u.userName=:name
]]>
</query>
</hibernate-mapping>
13. 引用查询—持久化代码片段
public class Test {
public static void main(String[] args) {
Configuration cfg = new Configuration().configure();
SessionFactory sf = null;
Session s1 = null;
Session s2 = null;
try {
sf = cfg.buildSessionFactory();
s1 = sf.openSession();
Query q=s1.getNamedQuery("queryByName");
q.setString("name", "zz");
System.out.println(q.list().size());
} catch (HibernateException e) {
e.printStackTrace();
}finally{
if(s1!=null){s1.close();}if(sf!=null){sf.close();}
}
}
}
14. 联合查询—概述
a) inner join
b) left outer join
c) right outer join
d) full join
15. 联合查询—inner join
a) 语法
From User u inner join fetch u.addr
b) 结果集
c) fetch
表示Addr读出后立即填充到User对象(addr属性)中
若无,则返回Object[ ]包含User和Addr对象
16. 联合查询—left outer join
a) 语法
b) From User u left outer join fetch u.addr
c) 结果集
d) SQL
e) Select * from T_USER user left outer join T_ADDR addr on user.id=addr.user_id
17. 联合查询—right outer join
a) 语法
From User u right outer join u.addr
b) 结果集
c) SQL
d) Select * from T_USER user right outer join T_ADDR addr on user.id=addr.user_id
18. 联合查询—full join
a) 语法
From User u full join fetch u.addr
b) 结果集
c) SQL
Select * from T_USER user full outer join T_ADDR addr on user.id=addr.user_id
19. 子查询
a) 在当前查询中利用另外一条查询语句的结果
b) 示例
查询拥有两条及以上地址的用户
From User u where(select count(*) from u.addr)>1
c) SQL
Select * from T_USER u where ( (select count(*) from T_ADDR addr where user.id=addr.user_id)>1)
20. SQL查询—概述
a) Hibernate提供了对原生SQL及存储过程(Hibernate3)的支持;
b) Hibernate对SQL进行封装(与JDBC比较)
c) 只需要指定别名,ResultSet和实体的映射由Hibernate自动完成
21. SQL查询
总结
Hibernate数据检索
Criteria
HQL
实体查询
属性查询
实体更新与删除
分组与排序
参数绑定
引用查询
联合查询
子查询
SQL查询
问题
比较几种连接查询
完善课堂案例熟练应用HQL查询语句