spring的HibernateDaoSupport以及HibernateTemplate和jdbcTemplate的選擇問題
spring提供訪問資料庫的有三種方式:
HibernateTemplate:org.springframework.orm.hibernate3.HibernateTemplate (推薦使用)
HibernateDaoSupport:org.springframework.orm.hibernate3.support.HibernateDaoSupport
jdbcTemplate
spring如果想整合hibernate的話,首先就應該獲得SessionFactory這個類,然後再通過獲得session就可以進行訪問資料庫了
即spring提供的類HibernateDaoSupport,HibernateTemplate應該是有setSessionFactory,在使用的時候注入一下就可以了
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="annotatedClasses">
<list>
<value>com.zcy.model.User</value>
<value>com.zcy.model.Log</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.OracleDialect
</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">
true
</prop>
</props>
</property>
</bean>
對於HibernateTemplate:
先我們來說一下我們為什麼要用HibernateTemplate,其實這個類就是我們平常使用hibernate進行dao操作的一個模版,我們不需要那些開頭的開啟事務、獲得session,結尾的提交事務,關閉session等操作了,這些工作是HibernateTemplate都給我們封裝好了,我們直接呼叫其dao的操作方法就可以了,並且他還給我們封裝了hibernate的幾乎所有的異常,這樣我們在處理異常的時候就不要記住那麼多繁瑣的異常了。所以我們就叫他是一個hibernate中dao操作的模版。
xml配置:
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
在程式中直接用就可以了,如下
HibernateTemplate實現原理:@Component("u")
public class UserDaoImpl_HibernateTemplate implements UserDao {
private HibernateTemplate hibernateTemplate;
@Resource
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}public void save(User user) {
hibernateTemplate.save(user);
}}
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出來的。
對於HibernateDaoSupport:
public final void setSessionFactory(SessionFactory sessionFactory)
public final SessionFactory getSessionFactory()
public final void setHibernateTemplate(HibernateTemplate hibernateTemplate)
public final HibernateTemplate getHibernateTemplate()
從它類裡的方法可以知道,在使用的時候只需要將sessionFactory注入給HibernateDaoSupport,然後就可以通過getHibernateTemplate
來獲得HibernateTemplate,這樣就可以使用HibernateTemplate了,就和上面使用HibernateTemplate的一樣的
(顯然這有點繞了一點彎,個人感覺還是直接使用HibernateTemplate就可以了,不過根據個人喜好或專案的需求而定)
下面是實現設計的方法:
service:
public class UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void add(User user){
userDao.save(user);
}
dao:
public class UserDaoImpl extends HibernateDaoSupport implements UserDao {
public void save(User user) {
this.getHibernateTemplate().save(user);
}}
bean.xml:
<bean id="userService" class="com.zcy.service.UserService">
<property name="userDao" ref="userDao"></property>
</bean>
<bean id="userDao" class="com.zcy.dao.impl.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
這裡的sessionFacotry注入不是給類UserDaoImpl 的,而是給繼承HibernateDaoSupport類的sessionFactory,使用HibernateDaoSupport好處就是我們不再需要關心關閉、是否連線成功等問題(在使用spring封裝的這些類,即HibernateDaoSupport,HibernateTemplate,jdbcTemplate,都不需要關心是否關閉,是否連線的問題,因為spring已這些操作封裝給注入好了),
這樣用起來很方便。但是這個不好就是java只支援單繼承,所以唯一的繼承給了HibernateDaoSupport有點可惜。
另外注意的是因為HibernateDaoSupport已經有setSessionFactory(SessionFactory sessionFactory)這個方法了,所以在UserDaoImpl 的類裡就不需要寫了,
並且HibernateDaoSupport的setSessionFactory的方法時final的,所以重寫還會報錯的。
用上面的方法我們可以發現一個問題,我們同樣解決不了xml配置重複的問題,我們每一個dao都要在xml注入sessionfactory或者hibernateTemplate,解決這個問題的辦法就是我們自己在抽出一個SuperDao類,讓這個類去繼承HibernateDaoSupport,然後我們給SuperDao類去配置,這樣的話,我們在我的dao類中直接去繼承SuperDao類就可以了,這樣不管有多少dao類,只要繼承SuperDao,我們就可以實現我們想要的功能了。
對於jdbcTemplate:
這種方法適合那些不喜歡hibernate的save,delete等方法,喜歡自己寫的N人吧。有時候jdbcTemplate查詢的效率會很高。這可能是跟jdbc有關吧。
配置如下:
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
在類中set方法jdbctemplate方法就可以了,spring中的配置跟sessionFactory基本一樣。
總的感覺還是喜歡HibernateTemplate,原因就是好用,不需要寫太多的sql語句,不需要
類去繼承,只要提供一個set方法,再注入一下很方便。
相關推薦
spring的HibernateDaoSupport以及HibernateTemplate和jdbcTemplate的選擇問題
spring提供訪問資料庫的有三種方式: HibernateTemplate:org.springframework.orm.hibernate3.HibernateTemplate (推薦使用) HibernateDaoSupport:org.springframewor
關於hibernateTemplate和jdbcTemplate的是否共享事務的說明
1、hibernateTemplate 與 jdbcTemplate 事務為共享。 2、但hibernate中的HQL方法,比如save update等 ,若不呼叫flush(),則資料只存在於緩衝區
子選擇器、後代選擇器和通用選擇器以及偽選擇器
borde solid 顏色 clas lec 編輯 一段 html 一行 子選擇器(>) .food>li{border:1px solid red;}後代選擇器(空格) 包含選擇器,即加入空格,用於選擇指定標簽元素下的後輩元素。如右側代碼編輯器中的代碼: .
jquery獲取已選擇和未選擇的checkBox項以及清空所選項
獲取已選中的: var checkedArr = []; $("input[name='xxx']:checked").each(function() { checkedArr.push($(this).val()); }); 獲取未選中的: var notCheckedA
元素選擇器 和 #id 選擇器 以及 .class 選擇器三者的區別
jQuery 選擇器允許您對 HTML 元素組或單個元素進行操作,jQuery 選擇器基於元素的 id、類、型別、屬性、屬性值等”查詢”(或選擇)HTML 元素。 它基於已經存在的 CSS 選擇器,除此之外,它還有一些自定義的選擇器。jQuery 中所有選擇器都
ajax請求post和get的區別以及get post的選擇
最簡單的區別: 1.使用Get請求時,引數在URL中顯示,而使用Post方式,則不會顯示出來 2.使用Get請求傳送資料量小,Post請求傳送資料量大 3.get請求需注意快取問題,post請求不需擔心這個問題 Get方式: 用get方式可傳送簡單資料,但大小一
jdbcTemplate和HibernateTemplate和TransactionManager
【一個是一jdbc方式封裝的連線,一個是以hibernate方式封裝的,2者用法不同了,相當於一個是jdbc一個是hibernate!看你用什麼方式來處理資料了。 都是直接用就行了 不用顯示的開啟和關閉連線,由容器管理了。 】 【DataSourceTransaction
java小程式——給陣列隨機賦值,查詢輸入的值以及冒泡和選擇排序陣列並輸出
import java.util.Random; import java.util.Scanner; public class Test1{ public static void main(String[] args) { Scanner sc=new Scanner(Sy
Android傳送簡訊(簡訊傳送以及群發和從電話本選擇聯絡人)---簡訊管家2
分析下怎麼寫 首先,我們需要一個輸入框,可以手動的輸入手機號碼, 其次,很少有人願意手動輸入,那麼我們需要提供一個按鈕來給我們的使用者選擇自己電話本中的聯絡人(一次可以選擇多個即群發) 然後,我們需要一個簡訊編輯介面,可以編輯簡訊 最後兩個按鈕,一個傳送,點選後傳送訊息,一個
zookeeper安裝以及配置和註意事項
zk1,安裝 wget tar zxvf zookeeper-3.4.9.tar.gz cd zookeeper-3.4.9/conf cp zoo_sample.cfg zoo.cfg 修改zoo.cfg配置文件 如下tickTime=2000 initLimit=10 syncLi
if判斷和switch選擇
console 分享 說明 logs 知識 else if def put 技術分享 在C#中,if判斷語句相信是最基礎最普遍的一個語法了,在這裏簡單記錄一下if判斷語句和switch選擇之間的某些關聯。 if判斷語句的代碼格式: 其中的條件1和條件2,均為boll
bootstrap-表單控件——復選框checkbox和單選擇按鈕radio
bootstrap-表單控件——復選框checkbox和單選擇按鈕radio1.運行效果如圖所示2.實現代碼如下<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-
js ==和===以及!= 和 !==的區別
true style cnblogs 基礎類型 family var ber 16px 運算 一、js == 與 === 的區別[轉] 1. 對於string,number等基礎類型,==和===是有區別的 1)不同類型間比較,==之比較“轉化成同一類型後的值”看“
普通集合和泛型集合的區別,哈希表和字典表的區別,隊列和堆棧的區別以及堆和棧的區別。
ear 釋放內存 main 廣泛 棧內存 節點 except {0} 常數 普通集合和泛型集合的區別: 泛型集合與傳統集合相比 類型更安全. 泛型集合無需裝箱拆箱操作. 泛型的重要性. 泛型是未來五年的主流技術 ...通常情況下,建議您使用泛型集合,因為這樣可以獲得類型安全
對於if判斷和switch選擇的入門理解
ima 運行 用戶 流程控制語句 pan 如果 spa 用戶輸入 ase 今天是分享一下流程控制語句中對if判斷和switch選擇的初步了解,讓我們來看一下這兩者的代碼結構。 if 判斷:
simple_tag,filte,分頁以及cookie和裝飾器
關閉瀏覽器 param max request 內容 關於 block django spl 內置的方法 首先Django中包含了很多內置的方法: 這裏通過lower實現 在views視圖函數中寫如下代碼: def tp3(request): name= "ABC
Android零基礎入門第57節:日期選擇器DatePicker和時間選擇器TimePicker
oncreate ted show imageview bce min date 教程 運行程序 在實際開發中,經常會遇見一些時間選擇器、日期選擇器、數字選擇器等需求,那麽從本期開始來學習Android中常用選擇器,今天學習的是DatePicker和TimePicke
(八)數組以及排序和查找
binary char and log 最簡 排序。 我認 最好 數組 JavaSE(八) --數組以及排序和查找 一、數組的定義 三種定義方法: int b[]=new int[5]; Int []b=new int[5]; int[] a=new int[5]; (建議
模板方法模式和JDBCTemplate(一)
和我 進行 源碼 temp 很遺憾 ces boolean 對象 行為 本篇博客的目錄: 一:模板方法模式介紹 二:模板方法模式的簡單實現 三:總結 一:模板方法模式的介紹 1.1:模板方法模式的定義 定義:一個操作中的算法的骨架,而將一些步驟延遲到子類中。Template
移動端適配方案以及rem和px之間的轉換
場景 adding 區間 tin 每一個 left ios7 分辨率 user 背景 開發移動端H5頁面 面對不同分辨率的手機 面對不同屏幕尺寸的手機 視覺稿 在前端開發之前,視覺MM會給我們一個psd文件,稱之為視覺稿。 對於移動端開發而言,為了做到頁面高