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操作实体类和属性

  1. 常用的hql语句
    1. 查询所有: from 实体类名称
    2. 条件查询: from 实体类名称 where 属性名称=?
    3. 排序查询: from 实体类名称 order by 实体类属性名称 asc/desc
  2. 使用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();

web38Hibernate笔记四
(3)排序查询
web38Hibernate笔记四

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里面每部分是数组形式。
web38Hibernate笔记四
**迫切内连接:**迫切内连接和内连接底层实现一样的,区别:使用内连接返回list中每部分是数组,迫切内连接返回list每部分是对象,只需要加一个关键字fetch

from  Customer  c  inner  join  fetch  c.setLinkMan

web38Hibernate笔记四
HQL左外连接

(1)from  Customer  c  left  outer  join  c.setLinkMan
(2)迫切左外连接from  Customer  c  left  outer  join  fetch  c.setLinkMan
左外连接返回list中每部分是数组,迫切左外连接返回list每部分是对象

web38Hibernate笔记四
迫切左外连接
web38Hibernate笔记四
右外连接语句: from Customer c right outer join c.setLinkMan

6 hibernate的检索策略
(1)概念
立即查询:根据id查询,调用get方法,一调用get方法马上发送语句查询数据库
web38Hibernate笔记四
延迟查询:根据id查询,还有load方法,调用load方法不会马上发送语句查询数据,只有得到对象里面的值时候才会发送语句查询数据库
web38Hibernate笔记四

  • 延迟查询分成:类级别和关联级别延迟

类级别延迟:根据id查询返回实体类对象,调用load方法不会马上发送语句
关联级别延迟
查询某个客户,再查询这个客户的所有联系人,查询客户的所有联系人的过程是否需要延迟,这个过程称为关联级别延迟
web38Hibernate笔记四
关联延迟是hibernate默认的,可以通过配置
1 在映射文件中进行配置实现
(1)根据客户得到所有的联系人,在客户映射文件中配置

2 在set标签上使用属性
(1)fetch:值select(默认)
(2)lazy:值

  • true:延迟(默认)
  • false:不延迟
  • extra:极其延迟
    web38Hibernate笔记四
    web38Hibernate笔记四
    调用get之后发送两条sql语句
    web38Hibernate笔记四
    及其懒惰:就是你要什么数据,它给你什么数据
    web38Hibernate笔记四

web38Hibernate笔记四
批量抓取
应用场景: 查询所有的客户,返回list集合,遍历list集合,得到每个客户,得到每个客户的所有联系人
上面操作代码,发送多条sql语句
web38Hibernate笔记四
在客户的映射文件中,set标签配置
batch-size值,值越大发送语句越少
web38Hibernate笔记四