Hibernate延迟加载和即时加载
来源:互联网 发布:php授权验证系统2.6.8 编辑:程序博客网 时间:2024/05/21 17:36
1、基本概念
即时加载,就是立即去数据库查找,延迟加载,查询是不会立即访问数据库,而是返回代理对象,只有真正需要使用对象的时候才会访问数据库
一般来说,延迟加载要比即时加载节省资源,但是如果处理不当,延迟加载容易抛出异常。
举例:
在一个一对多例子中,班级和学生,班级类里面有学生类的引用并且班级的.hbm.xml中的lazy设置了true,
public class Grade implements Serializable { private int gid; private String gname; private String gdesc; //在一方定义一个多方的集合 private Set<Student> students=new HashSet<Student>(); public int getGid() { return gid; } public void setGid(int gid) { this.gid = gid; } public String getGname() { return gname; } public void setGname(String gname) { this.gname = gname; } public String getGdesc() { return gdesc; } public void setGdesc(String gdesc) { this.gdesc = gdesc; } public Set<Student> getStudents() { return students; } public void setStudents(Set<Student> students) { this.students = students; } public Grade(String gname, String gdesc) { super(); this.gname = gname; this.gdesc = gdesc; } public Grade() { // TODO Auto-generated constructor stub }
Teacher.hbm.xml
<set name="students" table="student" cascade="save-update" inverse="false" lazy="true"> <key column="gid"></key> <one-to-many class="entity.Student"/> </set>
测试
Session session=HibernateSessionFactoryUtil.getSession();Transaction tx=session.beginTransaction();Grade g=(Grade)session.get(Grade.class, 1);tx.commit();HibernateSessionFactoryUtil.closeSession(session);
控制台输出:
Hibernate: select grade0_.gid as gid0_0_, grade0_.gname as gname0_0_, grade0_.gdesc as gdesc0_0_ from grade grade0_ where grade0_.gid=?
只是打印了select班级的语句
当我们的测试添加 一句输出学生的姓名时
控制台输出(为了便于观察,我认为在第一个和第二个select语句中加了空行):
Hibernate: select grade0_.gid as gid0_0_, grade0_.gname as gname0_0_, grade0_.gdesc as gdesc0_0_ from grade grade0_ where grade0_.gid=?Hibernate: select students0_.gid as gid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.sex as sex1_0_, students0_.gid as gid1_0_ from student students0_ where students0_.gid=?李四张三
张三李四是班级号为1的学生,只有在要使用grade对象的时候才会执行查询student的语句
如果此时还是没有看出异样,我们把Grade.hbm.xml的lazy设为false试一次
<set name="students" table="student" cascade="save-update" inverse="false" lazy="false"> <key column="gid"></key> <one-to-many class="entity.Student"/></set>
测试:
session=HibernateSessionFactoryUtil.getSession();Transaction tx=session.beginTransaction();Grade g=(Grade)session.get(Grade.class, 1);tx.commit();HibernateSessionFactoryUtil.closeSession(session);
控制台输出(为了便于观察,我认为在第一个和第二个select语句中加了空行):
Hibernate: select grade0_.gid as gid0_0_, grade0_.gname as gname0_0_, grade0_.gdesc as gdesc0_0_ from grade grade0_ where grade0_.gid=?Hibernate: select students0_.gid as gid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.sex as sex1_0_, students0_.gid as gid1_0_ from student students0_ where students0_.gid=?
发现了吧,在lazy=false时,也就是即时加载,就算不用Grade,他也会查找自己的外键(因为我们在set标签里设了lazy属性,所以加载外键,不懂的可以看我另一篇博客hibernate映射)
2、出现的情景
(1)在.hbm.xml中可以设置加载方式,class标签中可以设置
(2)在set/bag标签下也可以设置
(3)映射(many-to-one、many-to-many、one-to-many)
(4)get支持即时加载,load支持懒加载
详细解释下get和load(来自:http://www.cnblogs.com/fingerboy/p/5256087.html)
一、
get和load方法都是根据id去获得对应数据的,但是获得机制不同:如果使用get方法,hibernate会去确认该id对应的数据是否存在,它首先会去session中去查询(session缓存其实就hibernate的一级缓存),如果没有,再去二级缓存中去查询,如果再没有,就去数据库中查询,仍然没有找到的话,就返回null
而使用load方法的话,hibernate会认定该id对应的数据一定存在,它也会先去session缓存中去查找,如果没有找到,hibernate会根据lazy属性值来确定是否使用延迟加载。如果lazy=‘true’ ,就使用延迟加载,返回该代理对象,等到真正访问到该对象的属性时才会去二级缓存中查询,如果没有,再去数据库中查询,如果还没有,就抛出org.hibernate.ObjectNotFoundException异常。如果lazy=’false’ 则不使用延迟加载,这是load的访问机制就和get一样了。
二、
对于load和get方法返回类型:虽然好多书中都这么说:“get()永远只返回实体类”,但实际上这是不正确的,get方法如果在 session缓存中找到了该id对应的对象,如果刚好该对象前面是被代理过的,如被load方法使用过,或者被其他关联对象延迟加载过,那么返回的还是 原先的代理对象,而不是实体类对象,如果该代理对象还没有加载实体数据(就是id以外的其他属性数据),那么它会查询二级缓存或者数据库来加载数据,但是 返回的还是代理对象,只不过已经加载了实体数据。
- Hibernate延迟加载和即时加载
- hibernate 立即加载和延迟加载
- Hibernate框架-----属性延迟加载和关系延迟加载(七)
- Hibernate中的即时加载
- Entity Framework:即时加载与延迟加载
- 多线程下单例模式:懒加载(延迟加载)和即时加载
- 多线程下单例模式:懒加载(延迟加载)和即时加载
- hibernate 之《lazy》延迟加载和inverse
- hibernate延迟加载机制和二级缓存
- Hibernate学习3 二级缓存和延迟加载
- 谈谈hibernate的延迟加载和openSessionInView
- hibernate 延迟加载 load和get方法
- hibernate延迟加载和session关闭问题
- Hibernate中的延迟加载
- Hibernate延迟加载机制
- Hibernate延迟加载机制
- 再论hibernate延迟加载
- HIBERNATE延迟加载原理
- react native与Android混合开发
- linux(ubuntu15)安装angle opengles开发工具
- 科锐课堂笔记:2017/3/23 共用体与枚举类型
- es及插件安装
- c# 打开外部可执行文件exe。
- Hibernate延迟加载和即时加载
- 工具栏和菜单
- mongodb及可视化工具安装使用
- react native与Android开发调试
- L1-027. 出租
- C#中打开摄像头(Halcon)
- 802.1x技术介绍
- Android studio报错:app:mergeDebugResources FAILED(记一次痛苦不堪的debug)
- Java之this关键字区分局部变量和成员变量