1. 程式人生 > >【Hibernate】Hibernate中使用延遲加載應該註意的事項

【Hibernate】Hibernate中使用延遲加載應該註意的事項

取出 struts2 dial 表示 指定 cef init pen ima

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中使用延遲加載應該註意的事項