八 Hibernate延迟加载&抓取策略(优化)
面试:Hibernate效率很低,如何优化?
缓存怎么弄的,语句怎么优化?
聊聊一级缓存,聊聊抓取策略和延迟加载,聊聊批量抓取
延迟加载:
一般不单独使用,和延迟加载一起使用
延迟加载:lazy(懒加载)
执行到该行代码的时候不会发送语句,真正使用这个对象的属性的时候才会发送sql语句进行查询。
- 类级别延迟加载:指的是是通过load方法查询某个对象的时候是否采用延迟,通过class标签上的lazy来配置。
- 让类级别延迟加载失效:1 lazy设为false 2 final修饰 3 调用Hibernate.initialize
- 关联级别的延迟加载:指的是查询某个对象的关联对象的时候,是否采用延迟加载。session.get(Customer.class,1l) , customer.getLinkMans();
- 抓取策略往往和关联级别的延迟加载一起使用,优化语句
类级别延迟加载配置:默认为true

关联级别的延迟加载配置:在映射文件被关联的对象上配置

抓取策略:
通过一个对象抓取到关联对象需要发送sql语句,sql语句如何发送,发送成什么格式通过策略进行配置
- 通过<set> 或者发送一条子查询上通过fetch属性进行设置
- fetch和这些标签上的lazy如何设置优化发送的语句
<set>上的fetch和lazy
fetch:抓取策略,控制sql语句格式
- select: 默认值,发送普通select语句,查询关联对象,至少交互两次
- join: 发送迫切左外连接查询关联,与数据库交互一次,发一条数据
- subselect:发送一条子查询查询关联对象
lazy:延迟加载,控制查询关联对象的时候是否采用延迟
- true:默认值,查询关联对象默认采用延迟加载
- false:查询关联对象不采用延迟加载
- extra :极其懒惰。
在实际开发中,一般都采用默认值。如果有特殊需求,可能配置join
各种配置的区别测试:
/**
* 在<set>上的fetch和lazy
*/
public class HibernateDemo4 {
@Test
/**
* 默认情况
*/
public void demo1() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 查询1号客户
Customer customer = session.get(Customer.class, 1l);// 发送一条查询客户的sql
System.out.println(customer.getCust_name());
// 查看1号客户每个联系人的信息
for (LinkMan linkMan : customer.getLinkMans()) {// 发送一条根据客户查询联系人的sql
System.out.println(linkMan.getLkm_name());
}
transaction.commit();
} @Test
/**
* 设置fetch=select,lazy = true
*/
public void demo2() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 查询1号客户
Customer customer = session.get(Customer.class, 1l);// 发送一条查询客户的sql
System.out.println(customer.getCust_name());
// 查看1号客户每个联系人的信息
for (LinkMan linkMan : customer.getLinkMans()) {// 发送一条根据客户查询联系人的sql
System.out.println(linkMan.getLkm_name());
}
transaction.commit();
} @Test
/**
* 设置fetch=select,lazy =false
*/
public void demo3() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 查询1号客户
Customer customer = session.get(Customer.class, 1l);// 不延迟,直接发送两条语句,查询客户的sql,根据客户查询联系人的sql
System.out.println(customer.getCust_name());
System.out.println(customer.getLinkMans().size());// 发送一条select
// count(lkm_id)
// from transaction.commit();
} @Test
/**
* 设置fetch=select,lazy =extra
*/
public void demo4() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 查询1号客户
Customer customer = session.get(Customer.class, 1l);// 发送一条查询客户语句
System.out.println(customer.getCust_name()); System.out.println(customer.getLinkMans().size());// 发送一条select
// count(lkm_id)
// from
transaction.commit();
} @Test
/**
* 设置fetch=join,lazy =失效
*/
public void demo5() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 查询1号客户
Customer customer = session.get(Customer.class, 1l);// 发送一条迫切左外连接语句,两表全查
System.out.println(customer.getCust_name()); System.out.println(customer.getLinkMans().size());// 不发语句
transaction.commit();
} @Test
/**
* 设置fetch=subselect,lazy =true
*/
public void demo6() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 查询1号客户
List<Customer> list = session.createQuery("from Customer").list();// 发送查询所有客户的sql语句
for (Customer customer : list) {
System.out.println(customer.getCust_name());
System.out.println(customer.getLinkMans().size());// 发送一条子查询
}
transaction.commit();
} @Test
/**
* 设置fetch=subselect,lazy =false
*/
public void demo7() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
// 查询1号客户
List<Customer> list = session.createQuery("from Customer").list();// 发送查询所有客户的sql语句,发送一条子查询
for (Customer customer : list) {
System.out.println(customer.getCust_name());
System.out.println(customer.getLinkMans().size());
}
transaction.commit();
} }
<many-to-one>上的fetch和lazy
fetch:抓取策略
- select:默认值,发送普通sql查询关联对象
- join:发送迫切左外连接
lazy:延迟加载,控制查询关联对象的时候是否采用延迟
- proxy:默认值,具体的取值和另一端<class>上lazy的值相同
- false:查询关联对象,不采用延迟
- no-proxy(不会使用)
一般使用默认值
各种配置的区别测试:
/**
* 在<many-to-one>上的fetch和lazy
*/
public class HibernateDemo5 {
@Test
/**
* 默认情况
*/
public void demo1() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
LinkMan linkMan = session.get(LinkMan.class, 1l);// 发送一条查询联系人的语句
System.out.println(linkMan.getLkm_name());
System.out.println(linkMan.getCustomer());// 发送一条select查询联系人所关联的客户的语句
transaction.commit();
} @Test
/**
* fetch = "select" lazy = "proxy",默认值
*/
public void demo2() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
LinkMan linkMan = session.get(LinkMan.class, 1l);// 发送一条查询联系人的语句
System.out.println(linkMan.getLkm_name());
System.out.println(linkMan.getCustomer());// 发送一条select查询联系人所关联的客户的语句
transaction.commit();
} @Test
/**
* fetch = "select" lazy = "false"
*/
public void demo3() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
LinkMan linkMan = session.get(LinkMan.class, 1l);// 不延迟,发送一条查询联系人的语句,发送一条select查询联系人所关联的客户的语句
System.out.println(linkMan.getLkm_name());
System.out.println(linkMan.getCustomer());
transaction.commit();
} @Test
/**
* fetch = "join" lazy = 失效
*/
public void demo4() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
LinkMan linkMan = session.get(LinkMan.class, 1l);// 发送一条迫切左外连接,两表全查
System.out.println(linkMan.getLkm_name());
System.out.println(linkMan.getCustomer());
transaction.commit();
} }
批量抓取:
批量抓取:一批关联对象一起抓取,batch-size,
/**
* Hibernate批量抓取
*/
public class HibernateDemo6 {
@Test
/**
* 获取客户的时候批量抓取联系人,在Customer.hbm.xml中设置set标签batch-size="4"
*/
public void demo1() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
List<Customer> list = session.createQuery("from Customer").list();
for (Customer customer : list) {
System.out.println(customer.getCust_name());
for (LinkMan linkMan : customer.getLinkMans()) {
System.out.println(linkMan.getLkm_name());
}
}
transaction.commit();
} @Test
/**
* 获取联系的时候批量抓取客户,在Customer.hbm.xml中设置class标签batch-size="4"
*/
public void demo2() {
Session session = HibernateUtils.getCurrentSession();
Transaction transaction = session.beginTransaction();
List<LinkMan> list = session.createQuery("from LinkMan").list();
for (LinkMan linkMan : list) {
System.out.println(linkMan.getLkm_name());
System.out.println(linkMan.getCustomer().getCust_name());
}
transaction.commit();
}
}
八 Hibernate延迟加载&抓取策略(优化)的更多相关文章
- Hibernate框架笔记04HQL_QBC查询详解_抓取策略优化机制
目录 1. Hibernate的查询方式 1.1 方式一:OID查询 1.2 方式二:对象导航查询 1.3 方式三:HQL方式 1.4 方式四:QBC查询 1.5 方式五:SQL查询 2. 环境搭建 ...
- Hibernate的抓取策略(优化)
延迟加载的概述 什么是延迟加载 延迟加载:lazy(懒加载).执行到该行代码的时候,不会发送语句去进行查询,在真正使用这个对象的属性的时候才会发送SQL语句进行查询. 延迟加载的分类 l 类级别的延 ...
- Hibernate之抓取策略
时间:2017-1-23 19:08 --区分延迟和立即检索1.立即检索 当执行某行代码时,会马上发出SQL语句进行查询. 例如:get()2.延迟检索 当执行某行代码时,不会马上发 ...
- Hibernate的抓取策略
立即检索:当执行某行代码的时候,马上发出SQL语句进行查询(get())延迟检索:当执行某行代码的时候,不会马上发出SQL语句进行查询.当真正使用这个对象的时候才会发送SQL语句(load()) 类级 ...
- Hibernate学习第4天--HQL——QBC查询详解,抓取策略优化。
上次课回顾: l Hibernate的一对多 n 表与表之间关系 u 一对多关系 u 多对多关系 u 一对一关系 n Hibernate的一对多配置 u 搭建Hibernate基本环境 ...
- 【Hibernate】抓取策略
一.区分延迟和立即检索 二.类级别检索和关联级别检索 一.区分延迟和立即检索 立即检索: 当执行某行代码的时候,马上发出SQL语句进行查询. get() 延迟检索: 当执行某行代码的时候,不会马上发出 ...
- 【Hibernate 8】Hibernate的调优方法:抓取策略
在上一篇博客中,介绍了Hibernate的缓存机制.合理的配置缓存,可以极大程度上优化Hibernate的性能.这篇博客,介绍另外一个调优方式:抓取策略. 一.什么是抓取策略 抓取策略(fetchin ...
- Hibernate(十四)抓取策略
抓取策略: 抓取策略是当应用程序需要在(Hibernate实体对象图的)关联关系间进行导航的时候,Hibernate如何获取关联对象的策略.Hibernate的抓取策略是Hibernate提升性能的一 ...
- Hibernate 抓取策略
抓取策略: 为了改变SQL语句执行的方式 当应用程序需要在Hibernate实体对象的关联关系间进行导航的时候,Hibernate如何获取关联对象的策略 抓取策略可以在O/R映射的元数据中声明,也可以 ...
随机推荐
- Windows下MySQL5.7版本中修改编码为utf-8
我们新安装的MySQL数据库默认的字符是 latin1 ,所以每次新建数据库都要修改字符,非常麻烦.所以我们必须将它改成UTF8字符的. 修改方法如下: 一.修改MySQL的my.ini 首先在 \P ...
- 什么是函数,干嘛啊,怎么干。一个py程序员的视角.md
目录 前言 本质 math definition py definition class 是类,是对象的蓝本 回到函数 一个结论 self 是什么? 以上就是py世界里函数的定义 什么是函数,干嘛啊, ...
- 华水开学第一课&微信支付
由于疫情的延续,导致我们不能及时开学.只能在网上观看华水开学第一课,但是好像正常开学也没有这个哈哈(不记得了) 昨天没有玩到很晚,12点就睡下.大约半个小时睡着了.定了8点的闹钟.起来的时候那是真的困 ...
- 并发队列之ArrayBlockingQueue
上一篇我们说了并发队列中的LinkedBlockingQueue队列,这次我们看看ArrayBlockingQueue,看看名字,我们想象一下LinkedList和ArrayList的区别,我们可以知 ...
- Django--redis 保存session
pipenv install django-redis settings.py: # 作为 cache backend 使用配置 使用redis保存session CACHES = { "d ...
- 【转】CGI 和 FastCGI 协议的运行原理
介绍 深入CGI协议 CGI的运行原理 CGI协议的缺陷 深入FastCGI协议 FastCGI协议运行原理 为什么是 FastCGI 而非 CGI 协议 CGI 与 FastCGI 架构 再看 Fa ...
- Python 基础之函数初识与函数参数
一.函数初识 定义:满足某一个方法 满足某一个功能#(1)功能(包裹一部分代码 实现某一个功能 达成某一个目的)#(2)可以反复调用,提高代码的复用性,提高开发效率,便于维护管理#(3)函数的基本格式 ...
- 本周总结(19年暑假)—— Part1
日期:2019.7.14 博客期:107 星期日 这几周正在摸索着找寻与大型数据库相关的知识,重装了电脑,配置了虚拟机的环境,继续研究了几下修改器.
- 使用MyCat实现MySQL读写分离
说明 配置MyCat读写分类前需要先配置MySQL的主从复制,参考我上一篇的文章,已经做了比较详细地讲解了. 环境 centos7.MySQL5.7.mycat1.6 配置MyCat账号密码和数据库名 ...
- python正则表达式错误集
这篇博文主要记载一些个人的(python)正则表达式的常见错误以及误区,所以,不一定全面,不一定具有权威.但我会把每个例子列出来,争取用事实说话. 大括号中空格问题 In [15]: re.match ...