this.getsession實際上是調用了父類HibernateDaoSupport中的方法獲得session。使用spring管理hibernate的SessionFactory的時候,這個方法會從session池中拿出一session。這樣做有可能有問題,儘管這種方式拿到的Session會自動關閉,但是他是有一定的失效策略的,而且在超session池連接數的時候,spring無法自動的關閉這些session。 不推薦使用
this.getHibernateTemplate().getSessionFactory().getCurrentSession()從spring管理的sessionFactory中創建一個綁定線程的session。Spring會根據該線程的執行情況來自動判斷是關閉session還是延遲關閉。這樣做可以避免手動的管理實務,同時一個線程最多開啓和關閉一次session又可以提高程序的性能。 極力推薦使用這種方法
this.getHibernateTemplate().getSessionFactory().OpenSession。這種方法從spring管理的sessionFactory中創建一個session,此session不是線程綁定的。當執行完一個實務的時候自動關閉session。這種方法不用手動管理實務,但是同一個線程多次的開啓和關閉session,浪費系統資源和影響執行效率,正常情況下還是不要用了。
這個是測試的dao層 log是在servi層構造好的然後傳入
- package com.test.spring.dao;
- import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
- import com.test.spring.model.Log;
- public class LogDaoMysqlImpl extends HibernateDaoSupport implements LogDao {
- public void addLog(Log log) {
- //this.getSession().save(log);
- //getHibernateTemplate().save(log);
- this.getHibernateTemplate().getSessionFactory().openSession().save(log);
- }
- }
執行結果如下,log4j產生的日誌被忽略
- org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(addUser)
- check security
- org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(addUser)
- check security
- org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(addLog)
- check security
- org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint: execution(addLog)
- check security
- Hibernate: insert into log (type, time) values (?, ?)
沒有進行session的關閉(不用spring也不用關閉session,session的關閉交給SessionFactory自動處理,但是使用spring的this.getSession沒有使用spring創建SessionFactory而是直接從spring的session緩衝池拿到session,spring的session緩衝池中一般默認生成10session,前面也說了,可能是其他線程使用完沒有關閉的,所以要顯示的調用close,釋放資源,因爲取出來就放不回去了。所以要手動關閉,而且他兩種獲取的方法使用了spring提供的SessionFactory,spring會自動的處理沒有必要進行手動關閉),就連事物的開啓與關閉也不用。
這就是使用Spring的好處,把切面上零散的代碼統一進行處理。
--------------------------------------------------------華麗的分割線--------------------------------------------------------------
1.getCurrentSession();
獲得當前會話中的session,該session有容器自行維護管理,Spring可以代理事務。
2.this.getSession();
從當前的執行中獲得或創建一個hibernate的session對象,自己關閉,釋放連接資源。
3.openSession();
調用函數自行創建一個數據庫的連接,並將其打開,在使用Spring操作非查詢語句的請況下,Spring的事務對該session對象不起到事務管理的作用,所以該session對象應當由程序員自己關閉,釋放連接資源。
在項目中使用到了Spring框架技術,就是說明,我們不想直接去獲取,打開Session,開始一個事務,處理異常,提交一個事務,最後關閉一個Session,使用Spring後,這樣的工作對我們來講太過於繁瑣,
我們自己只專注於業務,不想去作這些重複而繁瑣的操作。我們把這些責任全部委託給了Spring的HibernateTemplate,然後使用聲明式的配置來實現這樣的功能。
如果我們通過類似getSession()這樣的方法獲得了Session,那就意味着我們放棄了上面所說的一切好處。
在Spring的框架中HibernateTemplate提供了相當多有用的輔助功能。我們想用它提供的輔助功能。但是HibernateTemplate包裝了
Hibernate的代碼,使用了它以後不能直接訪問到Session了。
HibernateTemplate提供HibernateCallback,就是爲了滿足這種使用了HibernateTemplate的情況下,仍然需要直接訪問Session的需求而來的。它提供了在HibernateTemplate裏面直接訪問Session的能力,程序員不必人爲的管理session對象, 這個就是使用HibernateCallback的原因。