More Related Content
Similar to Spring 2.0 技術手冊第六章 - Hibernate 與 Spring
Similar to Spring 2.0 技術手冊第六章 - Hibernate 與 Spring(20)
Spring 2.0 技術手冊第六章 - Hibernate 與 Spring
- 1. 。能功等理管易交的式告宣
如,能功的 合結以可並,化簡為更以可上用使在,型模用使
Spring
的致一 循 依以可都,上用使與定設的
Spring 在您讓,裝 Hibernate
封了行進 為 ,
Hibernate 合整中
S pring在以可您
Hibernate Spring
。能功等理管易交、定鎖、取快的需所層久持有供提也並,射
映動自的型模聯關庫料資式聯關與型模件物 供提,案方決解 Java
的) (射映係關件物個是
O bject/Relation Mapping, ORM Hibernate
Hibernate 與 Spring
6
- 2. Spring 2.0 良信林(冊手術技 – http://openhome.cc )
6.1 Hibernate 入門
了速 快 在 的 目 , 的 排 安 所 者 讀 的 過觸 接 未 對 針 是 節 小 個 這
Hibernate
習練際實,中節 的來下接利以,式程Hibernate 個一第寫撰何如解 6.2 Spring
直以可,式方寫撰的
Hibernate 解了經已您果如,例範合整的 與
Hibernate
。節小個這過略接
6.1.1 簡介 Hibernate
個一過計設經曾,中案專
5 5.1.2的 中章 第在
DataSourceDemo User-
DAO :的計設麼這是您,中法方 在中其,別類
find()
...
public User find(Integer id) {
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = dataSource.getConnection();
stmt = conn.prepareStatement(
"SELECT * FROM user WHERE id=?");
stmt.setInt(1, id.intValue());
ResultSet result = stmt.executeQuery();
if(result.next()) {
Integer i = new Integer(result.getInt(1));
String name = result.getString(2);
Integer age = new Integer(result.getInt(3));
User user = new User();
user.setId(i);
user.setName(name);
user.setAge(age);
return user;
}
6 2
- 3. Chapter 6 Hibernate 與 Spring
} catch (SQLException e) {
e.printStackTrace();
}
finally {
if(stmt != null) {
try {
stmt.close();
}
catch(SQLException e) {
e.printStackTrace();
}
}
if(conn != null) {
try {
conn.close();
}
catch(SQLException e) {
e.printStackTrace();
}
}
}
return null;
}
...
用使接 直個是 這 JDBC :的討探得值是題議個幾有中當,式程的詢查行進
SQL 句語 的中式程
援支個是則 ,法語的面層庫料資是 ,句語 寫撰接直中式程
SQL S QL J ava
程在,面方一另,型模言語的同不種兩是們它,言語式程的型模向導件物
SQL 。題問的護維以難有直一 插穿中式
裝封的件物料資
為 裝 封 料 資 將 能 才,式 程 些 一 寫 撰 己 自 須 必,料 資 的 來 回 詢 查 庫 料 資 從 User
對 中 庫 料 資 至 存 儲 之 將 想 並,時 件 物 個 一 得 取 您 當,例 實 個 一 的 別 類
User
句語 至插安,員成料資的件物 出取個一個一要也,時格表的應
User SQL
6 3
- 4. 6 4
)h ttp://www.jboss.com/
( 被 後, 獎 大 JBoss Jolt 2004
得 獲 末 年 於 並, 表 發
Hibernate 2 8
日 月 年 ,表發本版個一第 6 2 003 未年 Hibernate 2001
。 案方的 換 轉 射 映 動 自 中 程 過 個 這 了 供 提 Hibernate
,係關的間之格表與格表的中庫料資式聯關至射映,係關件物與件物
Java
的 中 將 是 就,一 之 用 作 的 H ibernate
,說 的 單 簡。 為 寫 簡,案 方 ORM
決 解 的) O bject/Relational Mapping
(」 射 映 係 關 件 物 「是 / Hibernate
。 決 解 待 有 題 問 的 多更有 還 都 , 應 對 作 何 如
要中庫料資式聯關在們它,係關的等合集、聯關、承繼有還中 在如例 Java
,些這只不還,題問的發引所同不的型模聯關與型模件物於由上實事
User
。例實的件物 為裝封料資的到詢查將來式程寫撰己自須必也,時
料資到詢查中庫料資從,存儲的料資行進以中 至插安,員成料資的上 SQL
User User
件 物 得取 行 自 要 , 時 件 物 存 儲 在 , 到 看以可 仍 中 例 範 案 專 些 一
5
的 章 第在 如 例 , 份 部 的 決解未 有 也 是 但 , 題 議 些一的 到 提 所 面 上 決 解 以
可容內的紹介時當,化簡與裝封的 於 JDBC
了紹介中章 第在 Spring 5
。決解
行自要都題問些這,等閉關要不要、取快作要不要 到慮考會 Statement
許 也 您 及 以,池 接 連 回 放 Connection
將 否 是,話 的) ( C onnection pool
池 接連 置 設 有是 或 ,閉 關 否是 後 之 畢完 用使 到意注要須必您 Connection
理管的 、 S tatement Connection
。力心的費花所時寫撰式程了加增,輯邏理處外
例 try...catch
了滿充中式程個整,外例的時 關相 行執理處了為 API JDBC
理處的外例
。作動些這了行進就法方
的別類 insert() UserDAO
中案專 D ataSourceDemo ,作動存儲行執 的 用使再,中之 API JDBC
) – http://openhome.cc 良信林(冊手術技 Spring 2.0
- 5. Chapter 6 Hibernate 與 Spring
節小個這,表發式正 月 年 , 一之目 項 子 其 為 成 而 納 收
2 005 3 Hibernate 3
寫改來 用使何如看看, 用 使是即 介 簡 的 行 進 要 所 中
Hibernate 3 Hibernate
。能功的
5 解了步初以,別類 的過計設所中章 第
UserDAO Hibernate
6.1.2 下載、設定 Hibernate
,候時的書此寫撰 Hibernate ( 是本版的新最
3.2 GA General
至 接 連 請 ,)
Availabity Hibernate 在 是 址 網 ,載 下 的 案 檔 行 進 站 網 方 官 的
:
http://hibernate.org/
圖 6.1 Hibernate 址網方官
「的邊左選點 會中面頁載下,面頁載下至入進以可,結鏈」
D ownload
「個有Hibernate Core 至接連結鏈」
Download「的」 Sourceforge
6
- 6. 6 6
。 案 檔 依 相 的到用 會 能 可 是 則 的 中 錄 目 在 , 件 文 考 參 關 相 lib
API
或明說 到找中錄目 在以可,裝封之 的要需所 doc API 是 Hibernate 3
這, hibernate3.jar
有就下錄目的開解在,後之縮壓解並案檔 載下 zip
。間時的載下省節以,站網射鏡的域區在所載下近接最個一擇選以可,站網
m irror
) ( 鏡擇選要需會,後之結鏈載下的案檔擇選,
射 hibernate-3.2.0.ga.zip
載 下 以 可 您 , 案 檔 載 下的 式 格 縮 壓 同 不 種 幾 有 供 提 上 在 Sourceforge
案檔關相 Hibernate 載下 Sourceforge 從 6.2 圖
:) id=127784
http://sourceforge.net/project/showfiles.php?group_id=40712&package_ (
) – http://openhome.cc 良信林(冊手術技 Spring 2.0
- 7. Chapter 6 Hibernate 與 Spring
圖 6.3 hibernate-3.2 容內的
的您設假,境環的作操一統了為 在放是都案檔關相
Hibernate
C:workspacelibraryhibernate-3.2 。容內的 圖考參請, 6.3
個一第的寫撰將於對 Hibernate 了除案檔 的要需所,式程 .jar hibernate3.jar
:要需還您,外之
antlr-2.7.6.jar
asm.jar
cglib-2.1.3.jar
commons-collections-2.1.1.jar
commons-logging-1.0.4.jar
dom4j-1.6.1.jar
ehcache-1.2.jar
jta.jar
log4j-1.2.11.jar
6 7
- 8. Spring 2.0 良信林(冊手術技 – http://openhome.cc )
式程動驅的 有 要 須 必 也 以 所, 用 使 是 仍 層 底 在
Hibernate JDBC JDBC
將中
jar 在 ,容 內 的 中 章 第 考 參 以 可 您,案 檔 的
2 2.1.2 Eclipse Hibernate
.jar 。中之案專至定設 關相
6.1.3 第一個 Hibernate 程式
個這 在 , 式 方 用 使 與 能 功 的 下 一 範示 , 案 專 個 寫 撰 來 接 直
Hibernate
與 解了 以 , 它 寫 改 來 再 會 後 稍 , 能 功 的
Spring 用使 不 時 暫 中 範 示 Spring
Hibernate 。性便方的後之合整
料資 至應對將別類 個這,別類 個一計設先,的樣同
User User demo
:) user ( 的單簡個一是只它,格表 個一的中庫 POJO P lain Old Java Object
HibernateDemo User.java
package onlyfun.caterpillar;
public class User {
private Integer id;
private String name;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
6 8
- 9. Chapter 6 Hibernate 與 Spring
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
,別識的性一唯中式程於件物為作來用,性屬 個一有須必別類
User id
。值 鍵 主 的 中 格 表 庫 料資 至 應 對 常 通 , 生 產
id Hibernate 由以可值 個這
的用使邊這在 MySQL 的 下 以 用 使 是 時 立 建 格 表,庫 料 資 SQL :
CREATE TABLE user (
id INT(11) NOT NULL auto_increment PRIMARY KEY,
name VARCHAR(100) NOT NULL default '',
age INT
) TYPE = InnoDB;
件文射映個一靠是上際實,係關映對立建要間之格表 與別類
User user
設 如 例, 為 名 命 當 通, 寫 撰 來 用 使 以 可 件 文 射 映, 成 完 來
XML .hbm.xml
User.hbm.xml :件文射映 個一計
HibernateDemo User.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="onlyfun.caterpillar.User" table="user">
6
- 10. Spring 2.0 良信林(冊手術技 – http://openhome.cc )
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="name" column="name"/>
<property name="age" column="age"/>
</class>
</hibernate-mapping>
,映對的格表與別類義定來用籤標
< class> ,中件文射映在 " name" 屬
中籤標 ;稱名格表定設來用性屬"table" ,稱名別類定設來用性 <id> "name"
是就也,位欄鍵主的中表料資至應對常通,別識一唯的件物定設來用性屬
鍵主定設來用
"column" 的 ;位欄應對的定設所性屬
< generator> "class"
主 成生來 式 方 成 生 鍵 主 的 己 自 庫 料 資 依 示 表
"native" 為定設,式方生產的
加每 會 以 所 , user 為定設鍵主,時立建在格表 如例,值鍵 auto_increment
。 值 鍵 主 增遞動 自 都 時 料 資 筆 一 入
由(性屬個一每的件物 定設則籤標
<property> User 的來下接 "name"
屬 由(位欄個一哪的格表 中庫料資至應對別分,)定設性屬user "column"
。)定設性
,時庫料資取存在式程用應讓,面介 IUserDAO 個一計設,的樣同著接
: 示 所下如 , 作 實 別 類 的 際 實非而 面 介 的 象 抽 於 賴 依
HibernateDemo IUserDAO.java
package onlyfun.caterpillar;
public interface IUserDAO {
public void insert(User user);
public User find(Integer id);
}
6 1
- 11. Chapter 6 Hibernate 與 Spring
由後然 作實來別類
UserDAO IUserDAO 用使時作實次這,面介
的
Hibernate API 個一入注要需, :件物
org.hibernate.SessionFactory
HibernateDemo UserDAO.java
package onlyfun.caterpillar;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
public class UserDAO implements IUserDAO {
private SessionFactory sessionFactory;
public UserDAO() {
}
public UserDAO(SessionFactory sessionFactory) {
this.setSessionFactory(sessionFactory);
}
public void setSessionFactory(
SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public void insert(User user) {
// Session
得取
Session session = sessionFactory.openSession();
// 易交啟開
Transaction tx= session.beginTransaction();
// 件物存儲接直
session.save(user);
// 易交出送
tx.commit();
session.close();
}
public User find(Integer id) {
Session session = sessionFactory.openSession();
6 11
- 12. 6 12
, Session
了閉關經已 ,前束結法方 在 。 find() LazyInitializationException
出丟會則否,態狀的啟開在是須必 時此而,詢查 Session
行進位欄應對的格表料資向會不,前料資得取 的件 物作操在正真 是就 Getter
也,能功 的 ) L azy initialization
(載加遲延 用啟是設預 後 之 Hibernate 3
。料 資 得 取 來 法 方 種 各
User User
上 件 物 作 操 以 可 就 , 態 型 回 換 轉 之 將 ,料資 的 應 對 相 了 括 包 就
中件物的來回詢查著接,態型別類的料資裝封要與值 的料資定指,法方 id
load()
的 Session
用使接直以可,中作實法方 的 在而 find() UserDAO
。 結 連 的 庫 料 資 對 閉關接 直 是 不 而 , 中 之 池 接 連 至 還 歸 Connection
將會,後畢完行執法方 的 close()
在,) Session ( C onnection pool
池接連用使有果如中 在, Hibernate閉關於等不並Connection 閉關 Session
, Session
閉關法方 close()
用 使 得 記 要 , 候 時的線 連 庫 料 資 用 使 不 在
。位欄的應
user
對中格表 至存儲並,換轉料資性屬個各的中件物將,件文射映據根會
H ibernate
,後 之 法 方 行執 commit() org.hibernate.Transaction
在, 存 儲
件物將接直法方 的 save() Session
用 使 以 可 ,候 時的 料資 存 儲 在 ,易 交 啟
開須必則,時存儲或更變料資行進在, Session
啟 開須必 都 前 之 取 存 料 資 行
進次每中 Hibernate
在,用作的 中 Connection
於似類用作的 JDBC Session
,org.hibernate.Session
理管來用是 ,中 S essionFactory
在 Hibernate
}
}
return user;
session.close();
Hibernate.initialize(user);
User user = (User) session.get(User.class, id);
) – http://openhome.cc 良信林(冊手術技 Spring 2.0
- 13. Chapter 6 Hibernate 與 Spring
每的例實 對先須必 ,料資位 欄的應對得取 利順以件 物的回傳作操 了為 User
。成完來法方 過透以可這,作動的入載化始初作性屬個
Hibernate.initialize()
告,下之 在置放檔定設個一義定須必還,時
Hibernate 用使在 Classpath
案 檔 用 使 以 可,等 置 位 件 文 射 映、碼 密、 稱 名 者 用 使、稱 名 庫 料 資 知 XML
: 示所下如 ,
hibernate.cfg.xml 為名檔,義 定來
HibernateDemo hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/
→ hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="show_sql">
true
</property>
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="connection.url">
jdbc:mysql://localhost/demo
</property>
<property name="connection.username">
caterpillar
</property>
<property name="connection.password">
123456
6 13
- 14. Spring 2.0 良信林(冊手術技 – http://openhome.cc )
</property>
<!-- 件文射映格表庫料資與件物置設下以 -->
<mapping resource="onlyfun/caterpillar/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
為 定設 被
<session-factory> ,中 定設 的 在
" show_sql" " true” 在示表 ,
;法語 的用使、成生所 示顯時作 動取存庫料資 行執
Hibernate SQL H ibernate
,別差所有會 上作操 或 在庫 料資的同不, 庫料資的 同不多許用使 以可 SQL
邊這於由 ,作操句語的 用適庫料 資種一哪用使 將示表來
"dialect" 定設 以可
為定設以所,庫料資
MySQL 是的用使所 org.hibernate.dialect.
、
MySQLDialect 、 的來著 接 ;
"connection.driver_class" " connection.url"
驅 定 設以用別 分
"connection.username" 、
" connection.password" JDBC
U RL 。碼密與稱名 者用使 、 、別類式 程動
文射 映 的 格 表 庫 料 資 與 件 物 是 的 定 設
<mapping> "resource" 的中 在
在案檔示表, 為定設的面上在,置位件
onlyfun/caterpillar/User.hbm.xml
常通 , 下 夾 料 資
Classpath 的夾料資
onlyfun 的下徑路
caterpillar hbm.xml
POJO 。起一在置放別類 的應對與議建
,檔定設取讀來件物 立建是就著接
org.hibernate.cfg.Configuration
建件物 ,件 物表代 體 具 的 定 設 關 相 中
hibernate.cfg.xml 是它 C onfiguration
新生產再外另須必則,容內的案檔定設了改修您果如,動變會不就後之立
Configuration 。 取讀次 再 被 會 才 更 變 的 新 , 件 物 的
看觀 便 方 了 為 , 息 訊 誌日 多 許 生 產 下 台 控 主 在 會 設 預
Hibernate 於由
有只定設,案檔 個一置放中
Classpath 在以可,果結行執
log4j.properties
: 如 例,示 顯 以 加 才 息 訊 示 警
6 14
- 15. Chapter 6 Hibernate 與 Spring
HibernateDemo log4j.properties
log4j.rootLogger=WARN, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
的料資行進式程的計設上以用使何如解了,式程的單簡個一看來接直
:詢查與存儲
HibernateDemo HibernateDemo.java
package onlyfun.caterpillar;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateDemo {
public static void main(String[] args) {
// Configuration 理管責負 Hibernate 息訊置配
Configuration config =
new Configuration().configure();
// 據根 config 立建SessionFactory
// SessionFactory 立建於用將 Session
SessionFactory sessionFactory =
config.buildSessionFactory();
//立建 DAO件物
IUserDAO userDAO = new UserDAO(sessionFactory);
User user = new User();
user.setName("caterpillar");
user.setAge(new Integer(30));
userDAO.insert(user);
user = userDAO.find(new Integer(1));
System.out.println("name: " + user.getName());
}
}
6 1
- 16. Spring 2.0 良信林(冊手術技 – http://openhome.cc )
建來訊資的括包所中當它用使以可就,後之件物
Configuration 立建在
例實的
SessionFactory 將時 立建在著接,件物 UserDAO 立
SessionFactory
執 個一, 了 存 儲 的 料 資 行 進 來 件 物 作 操以可 就 後 然 , 它 給 定 指
UserDAO
:示所 下 如 面 畫 考 參 的 行
圖 6.4 HibernateDemo 果結行執的案專
於關有 Hibernate 的上 站網 我考參 以可,紹介的盡詳更 Hibernate
:件文
http://caterpillar.onlyfun.net/Gossip/HibernateGossip/
HibernateGossip.html
6 16
- 17. Chapter 6 Hibernate 與 Spring
6.2 在 Spring 中整合 Hibernate
有供提並,定設的
Spring Hibernate 對了合整 org.springframework.orm.
以可時用使 合結在您讓,別類等
hibernate3.HibernateTemplate Hibernate
用使供提,型模用使的似類相 與以且並,程流的寫撰式程化簡 JDBC
Hibernate 。理 管 易 交 告 宣 與 理 管 易 交 程 編 的 時
6.2.1 SessionFactory 注入
是等 理 管 易 交 、 結 連 的
Spring ,用使合結
Hibernate 與以可
H ibernate
存需只常通中式程用應在
SessionFactory ,的始開 S essionFactory 立建由
的 用使以可 的層底
SessionFactory 而因 , 例 實 個 一 在
DataSource Spring
IoC 。中之件物的依相至入注 SessionFactory 把再後之,入注
除刪可先首,案專 中
6.1.3 下一寫改以可如例
HibernateDemo
寫撰中檔義定 在
hibernate.cfg.xml 由以可份部這為因, Spring Bean Data-
:檔義定 的
Source 寫撰 下 如 以 可 , 代 取 來 入 注 賴 依 及 定 設
Spring Bean
SpringHibernateDemo beans-config.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.
→ datasource.DriverManagerDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/demo"/>
<property name="username" value="caterpillar"/>
<property name="password" value="123456"/>
6 17
- 18. Spring 2.0 良信林(冊手術技 – http://openhome.cc )
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.
→ hibernate3.LocalSessionFactoryBean"
destroy-method="close">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>onlyfun/caterpillar/User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
</props>
</property>
</bean>
<bean id="userDAO" class="onlyfun.caterpillar.UserDAO">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>
Spring 用使到看以可
合整 Hibernate 將接直以可,處好的 DataSource
,中 至入注
org.springframework.orm.hibernate3.LocalSessionFactoryBean
的 Hibernate過透可則,定設關相的需所 於至 LocalSessionFactoryBean
,等碼密、稱名者用使、稱名庫料資定設是像,定設來性屬關相 LocalSession-
實個這將時入注賴依行執在並,例實的
FactoryBean 立建會
SessionFactory
UserDAO 。 給定設例
於定指則,稱名與置位之件文射映的格表聯關與件物的
Hibernate
檔定設的身本 供提行自果如,中性屬
"mappingResources" Hibernate
檔定設定指來性屬 用使以可也,)
h ibernate.cfg.xml ( "configLocation"
6 18
- 19. Chapter 6 Hibernate 與 Spring
用使則邊這而,置位的 在性屬
"hibernateProperties" Spring 的 Bean 義定
對 少 減 此藉以 可 , 定 指 接 直 中 檔 XML 。理管的案檔態組
6 1
- 20. Spring 2.0 良信林(冊手術技 – http://openhome.cc )
在!意注 Spring 2.0 或 合整要擇選以可中 Hibernate 2
(
Hibernate 3 相不是
H ibernate 3 與上稱名件套在 Hibernate 2
在而因,)的容 。 的本版種兩有會時合整中
Spring API
org.springframework.orm.hibernate.LocalSessionFactoryBean
合整在是 Hibernate 2 而,別類的用使所時 org.spring-
整在是則
framework.orm.hibernate3.LocalSessionFactoryBean
例 (的 同 相 是 稱 名 別 類 要 主 為 因 , 別 類 的 用 使 時
Hibernate 3 合
的稱名件套意 注要時寫撰以所,)
LocalSessionFactoryBean 如
。確正否是定設
看來,式程試測的單簡個一寫撰以可,改修用不都份部的下剩中案專
:取存料資的單簡行進,
Spring 合整 用使何如看
Hibernate
SpringHibernateDemo SpringHibernateDemo.java
package onlyfun.caterpillar;
import org.springframework.context.ApplicationContext;
import org.springframework.context.
support.ClassPathXmlApplicationContext;
public class SpringHibernateDemo {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext(
"beans-config.xml");
// 立建 DAO 件物
IUserDAO userDAO =
(IUserDAO) context.getBean("userDAO");
User user = new User();
user.setName("caterpillar");
user.setAge(new Integer(30));
userDAO.insert(user);
6 2
- 21. Chapter 6 Hibernate 與 Spring
user = userDAO.find(new Integer(1));
System.out.println("name: " + user.getName());
}
}
與上本基果結的行執 HibernateDemo 圖考參以可,的同相是案專 6.4
。面畫行執的
入加擇選是不您果如,中案專
SpringHibernateDemo 在
徑路 至案檔的下以入加別個須必則,話的
spring.jar Classpath
、 、 、
s ping-core.jar :中之
s pring-beans.jar s pring-context.jar
。 、
spring-jdbc.jar 、
s pring-dao.jar s pring-hibernate.jar
用 使 了 除,上 定 指 的 件 文 射 映 在 ,外之定設性屬
"mappingResources"
用使以可也
"mappingDirectoryLocations" 徑路個 某 定 指 次 一 , 定 設 性 屬
:如例,案檔 .hbm.xml 有所的下
...
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.
→ LocalSessionFactoryBean"
destroy-method="close">
<property name="dataSource" ref="dataSource"/>
<property name="mappingDirectoryLocations">
<list>
<value>classpath:/onlyfun/caterpillar</value>
</list>
</property>
...
</bean>
...
6 21
- 22. Spring 2.0 良信林(冊手術技 – http://openhome.cc )
6.2.2 HibernateTemplate
Spring 的 Template-callback 在制機 Hibernate 有供提,上現實的
org.springframework.orm.hibernate3.HibernateTemplate 與別類 org.
springframework.orm.hibernate3.HibernateCallback 的 用 使 個 一,面 介
:下如子例
HibernateTemplate hibernateTemplate =
new HibernateTemplate(sessionFactory);
...
hibernateTemplate.execute(new HibernateCallback() {
public Object doInHibernate(
Session session) throws HibernateException {
return session.load(User.class);
}
});
。閉關動自會件物 ,後之畢完行執
S ession 提也上
H ibernateTemplate
立建動自時行執在,法方的便方個數有供 HibernateCallback 如例,件物
load() 寫改以可,法方等
g et() 、 、 、
s ave d elete() SpringHibernateDemo
:寫撰的式程化簡來 UserDAO 用使,別類 的中案專 HibernateTemplate
HibernateTemplateDemo UserDAO.java
package onlyfun.caterpillar;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateTemplate;
public class UserDAO implements IUserDAO {
private HibernateTemplate hibernateTemplate;
public void setSessionFactory(
SessionFactory sessionFactory) {
hibernateTemplate =
new HibernateTemplate(sessionFactory);
}
6 22
- 23. Chapter 6 Hibernate 與 Spring
public void insert(User user) {
hibernateTemplate.save(user);
}
public User find(Integer id) {
User user = (User) hibernateTemplate.get(User.class, id);
return user;
}
}
。 的 同相是 也 果 結 的 行 執 , 改修要 需 不 並 案 檔 的 它 其
在須必您 Classpath spring-orm.jar
入加中 行執以可才案檔
HibernateTemplateDemo。式程的中案專
承繼以 可您
org.springframework.orm.hibernate3.support.Hibernate-
、
DaoSupport 理管些一去省以可這,別類 UserDAO 寫撰來別類 SessionFactory
以可就例實的
HibernateTemplate 入注要只,作工的 源資 SessionFactory
:行執 以 可 是 也 式 程 則 , 容 內 的 下 以 為 代 替
UserDAO 的面上將如例,了
package onlyfun.caterpillar;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class UserDAO extends HibernateDaoSupport implements IUserDAO {
public void insert(User user) {
getHibernateTemplate().save(user);
}
public User find(Integer id) {
User user = (User) getHibernateTemplate().get(User.class, id);
6 23
- 24. Spring 2.0 良信林(冊手術技 – http://openhome.cc )
return user;
}
}
用使是 都 邊 這 在 , 到 意 注
HibernateTemplate 的 get() 使是果如,法方
到用使會將,法方 的
HibernateTemplate load() 用 Session 方 的件物
load()
但 , 能功 載 加 遲 延 的 設 預
Hibernate 3 用使會將這,法 HibernateTemplate
得取試嘗再若時此而因,
load() 閉關接直會將,後之法方 完行執
Session
User 。 生發會將,時性屬的
LazyInitializationException
作實是,一之法方的決解 HibernateCallback 給入傳例實將並,面介
:如例,法方
HibernateTemplate 的 execute()
...
public User find(final Integer id) {
User user = (User) hibernateTemplate.execute(
new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
User user = (User) session.load(User.class, id);
Hibernate.initialize(user);
return user;
}
});
return user;
}
在 doInHibernate() 用使動主,中作實的法方 Hibernate.initialize() 法方
化始初 User 的 在 接直 是 就, 法 方 個 一 另。 性 屬 的 件 物 Hibernate . hbm.xml
定設中 " lazy"改修如例,能功載加遲延用使不示表,
" false" 為性屬
User.hbm.xml :
...
<hibernate-mapping>
6 24
- 25. Chapter 6 Hibernate 與 Spring
<class name="onlyfun.caterpillar.User" table="user" lazy="false">
...
</class>
</hibernate-mapping>
6.2.3 HibernateTemplate 的 Lob 支援
用使在 Spring 配搭
Hibernate 要只,理 處 的 態 型 對 化 簡 以 可 , 時
Lob
在 SessionFactory 定指時構建 入注
LobHandler 將並,入注
SessionFactory
給 HibernateTemplate:如例,
...
<bean id="lobHandler" class="org.springframework.jdbc.
→ support.lob.DefaultLobHandler"/>
<bean id="sessionFactory" class="org.springframework.orm.
→ hibernate3.LocalSessionFactoryBean"
destroy-method="close">
<property name="dataSource" ref=”dataSource”/>
<property name="lobHandler" ref=”lobHandler”/>
<property name="mappingResources">
<list>
<value>onlyfun/caterpillar/User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
</props>
</property>
</bean>
<bean id="hibernateTemplate" class="org.springframework.orm.
→ hibernate3.HibernateTemplate">
<property name="sessionFactory" ref=”sessionFactory”/>
</bean>
...
6 2
- 26. Spring 2.0 良信林(冊手術技 – http://openhome.cc )
定指邊這在 LobHandler 、 於對,時 MySQL D B2 、 、
M S SQL Server
用使,
Oracle 10g 於對而,可即
DefaultLobHandler Oracle 9i 用使以可則,
OracleLobHandler 。
對般一與作操的來下接 HibernateTemplate 資的您如例,異無作操的
:為格表庫料
CREATE TABLE user (
id INT auto_increment PRIMARY Key,
txt TEXT,
image BLOB
);
Spring 的 至射映 將以可
ClobStringType Clob String 而,
BlobByte-
ArrayType 將以可 Blob 個一計設以可, 至射映
byte[] User :下如別類
package onlyfun.caterpillar;
public class User {
private Integer id;
private String txt;
private byte[] image;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public byte[] getImage() {
return image;
}
public void setImage(byte[] image) {
this.image = image;
}
public String getTxt() {
return txt;
}
6 26
- 27. Chapter 6 Hibernate 與 Spring
public void setTxt(String txt) {
this.txt = txt;
}
}
於至 Use.hbm.xml :寫撰下如以可則
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="onlyfun.caterpillar.User" table="user">
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="txt" column="txt"/>
<property name="image" column="image"/>
</class>
</hibernate-mapping>
取 讀與存 儲 的 單 簡 個 是 下 以 Lob :範示段片式程的
...
ApplicationContext context =
new FileSystemXmlApplicationContext("beans-config.xml");
InputStream is = new FileInputStream(
new File("c:workspacewish.jpg"));
byte[] b = new byte[is.available()];
is.read(b);
is.close();
User user = new User();
user.setTxt("long...long...text");
user.setImage(b);
HibernateTemplate hibernateTemplate =
(HibernateTemplate) context.getBean("hibernateTemplate");
hibernateTemplate.save(user);
6 27
- 28. Spring 2.0 良信林(冊手術技 – http://openhome.cc )
user = (User) hibernateTemplate.execute(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
User user = (User) session.load(User.class, new Integer(1));
Hibernate.initialize(user);
return user;
}
});
System.out.println(user.getTxt());
b = user.getImage();
OutputStream os = new FileOutputStream(
new File("c:workspacewish_bak.jpg"));
os.write(b);
os.close();
...
6.2.4 Hibernate 編程交易管理
合整 用使在而然,作實理管易交的己自有供提
Hibernate Spring
的式程 編 用 使 以 可 您 , 責 負 來
Hibernate 由交理管易交將議建,時
Spring
, 似類理 管 易 交 的 式 程 編 行 進
5 用 使 接 直 中 章 第與 法 方 , 理 管 易 交
JDBC
使,寫改以加別類 的中案專
HibernateTemplateDemo 將可如例
UserDAO
。能 功 理 管 易 交 有 具 之
TransactionTemplateDemo UserDAO.java
package onlyfun.caterpillar;
import org.hibernate.SessionFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.
support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
6 28
- 29. Chapter 6 Hibernate 與 Spring
import org.springframework.orm.
hibernate3.HibernateTransactionManager;
public class UserDAO implements IUserDAO {
private TransactionTemplate transactionTemplate;
private HibernateTemplate hibernateTemplate;
public void setSessionFactory(
SessionFactory sessionFactory) {
this.transactionTemplate =
new TransactionTemplate(
new HibernateTransactionManager(
sessionFactory));
this.hibernateTemplate =
new HibernateTemplate(sessionFactory);
}
public void insert(User user) {
final User userData = user;
// 為行播傳定設
transactionTemplate.setPropagationBehavior(
TransactionDefinition.PROPAGATION_REQUIRED);
transactionTemplate.execute(
new TransactionCallbackWithoutResult() {
protected void doInTransactionWithoutResult(
TransactionStatus status) {
hibernateTemplate.save(userData);
}
});
}
public User find(Integer id) {
User user = (User) hibernateTemplate.get(User.class, id);
return user;
}
}
類
org.springframework.transaction.support.TransactionTemplate
作 實個一 要 需 , 時 立 建 在 別 PlatformTransactionManager 使邊這,例實的
6 2
- 30. Spring 2.0 良信林(冊手術技 – http://openhome.cc )
是的用 org.springframework.orm.hibernate3.HibernateTransaction-
為行播傳定設須必
Manager ,例實立建來別類
T ransactionTemplate
外例生發在,易交行執來件物
P ropagation Behavior 用使並、) Callback (
,後之外例捉捕在以可,作操消撤時何制控部細要需果如,作操消撤會將時
與 作動些 這 , 作 操 消 撤 法 方
TransactionStatus 的
setRollbackOnly() 用使
易 交 關 有 章 第 下 一 考 參 以可, 的 似 類 是 都 時 理 管 易 交
5 JDBC 解講章 第 5
。 明 說 節 細 些一 解 了 來 件 文 考 參
Spring 看看或,容內的理管
6.2.5 Hibernate 宣告交易管理
的過紹介中章 第與這,理管易交告宣供提
Spring Hibernate 對 5 JDBC
從接直,式方的單簡較比下一紹介來先,似類理管易交告宣 Hibernate-
只而,別類 改修要需不上實事,寫改行進來案專
TemplateDemo UserDAO
:可即 定 設 上 檔 義 定 在 要
HibernateDeclarativeTransactionDemo UserDAO.java
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.
→ datasource.DriverManagerDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/demo"/>
<property name="username" value="caterpillar"/>
<property name="password" value="123456"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.
6 3
- 31. Chapter 6 Hibernate 與 Spring
→ hibernate3.LocalSessionFactoryBean"
destroy-method="close">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>onlyfun/caterpillar/User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
</props>
</property>
</bean>
<bean id="userDAO" class="onlyfun.caterpillar.UserDAO">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.
→ hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="userDAOProxy"
class="org.springframework.transaction.
→ interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"
ref="transactionManager"/>
<property name="proxyInterfaces">
<list>
<value>onlyfun.caterpillar.IUserDAO</value>
</list>
</property>
<property name="target" ref="userDAO"/>
<property name="transactionAttributes">
<props>
<prop key="insert">PROPAGATION_REQUIRED</prop>
</props>
</property>
6 31
- 32. Spring 2.0 良信林(冊手術技 – http://openhome.cc )
</bean>
</beans>
與 了立建中檔定設於在別差的要主 "transactionManager"
的 定 設以所 , 型 模 定 設 的 性 致 一 的 供 提 所
"userDAOProxy" Spring 於由,
考參以 可 , 的 似 類 是 式 方 定 設 的 理 管 易 交 告 宣
5 JDBC 紹介中章 第與式方
5 。明說的理管易交告宣於關有章 第下一
:示所下如,作操行進來件物理代 回取次這,下一試測式程個寫來 DAO
HibernateDeclarativeTransactionDemo SpringHibernateDemo.java
package onlyfun.caterpillar;
import org.springframework.context.ApplicationContext;
import org.springframework.context.
support.ClassPathXmlApplicationContext;
public class SpringHibernateDemo {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext(
"beans-config.xml");
// 立建 DAO件物
IUserDAO userDAO =
(IUserDAO) context.getBean("userDAOProxy");
User user = new User();
user.setName("cater");
user.setAge(new Integer(30));
userDAO.insert(user);
user = userDAO.find(new Integer(1));
System.out.println("name: " + user.getName());
}
}
6 32
- 33. Chapter 6 Hibernate 與 Spring
行執在果如 insert() ,中格表至增新被會不料資則,外例了生發時法方
在行自以可您 UserDAO 否 是能功 的 易 交 試 測 以 , 外 例 個 出 丟 試 嘗 中 別 類
。行執確正
用使,時理管易交告宣行進
Spring對中 在,的樣同
Hibernate
中定設徑路的 在須必您以所,能功的
Spring AOP 到 Classpath
spring-aop.jar
。式程的中案專行執以可才案檔 入加
過紹介 在
5.3.6 Spring 2.0 於基 XML Schema 這在, 理 管 易 交 告 宣 的
下 一 改修要 只 則 , 用 使 要 若 邊 beans-config.xml :式方定設下以為
HibernateDeclarativeTransactionDemo2 beans-config.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: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.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.
datasource.DriverManagerDataSource">
→
<property name="driverClassName"
value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/demo"/>
6 33
- 34. Spring 2.0 良信林(冊手術技 – http://openhome.cc )
<property name="username" value="caterpillar"/>
<property name="password" value="123456"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.
→ hibernate3.LocalSessionFactoryBean"
destroy-method="close">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>onlyfun/caterpillar/User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
</prop>
</props>
</property>
</bean>
<bean id="userDAO" class="onlyfun.caterpillar.UserDAO">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.
→ hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:advice id="txAdvice"
transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="insert" propagation="REQUIRED"/>
<tx:method name="find" read-only="true"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="userDAOPointcut" expression=
6 34
- 35. Chapter 6 Hibernate 與 Spring
"execution(* onlyfun.caterpillar.IUserDAO.*(..))"/>
<aop:advisor advice-ref="txAdvice"
pointcut-ref="userDAOPointcut"/>
</aop:config>
</beans>
進例實 得取接直以所,件物理代定設中檔定設於再不於由 " userDAO"
寫改 如 例 , 式 方 定 設 的 於 基 用 使以可 也 您 。 可 即 作 操 行
Annotation User-
DAO :下如
HibernateDeclarativeTransactionDemo3 UserDAO.java
package onlyfun.caterpillar;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
public class UserDAO implements IUserDAO {
private HibernateTemplate hibernateTemplate;
public void setSessionFactory(
SessionFactory sessionFactory) {
hibernateTemplate =
new HibernateTemplate(sessionFactory);
}
@Transactional(propagation = Propagation.REQUIRED)
public void insert(User user) {
hibernateTemplate.save(user);
}
@Transactional(readOnly=true)
public User find(Integer id) {
User user = (User) hibernateTemplate.get(User.class, id);
return user;
}
}
6 3
- 36. Spring 2.0 良信林(冊手術技 – http://openhome.cc )
在著接 beans-config.xml 用使中 < tx:annotation-driven> 定設並 Tran-
sactionManager :如例,可即
HibernateDeclarativeTransactionDemo3 beans-config.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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="dataSource"
class="org.springframework.jdbc.
→ datasource.DriverManagerDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/demo"/>
<property name="username" value="caterpillar"/>
<property name="password" value="123456"/>
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.
→ hibernate3.LocalSessionFactoryBean"
destroy-method="close">
<property name="dataSource" ref="dataSource"/>
<property name="mappingResources">
<list>
<value>onlyfun/caterpillar/User.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.MySQLDialect
6 36
- 37. Chapter 6 Hibernate 與 Spring
</prop>
</props>
</property>
</bean>
<bean id="userDAO" class="onlyfun.caterpillar.UserDAO">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.
→ hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
6 37
- 38. 6 38
式方用使的 Hibernate 了化簡並合整 6.5 Spring 圖
。能功器容 的 IoC
Spring
用 使 合 整 於 易 是 處 好 的 它 用 使,架 框 的 供 提 所 MVC 識認先 Spring
將 先首, 案 方 決 解 的 供 提 所 層 於 Web Spring
下 一紹介 來 將 , 始 開 節 章 個
一下在,下一考參以可也您議建,明說的案方層久持於關有多更有還,中
件文考參的 Spring在,邊 這 到 明 說 且 暫 , 援 支 的 層 久 持 於 對 Spring
6.3 接下來的主題
) – http://openhome.cc 良信林(冊手術技 Spring 2.0