您的位置:首页 > 其它

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

    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: