Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Spring 2.0 技術手冊第六章 - Hibernate 與 Spring

2,885 views

Published on

Spring 2.0 技術手冊

Published in: Technology
  • Be the first to comment

Spring 2.0 技術手冊第六章 - Hibernate 與 Spring

  1. 1. 。能功等理管易交的式告宣如,能功的 合結以可並,化簡為更以可上用使在,型模用使 Spring的致一 循 依以可都,上用使與定設的 Spring 在您讓,裝 Hibernate封了行進 為 , Hibernate 合整中 S pring在以可您 Hibernate Spring 。能功等理管易交、定鎖、取快的需所層久持有供提也並,射映動自的型模聯關庫料資式聯關與型模件物 供提,案方決解 Java的) (射映係關件物個是 O bject/Relation Mapping, ORM Hibernate Hibernate 與 Spring 6
  2. 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. 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. 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. 5. Chapter 6 Hibernate 與 Spring節小個這,表發式正 月 年 , 一之目 項 子 其 為 成 而 納 收 2 005 3 Hibernate 3寫改來 用使何如看看, 用 使是即 介 簡 的 行 進 要 所 中 Hibernate 3 Hibernate 。能功的 5 解了步初以,別類 的過計設所中章 第 UserDAO Hibernate6.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 6 。 案 檔 依 相 的到用 會 能 可 是 則 的 中 錄 目 在 , 件 文 考 參 關 相 lib API 或明說 到找中錄目 在以可,裝封之 的要需所 doc API 是 Hibernate 3 這, hibernate3.jar 有就下錄目的開解在,後之縮壓解並案檔 載下 zip。間時的載下省節以,站網射鏡的域區在所載下近接最個一擇選以可,站網 m irror) ( 鏡擇選要需會,後之結鏈載下的案檔擇選, 射 hibernate-3.2.0.ga.zip載 下 以 可 您 , 案 檔 載 下的 式 格 縮 壓 同 不 種 幾 有 供 提 上 在 Sourceforge 案檔關相 Hibernate 載下 Sourceforge 從 6.2 圖 :) id=127784http://sourceforge.net/project/showfiles.php?group_id=40712&package_ ( ) – http://openhome.cc 良信林(冊手術技 Spring 2.0
  7. 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. 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. 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. 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. 11. Chapter 6 Hibernate 與 Spring 由後然 作實來別類 UserDAO IUserDAO 用使時作實次這,面介 的Hibernate API 個一入注要需, :件物 org.hibernate.SessionFactory HibernateDemo UserDAO.javapackage 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. 12. 6 12, Session 了閉關經已 ,前束結法方 在 。 find() LazyInitializationException出丟會則否,態狀的啟開在是須必 時此而,詢查 Session行進位欄應對的格表料資向會不,前料資得取 的件 物作操在正真 是就 Getter也,能功 的 ) L azy initialization (載加遲延 用啟是設預 後 之 Hibernate 3 。料 資 得 取 來 法 方 種 各 User User上 件 物 作 操 以 可 就 , 態 型 回 換 轉 之 將 ,料資 的 應 對 相 了 括 包 就中件物的來回詢查著接,態型別類的料資裝封要與值 的料資定指,法方 idload() 的 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. 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. 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. 15. Chapter 6 Hibernate 與 Spring HibernateDemo log4j.propertieslog4j.rootLogger=WARN, stdoutlog4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n的料資行進式程的計設上以用使何如解了,式程的單簡個一看來接直 :詢查與存儲 HibernateDemo HibernateDemo.javapackage 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. 16. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 建來訊資的括包所中當它用使以可就,後之件物 Configuration 立建在 例實的 SessionFactory 將時 立建在著接,件物 UserDAO 立 SessionFactory 執 個一, 了 存 儲 的 料 資 行 進 來 件 物 作 操以可 就 後 然 , 它 給 定 指 UserDAO :示所 下 如 面 畫 考 參 的 行 圖 6.4 HibernateDemo 果結行執的案專 於關有 Hibernate 的上 站網 我考參 以可,紹介的盡詳更 Hibernate :件文 http://caterpillar.onlyfun.net/Gossip/HibernateGossip/ HibernateGossip.html6 16
  17. 17. Chapter 6 Hibernate 與 Spring6.2 在 Spring 中整合 Hibernate 有供提並,定設的 Spring Hibernate 對了合整 org.springframework.orm.以可時用使 合結在您讓,別類等hibernate3.HibernateTemplate Hibernate用使供提,型模用使的似類相 與以且並,程流的寫撰式程化簡 JDBCHibernate 。理 管 易 交 告 宣 與 理 管 易 交 程 編 的 時6.2.1 SessionFactory 注入是等 理 管 易 交 、 結 連 的 Spring ,用使合結 Hibernate 與以可 H ibernate存需只常通中式程用應在 SessionFactory ,的始開 S essionFactory 立建由的 用使以可 的層底 SessionFactory 而因 , 例 實 個 一 在 DataSource SpringIoC 。中之件物的依相至入注 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. 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. 19. Chapter 6 Hibernate 與 Spring 用使則邊這而,置位的 在性屬 "hibernateProperties" Spring 的 Bean 義定對 少 減 此藉以 可 , 定 指 接 直 中 檔 XML 。理管的案檔態組 6 1
  20. 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. 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. 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. 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. 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. 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. 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. 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. 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. 29. Chapter 6 Hibernate 與 Springimport 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. 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. 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. 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. 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. 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. 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.javapackage 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. 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.MySQLDialect6 36
  37. 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. 38. 6 38 式方用使的 Hibernate 了化簡並合整 6.5 Spring 圖 。能功器容 的 IoCSpring 用 使 合 整 於 易 是 處 好 的 它 用 使,架 框 的 供 提 所 MVC 識認先 Spring將 先首, 案 方 決 解 的 供 提 所 層 於 Web Spring 下 一紹介 來 將 , 始 開 節 章 個一下在,下一考參以可也您議建,明說的案方層久持於關有多更有還,中件文考參的 Spring在,邊 這 到 明 說 且 暫 , 援 支 的 層 久 持 於 對 Spring 6.3 接下來的主題 ) – http://openhome.cc 良信林(冊手術技 Spring 2.0
  39. 39. Chapter 6 Hibernate 與 Spring 6 3

×