1. 程式人生 > >解決Hibernate懶載入的4種方式

解決Hibernate懶載入的4種方式

本文總結了我在學習hibernate的過程中,解決hibernate懶載入問題的四種方式。

懶載入簡述:當我們查詢一個物件的時候,在預設情況下,返回的只是該物件的代理物件,當用戶去使用該物件的屬性時,才會向資料庫再一次發出查詢語句。

例如,有一個物件是Employee,還有一個物件是Department。顯然,對於Employee相對Department來說,是多對一的關係;而對於Department相對Employee來說,是一對多的關係。當我們查詢Employee物件的時候,如果希望通過employee物件的屬性department查詢到所對應的Department,那麼是會丟擲異常的。這是因為懶載入的存在,在session關閉之後,hibernate又向資料庫發出一次請求,結果就丟擲異常了。

下面總結的是解決這個問題的四種方式:

1.顯式初始化(在查詢方法內部)

要查詢某員工屬於哪個部門的時候,需要對Department進行預先查詢

使用語句

Hibernate.initialize(Department.class);

2.修改物件關係檔案,將lazy 改寫lazy = false,即關閉懶載入

以上兩種方法,確實可以解決問題,但是缺點是無論後面是否使用該物件,hibernate都會向資料庫發出SQL語句請求資料,造成不必要的效能浪費。

3.使用過濾器(web專案)

①獲取session的方式必須使用getCurrentSession

②特殊的關閉session方式

public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain arg2) throws IOException, ServletException {
		// TODO Auto-generated method stub
		Session session = null;
		Transaction tx = null;
		try {
			session = HibernateUtil.getCurrentSession();
			tx = session.beginTransaction();
			arg2.doFilter(request, response);//請求一直在走
			tx.commit();
		} catch (Exception e) {
			// TODO: handle exception
			if(tx != null){
				tx.rollback();
			}
		}finally{
			//特殊的關閉方式
			HibernateUtil.closeCurrentSession();
		}
	}

4.在SSH框架中,使用spring提供的openSessionView

其原理和第三種方法中使用Filter類似,只不過這個filter是spring提供的。使用時只需要在web.xml檔案配置如下:

<!-- 使用spring解決懶載入問題 -->
	<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>/*</url-pattern>
	</filter-mapping>

第3和第4中方法也能解決懶載入的問題,其中第4種方法也是目前使用較多的。但是這兩種方法也是有缺點的,缺點就是延長了session關閉的時間,session的生命週期變長。沒有使用該方法之前,session是在查詢完資料之後,就被關閉了;而現在,session的關閉是在一次web請求的最後才關閉。