SessionFactory、HibernateTemplate、HibernateDaoSupport之間的關係說明

SessionFactory

       在接觸HibernateTemplate之前,我們知道,在對數據庫進行CRUD操作之前,需要開啓session、transaction等等。在hibernate學習過程中,我們知道了,得到session之前,需要先得到SessionFactory,進而從SessionFactory裏面openSession(),或者getCurrentSession(),接着開啓一transaction,然後進行對數據庫的操作,在操作結束後,提交事務,關閉session。當然如果session是通過getCurrentSession()得到的話,不用我們手動關閉。還有,關於異常的處理,這就涉及到事務的回滾。我們發現,這樣邏輯的代碼我們需要反覆使用,每次session的歷程都是這樣的。實例代碼如下:

[java] view plaincopy
  1. public class HibernateCoreAPITest {  
  2.     private static SessionFactory sessionFactory;  
  3.       
  4.     @BeforeClass  
  5.     public static void beforeClass() {  
  6.     sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();  
  7.     }  
  8.     @AfterClass  
  9.     public static void afterClass() {  
  10.         sessionFactory.close();  
  11.     }  
  12.         @Test  
  13.     public void testTeacherSave() {  
  14.         Teacher t = new Teacher();  
  15.           
  16.         t.setName("t1");  
  17.         t.setTitle("middle");  
  18.         t.setBirthDate(new Date());  
  19.           
  20.         //Session session = sessionFactory.openSession();  
  21.         Session session = sessionFactory.getCurrentSession();  
  22.         session.beginTransaction();  
  23.           
  24.         session.save(t);  
  25.               
  26.         session.getTransaction().commit();  
  27.     }  

 

HibernateTemplate

        從上面測試用的代碼(省略了異常處理和事務回滾)來看,如果在業務層某部分的功能模塊比較多,那我們不得不老實重複關於session的代碼。爲避免這樣的窘境,於是有了HibernateTemplate的出現。

       給HibernateTemplate注入SessionFactory,我們就能獲得利用SessionFactory來create sessionFactory,進而進行所有關於sessionFactory的功能操作。同時,由於HibernateTemplate本身關於sessionFactory的處理原理,我們不再需要手動編寫關於sessionFactory、session、transaction等等代碼。我們只需要編寫關於業務邏輯相關的操作,其他的一併由HibernateTemplate完成。HibernateTemplate的這種設計模式我們稱之爲TemplateMethod,採用的方式叫callback或者鉤子函數。這裏的重點就是把SessionFactory注入到HibernateTemplate裏面!!!

[java] view plaincopy
  1. <span style="font-size:18px;">@Component("employeeDao")  
  2. public class EmployeeDaoImpl implements EmployeeDao {  
  3.     private HibernateTemplate hibernateTemplate;  
  4.       
  5.     public HibernateTemplate getHibernateTemplate() {  
  6.         return hibernateTemplate;  
  7.     }  
  8.     @Resource  
  9.     public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {  
  10.         this.hibernateTemplate = hibernateTemplate;  
  11.     }  
  12.     @Override  
  13.     public void save(Employee employee) {  
  14.         hibernateTemplate().save(employee);  
  15.     }</span>  

        上面的代碼採用的是annotation方式,當然我們也可以使用xml方式,一樣很簡單。


HibernateDaoSupport

         HibernateDaoSupport對於HibernateTemplate,就好比HibernateTemplate對於SessionFactory,兩兩的關係,大致雷同。只是這一次,HibernateDaoSupport是需要被繼承的,而且不能像後者那樣減少什麼的代碼量。就是把HibernateTemplate注入到HibernateDaoSupport裏面,當然把SessionFactory注入到HibernateDaoTemplate裏面一樣可以。而起由於在HibernateDaoSupport裏面set方法是final類型的,我們不能夠重寫該方法,所以就不能過通過annotation方式注入HibernateTemplate,只有採用xml方式。

[java] view plaincopy
  1. <span style="font-size:18px;"><bean id="employeeDao" class="com.zzw.dao.impl.EmployeeDaoImpl">  
  2.         <property name="hibernateTemplate" ref="hibernateTemplate"></property>  
  3.     </bean></span>  
[java] view plaincopy
  1. <span style="font-size:18px;">public class EmployeeDaoImpl extends HibernateDaoSupport implements EmployeeDao {  
  2.     @Override  
  3.     public void save(Employee employee) {  
  4.         this.getHibernateTemplate().save(employee);  
  5.     }  
  6.   
  7.     @Override  
  8.     public void delete(Employee employee) {  
  9.         this.getHibernateTemplate().delete(employee);  
  10.     }  
  11.   
  12.     @Override  
  13.     public void update(Employee employee) {  
  14.         this.getHibernateTemplate().update(employee);  
  15.     }</span>  


       接着,我們來談談HibernateDaoSupport的拓展,當多個***Dao需要注入繼承HibernateDaoSupport的時候,理所當然,我們得在applicationContext.xml裏面給每個Dao注入hibernateTemplate或者sessionFactory。少量的好說,但是如果很多,比如幾百個Dao(當然,這種情況我們很少遇到,我們假設這樣),這樣,由於採用的是xml方式,我們配置起來一樣顯得麻煩。這個時候,我們可以這樣解決,抽象一個頂層Dao類,這個類必須注入HibernateTemplate,其實這個注入了HibernateTemplate的頂層Dao類,他的功能類似於HibernateDaoSupport類,唯一的不同就是這個類裏面的set方法是我們自己定義的,不是final類型的,所以我們採用註解annotation方式注入HibernateTemplate。然後,讓那些***Dao繼承這個頂層Dao類。這樣在xml裏面不用編寫任何的註解配置,當然除了在HibernateTemplate裏面注入sessionFactory。

注入HibernateTemplate的頂層Dao類:SuperDao.java

[java] view plaincopy
  1. <span style="font-size:18px;">import javax.annotation.Resource;  
  2.   
  3. import org.springframework.orm.hibernate3.HibernateTemplate;  
  4. import org.springframework.orm.hibernate3.support.HibernateDaoSupport;  
  5. import org.springframework.stereotype.Component;  
  6.   
  7. @Component  
  8. public class SuperDAO {  
  9.     private HibernateTemplate hibernateTemplate;  
  10.   
  11.     public HibernateTemplate getHibernateTemplate() {  
  12.         return hibernateTemplate;  
  13.     }  
  14.       
  15.     @Resource  
  16.     public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {  
  17.         this.hibernateTemplate = hibernateTemplate;  
  18.     }  
  19. }</span>  

        衆多***Dao裏面的一實例:UserDao.java

[java] view plaincopy
  1. <span style="font-size:18px;">@Component("userDAO")   
  2. public class UserDAOImpl extends SuperDAO implements UserDAO {  
  3.     public void save(User user) {  
  4.        this.getHibernateTemplate().save(user);  
  5.     }  
  6. }</span>  


       從上面的代碼中,我們發現整個過程我們並沒有使用HibernateDaoSupport這個抽象類,而是使用一個它的替代類:由我們自己定義的。如果非得使用HibernateDaoSupport類的話,也可以,就是講頂層Dao類SuperDao改爲:

[java] view plaincopy
  1. <span style="font-size:18px;">@Component  
  2. public class SuperDAO extends HibernateDaoSupport {  
  3.     @Resource(name="hibernateTemplate")  
  4.     public void setSuperHibernateTemplate(HibernateTemplate hibernateTemplate) {  
  5.         super.setHibernateTemplate(hibernateTemplate);  
  6.     }     
  7. }  
  8. </span>  

      注意:spring容器在對子類進行初始化的時候,首先會將其父類進行初始化,而如果兩者的注入方式不一致,比如一個是xml方式,一個是annotation方式的話,很容易出錯,所以,最好使用同種注入方式!

      最後,溫馨提示:建議使用HibernateTemplate的annotation注入方式,即第二種哦,親!

發佈了27 篇原創文章 · 獲贊 1 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章