1. 程式人生 > >Java程式設計師從笨鳥到菜鳥之(八十一)細談Spring(十)深入原始碼分析Spring之HibernateTemplate

Java程式設計師從笨鳥到菜鳥之(八十一)細談Spring(十)深入原始碼分析Spring之HibernateTemplate

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               


spring提供訪問資料庫的有三種方式:

 

HibernateDaoSupport

HibernateTemplate(推薦使用)

jdbcTemplate(我們一般不用)


類所在包:

HibernateTemplateorg.springframework.orm.hibernate3.HibernateTemplate

HibernateDaoSupportorg.springframework.orm.hibernate3.support.HibernateDaoSupport


       spring如果想整合hibernate的話,首先就應該獲得SessionFactory這個類,然後再通過獲得session就可以進行訪問資料庫了即spring提供的類HibernateDaoSupport,HibernateTemplate應該是有setSessionFactory,在使用的時候注入一下就可以了

HibernateTemplate類中的方法是spring封裝了hibernate中的方法,在使用完了以後會自動釋放session。而如果使用了HibernateDaoSupport的getSession方法,就需要配套的用releaseSession(Session session)或者session.close來關閉session,無法實現自動管理session。所以很多人都傾向於用spring的 Hibernatetemplate類或者HibernateDaoSupport的getHibernateTemplate方法來實現實現資料庫的互動,當然,如果遇到hibernatetemplate無法實現的功能,可以使用
 HibernateDaoSupport


首先我們先來看一下HibernateTemplate類:

首先我們來說一下我們為什麼要用HibernateTemplate,其實這個類就是我們平常使用hibernate進行dao操作的一個模版,我們不需要那些開頭的開啟事務、獲得session,結尾的提交事務,關閉session等操作了,這些工作是HibernateTemplate都給我們封裝好了,我們直接呼叫其dao的操作方法就可以了,並且他還給我們封裝了hibernate的幾乎所有的異常,這樣我們在處理異常的時候就不要記住那麼多繁瑣的異常了。所以我們就叫他是一個hibernate中dao操作的模版他提供的常用方法


get 從資料庫相關表中獲取一條記錄並封裝返回一個物件(Object) 
load 作用與get基本相同,不過只有在對該物件的資料實際呼叫時,才會去查詢資料庫 
save 新增記錄 
saveOrUpdate 判斷相應記錄是否已存在,據此進行新增或修改記錄
update 修改記錄 
delete 刪除記錄  


下面我們來看一下HibernateTemplate的原始碼來看一下他的具體方法是怎麼樣實現的,其實你觀察原始碼可以發現,他所提供的方法幾乎都是一個實現實現的。下面我們就以save方法來具體看一下:


public Serializable save(final Object entity) throws DataAccessException {return (Serializable) executeWithNativeSession(new HibernateCallback() {public Object doInHibernate(Session session) throws HibernateException {checkWriteOperationAllowed(session);return session.save(entity);}});}


       我們從原始碼中可以發現,HibernateTemplate把我們hibernate的異常都封裝成了一個DataAccessException 。好了,解釋一下上面的程式碼,上面程式碼中主要是呼叫了executeWithNativeSession這個方法,其實這個方法就是給我們封裝好的hibernate開頭和結尾一些列操作,他需要一個引數,這個引數是一個回撥的物件,其實這個物件是實現了一個HibernateCallback的介面,實現這個介面需要實現這個接口裡面的方法doInHibernate,這個方法需要把當前的session傳遞過來,其實他就是把他原先模版裡獲得的session傳過去。然後在在doInHibernate中利用模版中得到的session進行儲存資料。其實我們呼叫save的過程就是給他傳一個回撥物件的過程,我們可以看到,他的回撥物件是new出來的。


     如果你還沒看懂的話,那大家來看一下下面我們實現自己的HibernateTemplate,他的思路和spring提供的基本是一樣的:其中MyHibernateCallback 是一個簡單介面:

import org.hibernate.Session;public class MyHibernateTemplate {public void executeWithNativeSession(MyHibernateCallback callback) {Session s = null;try {s = getSession();s.beginTransaction();callback.doInHibernate(s);s.getTransaction().commit();} catch (Exception e) {s.getTransaction().rollback();} finally {//...}}private Session getSession() {// TODO Auto-generated method stubreturn null;}public void save(final Object o) {new MyHibernateTemplate().executeWithNativeSession(new MyHibernateCallback() {public void doInHibernate(Session s) {s.save(o);}});}}


    好了,原理我們介紹完了之後,下面我們來看一下具體應用,這個HibernateTemplate在我們的程式中怎麼用,在上面我們也說過了,這個用法主要是把sessionfactory注入給我們的HibernateTemplate

首先我們來看一下beans.xml的配置:


<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd           http://www.springframework.org/schema/context           http://www.springframework.org/schema/context/spring-context-2.5.xsd           http://www.springframework.org/schema/aop           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd           http://www.springframework.org/schema/tx            http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"><bean id="dataSource"class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"><property name="driverClassName" value="com.mysql.jdbc.Driver" /><property name="url" value="jdbc:mysql://localhost:3306/spring" /><property name="username" value="root" /><property name="password" value="bjsxt" /></bean><bean id="sessionFactory"class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"><property name="dataSource" ref="dataSource" /><property name="annotatedClasses"><list><value>com.bjsxt.model.User</value><value>com.bjsxt.model.Log</value></list></property><property name="hibernateProperties"><props><prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop><prop key="hibernate.show_sql">true</prop></props></property></bean><bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"><property name="sessionFactory" ref="sessionFactory"></property></bean><bean id="UserDao" class="com.bzu.dao.userDao"><property name="hibernateTemplate" ref="hibernateTemplate"></property></bean></beans>


下一步我們來看一下hibernateTemplate的使用:

public class UserDAOImpl implements UserDAO {private HibernateTemplate hibernateTemplate;public HibernateTemplate getHibernateTemplate() {return hibernateTemplate;}public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {this.hibernateTemplate = hibernateTemplate;}public void save(User user) {hibernateTemplate.save(user);}}


這基本上就是我們的hibernateTemplate原理及使用了,其實他的使用很簡單


下面,我們來看一下HibernateDaoSupport

通過上面我們可以看出,通過xml注入hibernateTemplate,我們可以想象的到所有DAO類中都會有HibernateTemplate的bean方法,於是上面hibernateTemplate的set、get的方法和xml配置會有大量的,於是就出現了程式碼冗餘和重複,我們怎麼才能避免這個重複呢,我們很容易應該能想到,把上面注入hibernateTemplate抽出一個類,然後讓我們的dao類來繼承這個類。不過這個類Spring已經有了,那就是HibernateDaoSupport,除此之外,HibernateDaoSupport也有SessionFactory的bean方法,所以我們在用HibernateDaoSupport的時候同樣也要給我們注入sessionfactory或者hibernateTemplate,在用的時候你會發現HibernateDaoSupport也給我們提供了getHibernateDaoSupport方法。

相關配置示例:userdao繼承了HibernateDaoSupport


<bean id="userdao" class="com.bzu.dao.uerdao"><property name="sessionFactory" ref="sessionFactory"></property></bean>


     用上面的方法我們可以發現一個問題,我們同樣解決不了xml配置重複的問題,我們每一個dao都要在xml注入sessionfactory或者hibernateTemplate,解決這個問題的辦法就是我們自己在抽出一個SuperDao類,讓這個類去繼承HibernateDaoSupport,然後我們給SuperDao類去配置,這樣的話,我們在我的dao類中直接去繼承SuperDao類就可以了,這樣不管有多少dao類,只要繼承SuperDao,我們就可以實現我們想要的功能了。

           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述