懒载入(Load On Demand)是一种独特而又强大的数据获取方法,它可以在用户滚动页面的时候自己主动获取很多其它的数据,而新得到的数据不会影响原有数据的显示,同一时候最大程度上降低server端的资源耗用。总结一句话:什么时候须要数据。什么时候载入。

一、懒载入

1.1 类的懒载入

由javassist产生的代理类与Classes类是继承关系。

session.load()方法产生的是代理对象,该代理类是持久化类的子类

/**
* 类的懒载入
*/
@Test
public void testClass_lazy(){
session = HibernateUtils.openSession();
transaction = session.beginTransaction();
Classes classes = (Classes) session.load(Classes.class, 1L);
//classes.setName("asdj");
System.out.println(classes.getName());//发出sql
transaction.commit();
session.close();
}

1.2 集合的懒载入

/**
* 集合的懒载入
*/
@Test
public void testCollect_lazy(){
session = HibernateUtils.openSession();
transaction = session.beginTransaction(); Classes classes = (Classes) session.get(Classes.class, 1L);
Set<Student> students = classes.getStudents();//不发出
for (Student student : students) {//迭代的时候发出sql
System.out.println(student.getName());
}
transaction.commit();
session.close();
}
/**
* 更进一步的懒载入,设置extra,对于查询行数,最大值,最小值等
*/
@Test
public void testlazy_extra(){
session = HibernateUtils.openSession();
transaction = session.beginTransaction(); Classes classes = (Classes) session.get(Classes.class, 1L);
Set<Student> students = classes.getStudents();
System.out.println(students.size());
transaction.commit();
session.close();
}

1.3 单端关联的懒载入(many2one的懒载入)

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

No-proxy 延迟载入 默认值

Proxy是加强版的延迟载入

由于是通过多的一方载入一的一方。所以对效率影响不大。所以普通情况下用默认值就可以。

依据多的一端载入一的一端,其实仅仅是多查了一条数据,对性能差点儿没有影响,比方依据学生来查班级

总结

懒载入是Hibernate提供的一种优化方式。

1、延迟载入在映射文件设置,而映射文件一旦确定,不能改动了。

2、延迟载入是通过控制sql语句的发出时间来提高效率的。

所以在开发中通常是不会去设置懒载入的配置。

二、抓取策略

抓取策略解决的是怎样载入Set集合中数据的问题

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

public class FetchTest {

	private Session session;
private Transaction transaction;
private SessionFactory sessionFactory; /**
* fetch : select情况:
* 先查找Classes的id,在依据id查Student
* n+1条数据
* n:classes表中的条数
* 1:classes表本身
*/
@Test
public void testQueryAllStudent(){
session = HibernateUtils.openSession();
List<Classes> classes = session.createQuery("from Classes").list();
for (Classes classes2 : classes) {
System.out.println(classes2.getName());
Set<Student> students = classes2.getStudents();
for (Student student : students) {
System.out.println(student.getName());
}
}
session.close(); }
/**
* fetch : subselect情况:
* 由于该需求含有子查询,所以fetch 使用 subselect
* 2条sql
*/
@Test
public void testQueryAllStudent2(){
session = HibernateUtils.openSession();
List<Classes> classes = session.createQuery("from Classes").list();
for (Classes classes2 : classes) {
System.out.println(classes2.getName());
Set<Student> students = classes2.getStudents();
for (Student student : students) {
System.out.println(student.getName());
}
}
session.close(); }
/**
* select
* 先查询一的一方的所有的对象(Classes)。再依据每个对象的id值查询其关联对象(Student)
*/
@Test
public void testQueryClassesByCidAndStudents_Select(){
Session session = HibernateUtils.openSession();
Classes classes = (Classes)session.get(Classes.class, 1L);
System.out.println(classes.getName());
Set<Student> students = classes.getStudents();
for (Student student : students) {
System.out.println(student.getName());
}
session.close();
} /**
* join 利用左外连接一条SQL语句把classes和student表所有查询出来了
*
* 在含有子查询的需求分析中。利用join的抓取策略是不取的
* 1条sql
*/
@Test
public void testQueryClassesByCidAndStudents_Join(){
Session session = HibernateUtils.openSession();
Classes classes = (Classes)session.get(Classes.class, 1L);//发出sql,故fetch为join的抓取,会导致懒载入的失效
System.out.println(classes.getName());
Set<Student> students = classes.getStudents(); for (Student student : students) {
System.out.println(student.getName());
}
session.close();
}
}

总结:

由于抓取策略的设置在映射文件里,所以一旦映射文件生成就不能改变了。

通过发出SQL语句的不同的形式载入集合,从而优化效率的。

fetch为join的抓取策略会导致懒载入的失效

在设为join时,他会直接将从表信息以join方式查询到而不是再次使用select查询。这样导致了懒载入的失效。

抓取策略和延迟载入的结合

Set集合

1、 当fetch为join时,lazy失效

2、 当fetch为select时

假设lazy为true/extra

当遍历集合的时候,发出载入集合的sql语句

假设lazy为false

当获取班级的时候,发出载入集合的sql语句

3、 当fetch为subselect时和上面的情况一致。

最新文章

  1. Ubuntu下三个实用的录屏软件
  2. OData – the best way to REST–实例讲解ASP.NET WebAPI OData (V4) Service &amp; Client
  3. [MAC] mac系统如何截图
  4. HTML5 javascript修改canvas的大小
  5. 南阳理工ACM1076--方案数量
  6. VIM树状文件列表NERDTree
  7. 静态文件服务器(The static file servers)
  8. WebService地址变成计算机名的解决办法
  9. WallsEveryDay 必应桌面壁纸
  10. SeekBar 样式设置
  11. Python学习笔记——基础篇【第四周】——迭代器&amp;生成器、装饰器、递归、算法、正则表达式
  12. 响应式布局 —— Demo
  13. Dynamics CRM 系统自定义部分的语言翻译
  14. Oracle如何扩展表空间
  15. 关于python的315道题
  16. 生成Area URL链接
  17. .net mvc数据库操作添加数据的几中方法
  18. 百度地图api公交路线,IE下跳转百度地图后中文变成乱码的解决办法
  19. SANS社区帐号邮件激活问题
  20. Spring MVC @PathVariable被截断

热门文章

  1. RabbitMQ~消息的产生和管理(15672)
  2. Git的使用及托管代码到GitHub
  3. 【PostgreSQL-9.6.3】触发器概述(普通触发器)
  4. [Windows Server 2003] 安装网站伪静态
  5. css特殊效果
  6. java中“53”个关键字(含2个保留字)
  7. C# 金钱添加逗号0000
  8. PHP 之CURL请求封装GET、POST、PUT、DELETE
  9. centos 设置 ip地址
  10. 跳转语句(break、continue)