首页 > 代码库 > 【Hibernate】Hibernate中使用延迟加载应该注意的事项

【Hibernate】Hibernate中使用延迟加载应该注意的事项

1,简介

在使用一些查询方法时,方法执行了,但是并没有立刻发送SQL语句查询数据库。而是在访问对象的getXxx方法时候才触发SQL执行加载对象数据。这种机制就称为延迟加载。

2,优点

延迟加载主要是为后续关联映射提供,避免查找无用的关联数据。
可以降低数据库操作的并发率,提升内存资源使用率。

3,使用

在struts2中,session.load()和query.iterator()都使用的这种机制。

下面笔者使用session.load()方法举例:

技术分享

hibernate.cfg.xml 文件

技术分享
<?xml version=‘1.0‘ encoding=‘UTF-8‘?><!DOCTYPE hibernate-configuration PUBLIC          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><!-- Generated by MyEclipse Hibernate Tools.                   --><hibernate-configuration>    <session-factory>        <property name="dialect">            org.hibernate.dialect.MySQLDialect        </property>        <property name="connection.url">            jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf8        </property>        <property name="connection.username">root</property>        <property name="connection.password">517839</property>        <property name="connection.driver_class">            com.mysql.jdbc.Driver        </property>        <property name="show_sql">true</property>        <property name="format_sql">true</property>                <!-- 加载映射描述信息 -->        <mapping class="cn.test.bean.User" />            </session-factory></hibernate-configuration>
hibernate.cfg.xml

在里面指定了在控制台打印Sql执行日志

User.java 文件

技术分享
package cn.test.bean;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.Id;import javax.persistence.Table;@Entity@Table(name="user")//表示对应的表名public class User {    @Id    @Column(name="uid")    private int id;    @Column(name="uname")    private String name;    @Column(name="upass")    private String password;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }            }
User.java

接下来是测试文件:

如果我们使用如下的测试代码

Configuration conf = new Configuration();conf.configure("hibernate.cfg.xml");//读取连接参数和映射描述信息SessionFactory factory = conf.buildSessionFactory();Session session = factory.openSession();User user = (User)session.get(User.class,1);System.out.println("我在语句发送之后");            
System.out.println(user.getId()+","+user.getName()+","+user.getPassword());
session.close();

可以看到控制台上打印出了信息

技术分享

如果把上面的get方法换成 User user = (User)session.load(User.class,1); 

技术分享

通过这两次结果的对比可以看出,load方法使用延迟加载。使用load方法获取数据的方式,当程序加载到load方法时,程序并不会真正从数据库中查询语句,只有当查询的结果对象使用getXxx()方法的时候,才会在数据库中查询。

4,org.hibernate.LazyInitialization:could not initialize proxy -  no Session

如果使用了延迟加载,并且出现这样的错误,就是很有可能是session关早了。在session关闭后,再调用结果对象的getXxx(),这样从数据库中查询数据就会出错。在MVC开发出,如果想要使用延迟加载(使用session.load()方法或是query.iterator()方法)从数据库中取出数据到页面展现(在页面调用对象的getXxx方法),那么在数据层得到数据对象后,不要关闭session,因为关闭session后,再在页面调用getXxx()方法就会抛出异常。

要解决这种方法,要么不使用延迟加载,要么就在页面调用了getXxx()方法后,再关闭session。

如果我们把上面

 

【Hibernate】Hibernate中使用延迟加载应该注意的事项