web38Hibernate笔记四
1 hibernate的查询方式
**1.1 对象导航查询 :**根据id查询某个客户,再查询这个客户里面所有的联系人
// 查询cid=2的客户,再查询这个客户的所有联系人
Customer customer = session.get(Customer.class, 2);
// 查询到客户以后,直接得到联系人里面的set集合
Set<LinkMan> linkmans = customer.getSetLinkMan();
**1.2OID查询:**调用session里面的get方法实现
Customer customer = session.get(Customer.class, 2);
1.3HQL查询: hibernate query language,hibernate提供一种查询语言,hql语言和普通sql很相似,区别:普通sql操作数据库表和字段,hql操作实体类和属性
- 常用的hql语句
1. 查询所有: from 实体类名称
2. 条件查询: from 实体类名称 where 属性名称=?
3. 排序查询: from 实体类名称 order by 实体类属性名称 asc/desc - 使用hql查询操作时候,使用Query对象
(1) 查询所有
// 1创建Query对象,写hql语句
Query query = session.createQuery("from Customer");
// 2.调用方法得到结果
List<Customer> list = query.list();
(2)条件查询
from 实体类名称 where 实体类属性名称=? and实体类属性名称=?
from 实体类名称 where 实体类属性名称 like ?
// 1 创建Query对象,写hql语句
Query query = session.createQuery("from Customer where cid=? and custName=?");
// 2.设置条件值
// setParameter 方法两个参数,第一个参数是?的位置,从0开始,第二个参数具体的值
query.setParameter(0, 3);
query.setParameter(1, "百度");
// 调用方法得到结果
List<Customer> list = query.list();
(3)排序查询
from 实体类名称 order by 实体类属性名称 asc/desc
Query query = session.createQuery("from Customer order by cid asc");
// 调用方法得到结果
List<Customer> list = query.list();
(4)分页查询
//1. 创建
Query query = session.createQuery("from Customer ");
// 设置分页数据
// 2.1 设置开始位置
query.setFirstResult(0);
query.setMaxResults(3);
// 调用方法得到结果
List<Customer> list = query.list();
(5)投影查询: 查询的不是所有字段值,而是部分字段的值
select 实体类属性名称1, 实体类属性名称2 from 实体类名称,select 后面不能写 * ,不支持的
Query query = session.createQuery("select custName from Customer ");
List<Object> list = query.list();
(6)聚集函数使用
Query query = session.createQuery("select count(*) from Customer ");
// 调用方法得到结果
// query对象里面有方法,直接返回对象形式
Object obj = query.uniqueResult();//返回的值是long类型,不是int类型
4 QBC 查询
使用hql查询需要写hql语句实现,但是使用qbc时候,不需要写语句了,使用方法实现, 使用qbc时候,操作实体类和属性,使用qbc,使用Criteria对象实现
(1)查询所有
// 1创建对象
Criteria criteria = session.createCriteria(Customer.class);
// 2 调用方法得到结果
List<Customer> list = criteria.list();
(2)条件查询
// 1创建对象
Criteria criteria = session.createCriteria(Customer.class);
// 2 使用criteria对象里面的方法设置条件值
// 首先使用add方法,表示设置条件值,在add方法里面使用类的方法实现条件设置
criteria.add(Restrictions.eq("cid", 3));
criteria.add(Restrictions.eq("custName", "百度"));
// 2 调用方法得到结果
List<Customer> list = criteria.list();
(3)排序查询
Criteria criteria = session.createCriteria(Customer.class);
// 设置对哪个属性进行排序,设置排序规则
criteria.addOrder(Order.asc("cid"));//升序
List<Customer> list = criteria.list();
(4)分页查询
Criteria criteria = session.createCriteria(Customer.class);
// 设置分页数据
// 设置开始位置
criteria.setFirstResult(0);
// 每页显示记录数
criteria.setMaxResults(3);
(5)统计查询
Criteria criteria = session.createCriteria(Customer.class);
// 设置操作
criteria.setProjection(Projections.rowCount());
Long obj = (Long) criteria.uniqueResult();
(6)离线查询
应用场景: servlet调用service,service调用dao,在dao里面对数据库crud操作,在dao里面使用hibernate框架,使用hibernate框架时候,调用session里面的方法实现功能
// 1 创建对象
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);
// 最终执行时才需要用到session
Criteria criteria = detachedCriteria.getExecutableCriteria(session);
List<Customer> list = criteria.list();
5 hql多表查询
- 内连接、迫切内连接、左外连接、迫切左外连接、右外连接
1 内连接查询hql语句写法:以客户和联系人为例
(1)from Customer c inner join c.setLinkMan
// 1 创建query对象
Query query = session.createQuery("from Customer c inner join c.setLinkMan ");
List list = query.list();
返回list,list里面每部分是数组形式。
**迫切内连接:**迫切内连接和内连接底层实现一样的,区别:使用内连接返回list中每部分是数组,迫切内连接返回list每部分是对象,只需要加一个关键字fetch
from Customer c inner join fetch c.setLinkMan
HQL左外连接
(1)from Customer c left outer join c.setLinkMan
(2)迫切左外连接from Customer c left outer join fetch c.setLinkMan
左外连接返回list中每部分是数组,迫切左外连接返回list每部分是对象
迫切左外连接
右外连接语句: from Customer c right outer join c.setLinkMan
6 hibernate的检索策略
(1)概念
立即查询:根据id查询,调用get方法,一调用get方法马上发送语句查询数据库
延迟查询:根据id查询,还有load方法,调用load方法不会马上发送语句查询数据,只有得到对象里面的值时候才会发送语句查询数据库
- 延迟查询分成:类级别和关联级别延迟
类级别延迟:根据id查询返回实体类对象,调用load方法不会马上发送语句
关联级别延迟
查询某个客户,再查询这个客户的所有联系人,查询客户的所有联系人的过程是否需要延迟,这个过程称为关联级别延迟
关联延迟是hibernate默认的,可以通过配置
1 在映射文件中进行配置实现
(1)根据客户得到所有的联系人,在客户映射文件中配置
2 在set标签上使用属性
(1)fetch:值select(默认)
(2)lazy:值
- true:延迟(默认)
- false:不延迟
- extra:极其延迟
调用get之后发送两条sql语句
及其懒惰:就是你要什么数据,它给你什么数据
批量抓取
应用场景: 查询所有的客户,返回list集合,遍历list集合,得到每个客户,得到每个客户的所有联系人
上面操作代码,发送多条sql语句
在客户的映射文件中,set标签配置
batch-size值,值越大发送语句越少