hibernate懒加载(lazy加载)
2016-04-24 22:26
330 查看
所谓懒加载(lazy)就是延时加载,延迟加载。当两个及以上表使用hibernate来管理级联关系时,一个表被加载到jvm内存时,其相关表可以暂存在数据库的缓存中,当需要使用相关表数据时在加载到jvm内存中,通过懒加载机制可以减少内存中不必要的开销,以提高程序的性能。
需要注意的是,当使用懒加载时,如果将session关闭,则断开了与数据库的连接,此时如果要访问子表数据,由于子表数据是存放在数据库的缓存中,而连接已经关闭,则访问子表数据会抛出LazyInitializationException异常。
解决方法:
1)不使用懒加载:将子表配置文件中lazy属性改为false,对某一个级联关系不使用懒加载
<many-to-one name="parent" class="ParrentClass"
column="parentId" lazy="false"></many-to-one>
注:对于many-to-many同样适用
或者将整个子表设置为对任何父表都不使用懒加载,则对整个子表都不使用懒加载
<class name="ChildClass" table="childTable"
lazy="false">
2)使用过滤器,把close Session这一步推迟到得到页面结果后执行。这里可以采用spring中OpenSessionInViewFilter(这是一个过滤器)来实现。
在web.xml中加入配置
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
3)手动将需要的子表数据从数据库缓存加载到jvm内存中。例如Classroom与Student实体类存在一对多关系(多对多同样适用),即
public Classroom {
private Set<Student> students;
.........
}
dao层有
List<ClassRoom> list = session获得结果集操作
for (Classroom classroom : list) {
Hibernate.initialize(classroom.getStudents()); //循环将classroom实体对应的Student集合patch到jvm内存中
}
session.close();
方法比较:第一种方法简单粗暴,优点是不必太在意延迟加载异常,因为不会发生,缺点是每次都将所有相关数据加载到jvm内存中,消耗内存资源;第二种方法是javaweb中常用的方法,优点是根据需要合理确定加载时间以及是否加载,缺点是只能用在J2EE中,对于J2SE项目则不适用;第三种方法,优点是灵活掌控何时加载,缺点是增加额外代码,并且需要加载子表数据但是忘记在session关闭前将其拉入jvm内存中时,会抛出LazyInitializationException
需要注意的是,当使用懒加载时,如果将session关闭,则断开了与数据库的连接,此时如果要访问子表数据,由于子表数据是存放在数据库的缓存中,而连接已经关闭,则访问子表数据会抛出LazyInitializationException异常。
解决方法:
1)不使用懒加载:将子表配置文件中lazy属性改为false,对某一个级联关系不使用懒加载
<many-to-one name="parent" class="ParrentClass"
column="parentId" lazy="false"></many-to-one>
注:对于many-to-many同样适用
或者将整个子表设置为对任何父表都不使用懒加载,则对整个子表都不使用懒加载
<class name="ChildClass" table="childTable"
lazy="false">
2)使用过滤器,把close Session这一步推迟到得到页面结果后执行。这里可以采用spring中OpenSessionInViewFilter(这是一个过滤器)来实现。
在web.xml中加入配置
<filter>
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
3)手动将需要的子表数据从数据库缓存加载到jvm内存中。例如Classroom与Student实体类存在一对多关系(多对多同样适用),即
public Classroom {
private Set<Student> students;
.........
}
dao层有
List<ClassRoom> list = session获得结果集操作
for (Classroom classroom : list) {
Hibernate.initialize(classroom.getStudents()); //循环将classroom实体对应的Student集合patch到jvm内存中
}
session.close();
方法比较:第一种方法简单粗暴,优点是不必太在意延迟加载异常,因为不会发生,缺点是每次都将所有相关数据加载到jvm内存中,消耗内存资源;第二种方法是javaweb中常用的方法,优点是根据需要合理确定加载时间以及是否加载,缺点是只能用在J2EE中,对于J2SE项目则不适用;第三种方法,优点是灵活掌控何时加载,缺点是增加额外代码,并且需要加载子表数据但是忘记在session关闭前将其拉入jvm内存中时,会抛出LazyInitializationException
相关文章推荐
- Android Studio--gradle,jCenter
- 堆排序
- 机器学习笔记(七)——决策树模型
- matplotlib 绘图库的简单用法
- Light OJ:1138 Trailing Zeroes (III)(二分)
- TCP/IP和http全称和概述
- 确定两串乱序同构
- 监听控件事件方法
- #include <NOIP2009 Junior> 细胞分裂 ——using namespace wxl;
- 冲刺04
- 第四天
- R学习-- R中的绘图命令练习
- java类加载机制
- 两个.aspx 页面传值 Request.QueryString["NAME"]
- Scala--基础入门
- 栈的压入、弹出序列
- 项目开发中遇到的一些问题纪录
- [改善Java代码]推荐覆写toString方法
- MySQL大数据优化
- mysql视图,存储过程,游标,触发器,事务简单了解