SlideShare une entreprise Scribd logo
1  sur  68
Télécharger pour lire hors ligne
。援支些一的
上易交及以取存      JDBC 於        紹介來子例的際實些一以將,中節
                      Spring
章 個 這 在。能 功 的 務 服 關 相 等 易 交 得 獲 易 輕 並,式 方 用 運 的    化 JDBC
簡 以 可,能 功 的 供 提 所 架 框 與 器 容
                          AOP            合 結,之 言 而 總
                                     Spring IoC
                   。)                         (
                        D eclarative transaction management
理管易交式告宣與)                                     (
                    P rogrammatic transaction management
理管易交式程編了供提             ,面方理處的易交於關。用使
                       Spring
作操的上 在 API   JDBC 化簡以別類等         了供提也
                                JdbcTemplate           Spring
,上用使的    JDBC API 在。外例的定特理處否是擇選以可您,裝封新
重以加 外例些一 的時取 存庫料資對         。節細術技的庫料資層底
                                S pring
觸 接 用 不 以 可 您 ,架 框 了 供 提
                    DAO    ,援 支 的 取 存 庫 料 資 於 對
                                S pring
                                JDBC、交易支援
    5
2
                                 }
                                     public void delete(User user);
                                     public void update(User user);
                                     public User find(Integer id);
                                     public void insert(User user);
                                 public interface IUserDAO {
                                         package onlyfun.caterpillar;
  :面介  IUserDAO  個 一 如例, 面 介 個 一 賴 依 它 讓以可 而 , 作 實 別 類 的 際
實個一於賴依應不式程用應,) 、 、 、 如例(時取 d elete   u pdate   i nsert   select
                    User
存 庫 料 資 行 進 在, 件 物 個 有 中 式 程 用 應 設 假, 子 例 的 個 舉             DAO
                                               。節細關相的
時取存作實,中之法方的範規在並,面介該作實要件物的取存庫料資行進
上際實而,作操來面介取存料資個一過透是,時取存料資到用使要需,中
式程用應在,    Data Access Object               D AO
                            為 名 全 的 ,節 細 術 技 庫 料 資 定 特
的用 使 所 到 觸 接 須 無 ,時取 存 庫 料 資 行 進 在 您 讓 架 框    的      DAO          Spring
                                     5.1.1 Spring 的 DAO 支持
                                          。層久持                        Spring
門入來子例的際實以並,計 設             DAO
                             的       Spring
                                      介簡來先節小個這,術技
庫料 資 定 特 於 合 耦 須 無時發 開 式 程 用 應 讓 , 架 框   了供提   DAO                Spring
                                 5.1 Spring 持久層入門
             )   – http://openhome.cc     良信林(冊手術技                Spring 2.0
Chapter 5 JDBC      援支易交、

作 實 以 可 別 類 的取存 庫 料 資 行 進 上 際 實          IUserDAO   一義定如例,面介
             :別類
         UserDAO           的單簡個
package onlyfun.caterpillar;
...
public class UserDAO implements IUserDAO {
    private DataSource dataSource;

   public void setDataSource(DataSource dataSource) {
       this.dataSource = dataSource;
   }

   public void insert(User user) {
      String name = user.getName();
      int age = user.getAge().intValue();

      Connection conn = null;
      PreparedStatement stmt = null;
       try {
           conn = dataSource.getConnection();
           stmt = conn.prepareStatement (
               "INSERT INTO user (name,age) VALUES(?,?)");
           stmt.setString(1, name);
           stmt.setInt(2, age);
           stmt.executeUpdate();
       } catch (SQLException e) {
           e.printStackTrace();
       }
       finally {
           if(stmt != null) {
               try {
                   stmt.close();
               }
               catch(SQLException e) {
                   e.printStackTrace();
               }
           }
           if(conn != null) {
               try {
                   conn.close();
               }



                                                                     3
Spring 2.0   良信林(冊手術技        – http://openhome.cc   )

                  catch(SQLException e) {
                      e.printStackTrace();
                  }
              }
         }
    }

    public User find(Integer id) {
        ...
        return user;
    }

    public void update(User user) {
        ...
    }

    public void delete(User user) {
        ...
    }
}


用 使以可 , 時 取 存 料 資 行 進在程 流 主 式 程 用 應 的 您                 IUserDAO   告宣來
                           :如例,面介作操
...
User user = new User();
user.setName("caterpillar");
user.setAge(new Integer(30));

IUserDAO userDao = getUserDAO();
userDao.insert(user);
...


而,別類作實的               換替時隨以可以所,面介於賴依於由       IUserDAO
術技的取存庫料資層底與何任有沒並,上法方作操的告宣面介
IUserDAO
層 底與式 程 用 應 將 , 理 原 本基的 樣 這 於 基 是 正 架 框
        S pring   DAO                     的   ,節細
                                        :來開離隔術技取存

4
Chapter 5 JDBC   援支易交、




                                 圖   5.1 DAO   圖意示作運
如例(法方的關無術技取存庫料資定特與有只上面介取存料資
不 也,試 測 於 易 也 式 程 , 面介於 賴 依 上 計 設 , ) 等
update    i nsert   d elete                、 、
                     。術 技 庫 料 資 一 某 用 使能只 於 限 受 式 程 用 應 讓
驟步個幾有,說來程流取存庫料資的際實於對,中式程範示的前之在
不 於 對, 等 外 例 理 處、          得 取、
                         DataSource     得 取 如 例, 的 定 固 是
                                                Connection
設就,同不程流份部少有只,的同相是上致大驟步些這,術技庫料資的同
於寫撰程流的定固將,式模                            用使以可,言而上計
                              Template-Callback
來件物
Template     由委則,驟步節細些一的同不於對而,中之別類                            Callback
有中其於對,程流的定固是份部字體粗非,中段片式程的下以如例,成完
 :件物 的 當 適 回 傳 或 行 執 來 件 物        的 別 個作實 以 可 , 份 部 的 異 差
                                     Callback
         ...
         Connection conn = null;
         PreparedStatement stmt = null;
          try {
              conn = dataSource.getConnection();
              stmt = callback.createPreparedStatement(conn);
              stmt.executeUpdate();
          } catch (SQLException e) {
              e.printStackTrace();
          }
          finally {
              if(stmtCallback != null) {
                  try {
                      stmt.close();
                  }
Spring 2.0     良信林(冊手術技           – http://openhome.cc      )

                   catch(SQLException e) {
                       e.printStackTrace();
                   }
               }
               if(conn != null) {
                   try {
                       conn.close();
                   }
                   catch(SQLException e) {
                       e.printStackTrace();
                   }
               }

           }

於寫撰程流的定固將,式模
    Spring                            了用運就
                          Template-Callback
而,)別類
Template              、            如例(中之別類
                             JdbcTemplate        H ibernateTemplate
定 自以可 ( 理 處 來 件 物 援 支   定 特 託 委 則 , 驟步節 細 些 一 的 同 不 於 對
                                          DAO
       Spring                    :)生產動自           由或義




                      圖   5.2 DAO Template   與   DAO Support


應讓,系體理處外例的關無術技定特與供提也 ,面方理處外例在
                        S pring
,)        、       是像( 外例定特 理處因會不式 程用  SQLException      H ibernateException
                 。術技層 久持或庫 料資種某於合 耦而


6
7
    類子的      org.springframework.dao.DataAccessException
                                                     是都外例的
    有所   S pring
             , 外 例 的 關相術 技 庫 料 資 與 出 丟 不 並 架 框      的           DAO      Spring
               。 續 手 的 道 多更要 就 , 層 上 至 出 丟 外例些 這 讓 要 想 果 如 , 掉
    理處自暗來          try..catch
                      些一寫撰行自能只, 之將法無就,)           throw                   Hibernate
    是或    JDBC是像,況情種這有而同不術技層底的用使於由能可(
    外例的明聲上法方是不些某了生發中法方些這在果如而然,外例的型類些
    某 throws
           明聲上法方於,時面介義定在會也們它,息訊外例的關相些一括
    包,別類外例的關相承繼行自會架框或式程些有,面方一另,意主的好個
    一是不也播傳層上向以可外例讓,外例告宣上法方在                          用使接直       throws
                                         。 外 例些這 掉 理 處 來 法 語 理 處
    外例些一寫撰的何奈可莫好只員人計設式程,理處要定一求要器譯編於由
    ,Checked exception
                     對 面 而然, ) ? 息 訊 的 線 連 法無下 錄 記 如 例 ( 理 處 的
    力為能無些一作,中式程取存庫料資的層底在是不而,邊哪在出題問知得
    者用使讓,息訊關相示顯以捉捕式程用應層上由,式程用應層上至播傳外
    例讓,理處不是就式方理處的好最,)線連得取法無如例(時生發取存庫
    料資的層底在外例的類這當,作運常正至復回力無往往                                      Checked exception
    於對,候時有而然,作運常正復回能式程至理處以加以可員人計設式程是
    的 望 希, 時 生 發 外 例 類 這 於 對, 的 好 是 來 本 意 立 的              Checked exception
      。)面 介 形 圖 者 用 使 如 例(理 處 層 上 最 式 程 用 應至出 丟 接 直 外 例 讓 是 或
    ,理處作來         try...catch
                      用使擇選以可,時生發的真外例,外例的發引所期時
    行 執 在 ,誤 錯 的 上 輯 邏 式 程 於 由 是 常 通 , 別 類 子 的 別 類                RuntimeException
    java.lang.
            是上構架承繼外例在,)                       Runtime exception
                                                     (外例期時
    行執是則         U nckecked exception
                             ;理處以加                try...catch
                                                 以上法語在須必此因
    ,理處要定一求要器譯編,的生發期預以可是常通外例些這為因,外例的
    理 處須必 上 法 語 在 期 時 譯 編 是         C hecked exception
                                             。             Unchecked exception
    與  Checked exception  有外例的 ,理處外例解瞭來先首  Java
    援支易交、         Chapter 5 JDBC
8
取來  org.springframework.jdbc.datasource.DriverManagerDataSource
供提    Spring
         ,面介作操的入注                        Datasource
                                   個一留保上件物                                     Bean
的源來接連得取要需在以可,此為,輯邏務商的層上到響影應不為行些這
,為行的層底是動更的源來料資,等 過透是或、池接連過透、 用       JNDI                                   JDBC
使的綷純如例,源來料資的同不用使能可式程用應,統系的同不應因
                                               。式程行
一 何任改 修 用 不 而 , 置 配 改 修 中 檔 義 定             Bean
                                 在 要只源 來 料 資 換 更 , 入 注
javax.sql.DataSource
                 了供提           S pring
                             ,求需源來接連料資的同不於對
                                                5.1.2 DataSource 注入
           。圖承繼別類的              DataAccessException
                                           個有也,明說的理處
外例對些一有中當,節章                 DAO support
                                的中件文考參           看看以可。捉       Spring
捕 以加外 例 的 理 處 想 對 針 以 可 您 , 等             BadSqlGrammarException
                                                      的時誤
錯法語 、  S QL    DataAccessResourceFailureException
                                             的出丟會時誤錯結
連庫 料 資 如 例 , 類 分 了 好 作 外 例 將 也            S pring
                                     ,外例 的 定 特 理 處 要 果 如
                                 JVM
                  。 理 處 來 由 後 最 是 或 式程用 應 的 層 上 最 由 , 它
略 忽 者 或 ,它 理 處 擇 選 以 可 您 , 外 例 些 一 於 對 ,                RuntimeException
                                                      自承繼
NestedRuntimeException
                     而,        NestedRuntimeException
                                              的件套                          work.core
org.springframe-
              自 承 繼 它,別 類 礎 基 的 次 層 個 這 是                     DataAccessException
,次層理處外例的性致一供提下件套                              o rg.springframework.dao
                                                      ,件物
    DAO
外例 的己自為化轉等                   SQLException
                                   將     ,取存        S pring
                                                     於對             JDBC
。 式程用 應 的 層 上 至 播 傳 外例將 的 單 簡 很 以 可 也 ,下況 情 的 外 例 理 處 不 在
,理處 要 不 要 擇 選 己 自 以 可 而 , 外 例 理 處 來                 try...catch
                                             用使迫強被用不您
,Unchecked exception 於屬是 它 說 是 就 也 , 別 類 子 的                      RuntimeException
是  DataAccessException
                     且而,外例用通的關無術技庫料資與個一,別
                   )   – http://openhome.cc         良信林(冊手術技            Spring 2.0
Chapter 5 JDBC          援支易交、

         ,例實的它得
              D riverManagerDataSource    了作實    javax.sql.DataSource         您,
:寫撰麼這中檔義定 在以可
       Bean


...
<beans...>
    <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>
    ...
</beans>


                         屬個四
         "driverClassName"        、
                               " url"中其、 、
                                         " username"       " password"
                  JDBC      定設來用是別分性
                         、稱名者用使、定協 庫料資、別類式程動驅        URL
                                      。碼密
前之範示並,範示的入注    為 作 來 式程個 一 用 使 際 實 邊 這 在DataSource
  :下如面介作操的 個一了義定您設假,作實的紹介 於關有
       DAO                                     DAO


  DataSourceDemo                                               IUserDAO.java
package onlyfun.caterpillar;

public interface IUserDAO {
    public void insert(User user);
    public User find(Integer id);
}



   有 只 義 定 面 介 的 於 關 邊 這,制 限 的 幅 篇 於 基
                               DAO                         insert()   與   find()   兩
: 義 定 下 如 則 別 類 的 到 用 使 所中面 介 個 這 在 。 法 方 個
                                  User
Spring 2.0    良信林(冊手術技          – http://openhome.cc   )

        DataSourceDemo                                      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;
         }

         public Integer getAge() {
             return age;
         }

         public void setAge(Integer age) {
             this.age = age;
         }
    }



了作實它,別類             個一義定以可著接
                          UserDAO                IUserDAO   實是,面介
   : 示 所 下 如 , 件 物 的務服 取 存 庫 料 資 行 進 際



1
Chapter 5 JDBC       援支易交、

 DataSourceDemo                                           UserDAO.java
package onlyfun.caterpillar;

import   java.sql.Connection;
import   java.sql.PreparedStatement;
import   java.sql.ResultSet;
import   java.sql.SQLException;
import   javax.sql.DataSource;

public class UserDAO implements IUserDAO {
    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    public void insert(User user) {
       String name = user.getName();
       int age = user.getAge().intValue();

         Connection conn = null;
         PreparedStatement stmt = null;
         try {
             conn = dataSource.getConnection();
             stmt = conn.prepareStatement (
                  "INSERT INTO user (name,age) VALUES(?,?)");
             stmt.setString(1, name);
             stmt.setInt(2, age);
             stmt.executeUpdate();
          } catch (SQLException e) {
               e.printStackTrace();
          }
          finally {
               if(stmt != null) {
                   try {
                       stmt.close();
                   }
                   catch(SQLException e) {
                       e.printStackTrace();
                   }
               }



                                                                     11
Spring 2.0   良信林(冊手術技          – http://openhome.cc   )

               if(conn != null) {
                   try {
                       conn.close();
                   }
                   catch(SQLException e) {
                       e.printStackTrace();
                   }
               }
         }
     }

     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;
                 }
             } catch (SQLException e) {
                 e.printStackTrace();
             }
             finally {
                 if(stmt != null) {
                     try {
                         stmt.close();
                     }



12
Chapter 5 JDBC   援支易交、

                   catch(SQLException e) {
                       e.printStackTrace();
                   }
               }
               if(conn != null) {
                   try {
                       conn.close();
                   }
                   catch(SQLException e) {
                       e.printStackTrace();
                   }
               }
         }

         return null;
     }
}



     UserDAO 入注您讓以可,法方          個一告宣上別類
                                 setDataSource()
DataSource   :示所下如,義定的入注賴依行進中檔義定 在以可,例實的
                          Bean


    DataSourceDemo                                    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"/>
     </bean>




                                                                       13
Spring 2.0   良信林(冊手術技        – http://openhome.cc      )

     <bean id="userDAO"
            class="onlyfun.caterpillar.UserDAO">
          <property name="dataSource" ref="dataSource"/>
     </bean>
 </beans>



作 操 來 式 程 試測的 單 簡 個 一 寫 撰 以 可             UserDAO   能否是看看,例實的
            :詢查 與 存 儲 的 料 資 行 進
     DataSourceDemo                                 SpringDAODemo.java
 package onlyfun.caterpillar;

 import org.springframework.context.ApplicationContext;
 import org.springframework.context.
               support.ClassPathXmlApplicationContext;

 public class SpringDAODemo {
     public static void main(String[] args) {
         ApplicationContext context =
             new ClassPathXmlApplicationContext(
                     "beans-config.xml");

          User user = new User();

          user.setName("caterpillar");
          user.setAge(new Integer(30));

          IUserDAO userDAO =
              (IUserDAO) context.getBean("userDAO");

          userDAO.insert(user);

          user = userDAO.find(new Integer(1));

          System.out.println("name: " + user.getName());
      }
 }




14
Chapter 5 JDBC       援支易交、


            將並,務服庫料資啟開先要您,前之試測的式程行進在                                beans-
      與 稱 名 者 用 使、 庫 料 資、別 類 式 程 動 驅 的 關 相 中
      config.xml                                       URL
      而,庫 料 資       是 的 用 使 所 邊 這 在,定 設 的 您 為 改 修 等 碼 密 MySQL
             user :的立建來 的下以用使是格表 的立建     SQL

      CREATE TABLE user (
          id INT(11) NOT NULL auto_increment PRIMARY KEY,
          name VARCHAR(100) NOT NULL default '',
          age INT
      );



     據根著接,料資筆一入存中格表 的庫料資在先會果結行執的式程       user
id   。字文的        示顯會果結後最,料資的入存所前先出詢查值                  "name: caterpillar"




      、               、
             spring-core.jar    、       要需您
                                s pring-beans.jar      s pring-context.jar
      spring-dao.jar      spring-jdbc.jar
      是 的 用 使 您 果 如,案 檔 個 幾 這       與
      的依相要需也外另, 關相了括包經已中當,
      spring.jar                                API
           有 要 須 必 您, 用 使 了 為,然 當,
      commons-logging.jar                         JDBC                JDBC
                    jar           。案檔 的式程動驅

5.1.3 DataSource 置換

單簡作來用是只,能功的池接連供提有沒並
     DriverManagerDataSource
以   用 使 以 可 您。中 之 案 專 的 正 真 於 用 使 合 適 不 並,試 測 接 連 機 單 的                  DBCP
程改修要需不並           換置則,          用使果如。能功的池接連得獲
                                Spring                DataSource
          下一改修如例,了以可就檔義定 改修要只,碼始原式
                      Bean                                       DataSourceDemo
         beans-config.xml   :下如                 的中案專

                                                                                  1
Spring 2.0   良信林(冊手術技              – http://openhome.cc     )

<?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.apache.commons.dbcp.BasicDataSource"
            destroy-method="close">
          <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="userDAO"
           class="onlyfun.caterpillar.UserDAO">
         <property name="dataSource" ref="dataSource"/>
    </bean>
</beans>


                         是的用使所在現
                         org.apache.commons.dbcp.BasicDataSource            作
     在要需您,能功的   用使了為,例實
            DataSource        的入注為          DBCP                     Classpath
         與        、          定設中徑路
              commons-dbcp.jar          c ommons-pool.jar    commonscollec-
    。到找下錄目 的中本版依相的
tions.jar              在以可都些這, Spring                 lib

 確以可此如,性屬         了定設上
                  dataSource在到意注         "destroy-method"
         。
     BeanFactory 閉關併一也時閉關在       保        BasicDataSource

)                ( 了供提器容
            Servlet           果如  JNDI    J ava Naming and Directory Interface
           :
     DataSource個這上換的單簡以可也,       的           DataSource




16
Chapter 5 JDBC      援支易交、

...
<bean id="dataSource"
     class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc/demo"/>
</bean>
...


    用使了為        org.springframework.indi.JndiObjectFactoryBean 需您,
  要              ,
  spring-context.jar " jndiName"   的定設所據根要上際實           JNDI   ,稱名詢查
在如例    Tomcat   於以可中     server.xml    :定設麼這
...
<!—-  是錄目式程用應設假        JSP -->
<Context path="/JSP" docBase="JSP">
     <!--
     是稱名庫料資用使             GUESTBOOK -->
     <Resource name="jdbc/demo" scope="Shareable"
                type="javax.sql.DataSource"/>
     <ResourceParams name="jdbc/demo">
          <parameter>
              <name>factory</name>
              <value>
                 org.apache.commons.dbcp.BasicDataSourceFactory
              </value>
          </parameter>

        <!-- DBCP database connection settings -->
        <!-- JDBC URL -->
        <parameter>
           <name>url</name>
           <value>jdbc:mysql://localhost/demo</value>
        </parameter>
        <!-- JDBC  式程動驅   -->
        <parameter>
             <name>driverClassName</name>
             <value>com.mysql.jdbc.Driver</value>
        </parameter>
        <!-- 碼密與者用使庫料資        -->
        <parameter>
             <name>username</name>
             <value>caterpillar</value>



                                                                   17
Spring 2.0   良信林(冊手術技       – http://openhome.cc    )

        </parameter>
        <parameter>
            <name>password</name>
            <value>123456</value>
        </parameter>

        <!-- DBCP connection pooling options -->
        <!--  待等  Connection
                           制限不表 , 位單,間時的ms -1        -->
        <parameter>
             <name>maxWait</name>
             <value>3000</value>
        </parameter>
        <!-- 可多最中池接連       idle
                              ,數 Connection
                                       的
               的少最是就也   Connection
                               制限不表 ,數0       -->
        <parameter>
             <name>maxIdle</name>
             <value>10</value>
        </parameter>
        <!--  的多至池接連     Connection     0
                                    制限不示表 ,數     -->
        <parameter>
             <name>maxActive</name>
             <value>100</value>
        </parameter>
    </ResourceParams>
</Context>
...




18
Chapter 5 JDBC         援支易交、

5.2 JDBC 支援
用使在           JDBC 如例,節細的瑣繁理處要是總,時                                     、
                                                          Connection S tatement
 、得獲的                、
         S QLException     、理處的        C onnection    S tatement   ,題問等閉關的
 在
Spring      JDBC   化簡以可,別類個幾了供提上用使的                        JDBC    。程流的時用使

5.2.1 使用 JdbcTemplate

使接直中          ,中案專                  的紹 介 中 節 小 個 一 前 在
                               DataSourceDemo                U serDAO
、得取的
  JDBC          理處要中當,法方
                   insert()   find()與        作實來        用   Connection
,等 閉關的
Statement        、閉關的          、理處的外例、立建的
                                   S tatement             C onnection
這 作須必 都 次 一 每 , 的 異 小同大 是 程 流 些 這 , 取 存
                   JDBC                     的本基個一於對
                                      。煩厭 人 令 實 著 程 流 的 樣
類   Spring                                了供提
                         org.springframework.jdbc.core.JdbcTemplate
法 方作操 些 一 的 供 提 所 中 當 , )         ( 全 安緒行 執 為 計 設 被 它 , 別
                                T hread-safe
可別類          的中案專                  如例,程流的上以似類了裝封
                                DataSourceDemo                     UserDAO
須必,例實的                 立建要,寫改來
                JdbcTemplate                  用使的單簡以 JdbcTemplate
                     :件 物 的 時 構 建 為 作 件 物
            DataSource                            個一有要
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);


到看以可,作實容內的             中案專
                   DataSourceDemo         下一寫改來UserDAO
    : 進 改 的 樣 麼 什 有會上 程 流 寫 撰 的 式 程 在 , 時
    JdbcTemplate                                用使




                                                                                  1
Spring 2.0     良信林(冊手術技          – http://openhome.cc      )

     JdbcTemplateDemo                                          UserDAO.java
    package onlyfun.caterpillar;

    import   java.util.Iterator;
    import   java.util.List;
    import   java.util.Map;
    import   javax.sql.DataSource;
    import   org.springframework.jdbc.core.JdbcTemplate;

    public class UserDAO implements IUserDAO {
        private JdbcTemplate jdbcTemplate;

        public void setDataSource(DataSource dataSource) {
            jdbcTemplate = new JdbcTemplate(dataSource);
        }

        public void insert(User user) {
           String name = user.getName();
           int age = user.getAge().intValue();

             jdbcTemplate.update("INSERT INTO user (name,age) "
                     + "VALUES('" + name + "'," + age + ")");
        }

        public User find(Integer id) {
            List rows = jdbcTemplate.queryForList(
              "SELECT * FROM user WHERE id=" + id.intValue());

             Iterator it = rows.iterator();
             if(it.hasNext()) {
                 Map userMap = (Map) it.next();

                 Integer i = new Integer(userMap.get("id").toString());
                 String name = userMap.get("name").toString();
                 Integer age =
                       new Integer(userMap.get("age").toString());

                 User user = new User();
                 user.setId(i);
                 user.setName(name);
                 user.setAge(age);



2
Chapter 5 JDBC     援支易交、

               return user;
          }

          return null;
    }
}


,動變用不都檔定設與式程的它其,了以可就     寫改要只
                   UserDAO
Spring  由藉是要主,的示所稱名其如一
            JdbcTemplate   的                                       Template Method
                。裝封程流理處的
              JDBC        現實來式模

          用使果如     Hibernate)            ( 的類之
                                          ORM    O bject-Relational Mapping
          則,具 工    find()    一進以可還換轉的型模式聯關與型模件物中法方
         。化簡的步
了除,用使來
    Spring       於立獨以可上本基能功等裝封
                   JDBC                        的             Spring
對是像,別類
JdbcTemplate         的它其了供提還S pring      ,外之             Template
, 面方理 處 易 交 的 庫 料 資 在 。 現 實
Hibernate     J DO    i Batis     的等 、 、
                                      Template
雜 複的式 程 層 久 持 了 化 簡 ,能功 理 管 易 交 的 式 告 宣 與 式 程 編 了 供 提
Spring
                                  。 性 護維的 好 更 了 供 提 並 , 度

5.2.2 JdbcTemplate 執行與更新

    用使以可您            JdbcTemplate     的   execute()   行執法方    SQL    :如例,述陳
jdbcTemplate.execute(
     "CREATE TABLE USER (user_id integer, name varchar(100))");


是果如                用使以可您,
              UPDATE      或     INSERT                  update()   重個數有它,法方
   (載   Overload   作實受接如例,本版)                           org.springframework.jdbc.



                                                                                 21
Spring 2.0   良信林(冊手術技             – http://openhome.cc    )

core.PreparedStatementCreator      ,件物的面介        P reparedStatementCreator      介
:下如義定的面
package org.springframework.jdbc.core;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public interface PreparedStatementCreator {
    PreparedStatement createPreparedStatement(Connection con)
        throws SQLException;
}


將以可如例             5.2.1   的   JdbcTemplateDemo   中案專   UserDAO   的   insert()   方
 :下如寫改法
...
public void insert(User user) {
    final String name = user.getName();
    final int age = user.getAge().intValue();

      jdbcTemplate.update(
        new PreparedStatementCreator() {
            public PreparedStatement createPreparedStatement(
                    Connection con) throws SQLException {
               String sql =
                   "INSERT INTO user (name,age) VALUES(?,?)";
               PreparedStatement ps =
                            con.prepareStatement(sql);
               ps.setString(1, name);
               ps.setInt(2, age);
               return ps;
            }
        });
}
...




22
Chapter 5 JDBC         援支易交、

            備準 來            了用 使,中子例個 這在
                              PreparedStatement             SQL   ,   J dbcTemplate
而,程流       了現實中法 方      ,制機
          Template-Callback            了現實
                                     u pdate()                Template
,中程流的     行執在,件物
PreparedStatementCreator了現 實則         Callback                  JDBC
方                是就也, 法 方      的義 定所行執會時 要必
                         callback                 createPreparedStatement()
     的中 法 方      成完以,件 物
                PreparedStatement   個一回傳 ,法        update()               Template
                                       。 程流
                是面介的補互
          PreparedStatementCreator     與           org.springframework.jdbc.
                      :面介
core.PreparedStatementSetter


package org.springframework.jdbc.core;

import java.sql.PreparedStatement;
import java.sql.SQLException;

public interface PreparedStatementSetter {
    void setValues(PreparedStatement ps) throws SQLException;
}


       將以可如例      JdbcTemplateDemo   中案專     UserDAO   的   insert()   :下如寫改法方
...
public void insert(User user) {
    final String name = user.getName();
    final int age = user.getAge().intValue();

      jdbcTemplate.update(
         "INSERT INTO user (name,age) VALUES(?,?)",
         new PreparedStatementSetter() {
                public void setValues(PreparedStatement ps)
                                       throws SQLException {
                   ps.setString(1, name);
                   ps.setInt(2, age);
                }
            });
}
...



                                                                                  23
Spring 2.0   良信林(冊手術技              – http://openhome.cc     )

  立建動自會JdbcTemplate                 PreparedStatementCreator    供提以,例實的
     的法方    給遞傳
          setValues()          PreparedStatement      。件物
如就, 供提接直以可也您                 SQL          JdbcTemplateDemo      的範示所中案專
   :法方
UserDAO  的中      insert()


...
public void insert(User user) {
    String name = user.getName();
    int age = user.getAge().intValue();

      jdbcTemplate.update("INSERT INTO user (name,age) "
              + "VALUES('" + name + "'," + age + ")");
}
...


陣 件 物 用 使 並, 元 字 位 佔 為 作 用 使 以 可 也 , 時 句 語 下 接 直 在
                SQL                          "?"
           寫改如例,法方           的
                        JdbcTemplate      給遞 傳 數 引 為 作 列
                                        update()                  JdbcTemplate-
Demo             :法方       的中
                            UserDAO     的範示所中案專
                                           insert()


...
public void insert(User user) {
    jdbcTemplate.update(
        "INSERT INTO user (name, age) VALUES(?,?)",
        new Object[] {user.getName(), user.getAge()});
}
...


       JdbcTemplate   與            立建動自會
                                       PreparedStatementCreator       Prepared-
StatementSetter   數引與 供提要只,會理用不您節細些這而然,例實的                          SQL
            。了好就
作實以可,時理處次批要需果如                           org.springframework.jdbc.core.Batch-
  :面介
PreparedStatementSetter




24
Chapter 5 JDBC   援支易交、

package org.springframework.jdbc.core;

import java.sql.PreparedStatement;
import java.sql.SQLException;

public interface BatchPreparedStatementSetter {
    void setValues(PreparedStatement ps,
                      int i) throws SQLException;
    int getBatchSize();
}


在以可 如例            JdbcTemplateDemo    及面介            的中 案 專
                                               IUserDAO       UserDAO
個一加增上別類           insertUsers()   : 容 內 的 下 以 是 像 ,作 實 與 義 定 的 法 方
...
public int[] insertUsers(final List users) {
    String sql = "INSERT INTO user (name,age) VALUES(?,?)";
    BatchPreparedStatementSetter setter =
      new BatchPreparedStatementSetter() {
         public void setValues(
             PreparedStatement ps, int i) throws SQLException {
             User user = (User) users.get(i);
             ps.setString(1, user.getName());
             ps.setInt(2, user.getAge().intValue());
         }
         public int getBatchSize() {
             return users.size();
         }
      };

      return jdbcTemplate.batchUpdate(sql, setter);
}
...


 果如        JDBC   果如 , 能 功 的 它 用 使 接直則 , 話 的 理 處 次 批 援 支 式 程 動 驅
則,援支不        Spring       。 理 處 次 批 擬 模以新 更 理 處 個 一 個 一 動 自 會


                                                                        2
Spring 2.0      良信林(冊手術技           – http://openhome.cc   )

5.2.3 JdbcTemplate 查詢

用使         JdbcTemplate             用使以可,時詢查行進       queryForXXX()   ,法方等
用使如例       queryForInt()       :數筆料資的中格表 回傳法方
                                        user


jdbcTemplate.queryForInt("SELECT COUNT(*) FROM user");


 用使以可也                 queryForObject()   回傳 如 例 , 件 物 果 結 的 後 詢 查 個 一 回 傳
:件物    個一
       String


String name = (String) jdbcTemplate.queryForObject(
              "SELECT name FROM USER WHERE id = ?",
               new Object[] {id},
               java.lang.String.class);


使以可則,料資筆多回傳果如,料資筆一單是都的回傳子例個兩面上
                  :如例,法方
     queryForList()            用
List rows = jdbcTemplate.queryForList(
           "SELECT * FROM user WHERE id=" + id.intValue());


的中果結詢查表代件物 個每,件物 是的括包中 的回傳
                List              Map              Map
位欄用使要,值的中位欄得取要,容內位欄個多括包料資筆每,料資筆一
           "      :如例, ) (鍵 為作稱名
                  K ey     "


...
Iterator it = rows.iterator();
while(it.hasNext()) {
    Map userMap = (Map) it.next();
    System.out.println(userMap.get("id"));
    System.out.println(userMap.get("name"));
    System.out.println(userMap.get("age"));
    ...
}
...


26
Chapter 5 JDBC   援支易交、

                    作實以可您
                     org.springframework.jdbc.core.RowCallbackHandler      介
下一改修如例,回傳再理處些一作先後之料資到詢查在,面                                         5.2.1   的
  在,下如法方   的
JdbcTemplateDemo中案專          UserDAO       find()            RowCallback-
    (
Handler 的單簡作實中法方       的
              processRow()                          ORM   O bject-Relational
Mapping             :作動)
...
public User find(Integer id) {
    final User user = new User();
    jdbcTemplate.query(
       "SELECT * FROM user WHERE id = ?",
       new Object[] {id},
         new RowCallbackHandler() {
            public void processRow(ResultSet rs)
                                    throws SQLException {
                user.setId(new Integer(rs.getInt("id")));
                user.setName(rs.getString("name"));
                user.setAge(new Integer(rs.getInt("age")));
            }
        });

      return user;
}
...


      作實先以可則,件物的果結詢查多很回取要次一果如                             org.springframe-
             :如例,面介
work.jdbc.core.RowMapper


package onlyfun.caterpillar;

import java.sql.ResultSet;
import java.sql.SQLException;

import org.springframework.jdbc.core.RowMapper;

public class UserRowMapper implements RowMapper {

      public Object mapRow(ResultSet rs,



                                                                           27
Spring 2.0   良信林(冊手術技             – http://openhome.cc   )

                           int rowNum) throws SQLException {
          User user = new User();
          user.setId(new Integer(rs.getInt("id")));
          user.setName(rs.getString("name"));
          user.setAge(new Integer(rs.getInt("age")));

          return user;
      }
}



     在    Spring 2.0   ,中           詢查,除移被經已別類作實其與面介
                            R esultReader
受接接直在現法方               RowMapper    :時法方       用使如例,例實
                                                queryForObject()

...
      public User find(Integer id) {
          User user = (User) jdbcTemplate.queryForObject(
                  "select * from user where id=?",
                  new Object[] {id},
                  new UserRowMapper());

          return user;
      }
...


       用使已果結的回傳             UserRowMapper   為裝封之將,義定的          User   。件 物
:範示個一的時法方   用使是下以
              query()


List users = jdbcTemplate.query("select * from user",
                new UserRowMapper());

for(int i = 0; i < users.size(); i++) {
    User user = (User) users.get(i);
    System.out.println("tId:t" + user.getId());
    System.out.println("tName:t" + user.getName());
    System.out.println("tAge:n" + user.getAge());
}




28
Chapter 5 JDBC     援支易交、

       為 裝封 已 並,果 結 的 來出詢 查 中 庫 料 資 從 了 括 包,中 件 物 的 回 傳
             List
User                                           。例實的別類

5.2.4 JdbcTemplate 的 Lob 支援

        ( 與
         J DBC)                   ( 用使以可中 在
                             C lob C haracter large object   B lob B inary large
透以可中
object      。存儲行進案檔位進二與案檔字文對針別分以,)                            S pring
如 例(庫 料 資 定 特 理 處 免 避 以 ,
   JdbcTemplate                與
                             CLOB     理處來
                                       BLOB     過
資      的 您 設 假 , 說 來 子 例 個 舉 。 題 問 異 差 、 的)
Oracle 9i        Clob    B lob                                      MySQL
                                          :下如格表庫料
CREATE TABLE test (
    id INT AUTO_INCREMENT PRIMARY,
    txt TEXT,
    image BLOB
);


料資至存儲之將想並,案檔位進二與案檔字文個一進讀別分在現設假
              :如例,      用使以可則,中庫
                        JdbcTemplate
final File binaryFile = new File("wish.jpg");
final File txtFile = new File("test.txt");

final InputStream is = new FileInputStream(binaryFile);
final Reader reader = new FileReader(txtFile);

JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

final LobHandler lobHandler = new DefaultLobHandler();

jdbcTemplate.execute("INSERT INTO test (txt, image) VALUES(?, ?)",
  new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
     protected void setValues(PreparedStatement pstmt,
       LobCreator lobCreator) throws SQLException,DataAccessException {
         lobCreator.setClobAsCharacterStream(
                pstmt, 1, reader, (int) txtFile.length());



                                                                                   2
Spring 2.0   良信林(冊手術技                – http://openhome.cc          )

         lobCreator.setBlobAsBinaryStream(
                pstmt, 2, is, (int) binaryFile.length());
     }
 });
reader.close();
is.close();


,時件物                                    立建在
             AbstractLobCreatingPreparedStatementCallback
   或        (      於對,例實
             LobHandler                 個一遞傳要  MySQL     M S SQL Server           Oracle
  的定特
10g        於對,可即                   用使邊這,)
                         DefaultLobHandler                      Oracle 9i          LOB
用使,中作實法方       在。   OracleLobHandler用使以可,理處          setValues()
與一第示表 、 引索,流串源來的 與 定設別分來
LogCreator                    Blob      Clob                           1    2
             。度 長 取 讀 定 指 並 , 置 位 的 元 字 位 佔 個 二 第
                  ' ?'


的下以用使以可,案檔為存另並,來出取讀料資將中庫料資從要果如
                             :式程
final Writer writer = new FileWriter("test_bak.txt");
final OutputStream os = new FileOutputStream(new File(wish_bak.jpg"));

jdbcTemplate.query("SELECT txt,image FROM test WHERE id = ?",
   new Object[] {new Integer(1)},
   new AbstractLobStreamingResultSetExtractor() {
      protected void streamData(ResultSet rs)
             throws SQLException, IOException, DataAccessException {
          FileCopyUtils.copy(
                 lobHandler.getClobAsCharacterStream(rs, 1), writer);
          FileCopyUtils.copy(
                 lobHandler.getBlobAsBinaryStream(rs, 2), os);
      }
  });
writer.close();
os.close();


  用使邊這在            FileCopyUtils        的   copy()   將,法方   LogHandler          流串的得取
出輸案檔給接轉接直                  FileWriter   、   F ileOutputStream   。件物

3
31
                             sf.run();
                             sf.compile();
                                 dataSource, "SELECT COUNT(*) from user");
                             SqlFunction sf = new SqlFunction(
           : 子 例 個 一是面 下 , 數 筆 料 資 的 到詢查 示 表 數 整 個 一 傳 回
 後然,     COUNT()
           行執以可如例,                   SQL Function
                                    行執來用                     SqlFunction
                                                 。例 實的
 別類些這用使複重下境環的緒行執多在以可以所,)                       (全安緒行   T hread-safe
 執為計設被們它,別類等                 org.springframework.jdbc.object.MappingSqlQuery
 、   org.springframework.jdbc.object.SqlUpdate
                                 類 子其用使 以可您,作操 等序
 程存 預、新更、詢 查的 )             R elational Database Management System
                                                (                       RDBMS
 表代,類象抽個是            org.springframework.jdbc.object.RdbmsOperation
                                           。作操關相庫料
 資行進來法方的它行執,例實個這用利複重以可就後之,譯編並別類的應
 對相化例實接直或承繼先事要只,式程的面方作操庫料資計設來式方的向
 導件物更以您讓,件套                org.springframework.jdbc.object
                                           供提                         Spring
                                       。 式方作操的向 導件
 物近接更 作操庫料資, 看來點觀 的們他從,節 細的 到 觸接須無就 們他                SQL
 ,用使員人發開給件物用重可的成完計設些這將,時計設庫料資行進在後之
 立建, 件物作操的用 重可立建步一進以 可您, 中              在 , 些某 用重   Spring     SQL
              SQL
 是或,法語 到觸接用不員人發開式程些一讓想果如,法語 用使何                                   SQL
 如悉熟須仍法方 個各的               JdbcTemplate
                           而然,術 技庫料資 的層底觸接用 不您
 讓,節細 的理 處          JDBC
                了裝 封它,看來法 方個各 的 上                  就    JdbcTemplate
                                          5.2.5 以物件方式進行操作
 援支易交、       Chapter 5 JDBC
Spring 2.0   良信林(冊手術技          – http://openhome.cc    )

數參關相及以 、
     RdbmsOperation        好定設在別類子的       DataSource   S QL
在 ,例實 個 這 用 使 複 重 以 可 就 後 之 , 譯 編 行 進
                 compile()                    行執 先 須 必 , 後
          中 改修如例, 裝封來
                 SqlFunction        SQL       承繼以可時計設
                                                   5.2.1      JdbcTemplate-
Demo                  :示 所 下 如 別 類 個 一 增 新 , 容 內 的 案 專
  RdbmsDemo                                            UserFunction.java
 package onlyfun.caterpillar;

 import javax.sql.DataSource;

 import org.springframework.jdbc.object.SqlFunction;

 public class UserFunction extends SqlFunction {
     public UserFunction(DataSource dataSource) {
         super(dataSource, "SELECT COUNT(*) from user");
         compile();
     }
 }



參關相定設以可也您,作操新更的 個一示表來用別類
     SqlUpdate                    SQL
         : 如 例 , 裝 封 的 行 進 來 它承繼 以 可 也 時 計 設 , 數
                                 SQL


  RdbmsDemo                                                UserUpdate.java
 package onlyfun.caterpillar;

 import java.sql.Types;

 import javax.sql.DataSource;

 import org.springframework.jdbc.object.SqlUpdate;

 public class UserUpdate extends SqlUpdate {
     public UserUpdate(DataSource dataSource) {
         super(dataSource,
                "INSERT INTO user (name,age) VALUES(?,?)");
         int[] types = {Types.VARCHAR, Types.INTEGER};



32
Chapter 5 JDBC   援支易交、

          setTypes(types);
          compile();
      }
}



,型 類 據 數 的 入 插 要 所 元 字 位 佔 中 定 設 來 用 法 方
      setTypes()               SQL   "?"
每 ,詢查 行 進 來 數 引 為 作 列陣件 物 定 指 僅 以 可 , 時 法 方
           update()                               行執後之
           : 用 使 麼 這 以 可 如 例 , 元 字 位 佔 代取 際 實 將 值 列 陣 個 一
                        "?"


...
      SqlUpdate userUpdate = new UserUpdate(dataSource);
      ...
      userUpdate.update(
          new Object[] {user.getName(), user.getAge()});


,別類個這用使接直少很常通但,作操詢查 個一示表別類
      SqlQuery                SQL
以可,例實的別類 為裝封如例,理處些一作會,後之料資到詢查為因                   User
來                          別類子的它用使
                   org.springframework.jdbc.object.MappingSqlMapping
                      :如 例 , 作 動 個 這 行 進
    RdbmsDemo                                              UserQuery.java
package onlyfun.caterpillar;

import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.DataSource;

import org.springframework.jdbc.object.MappingSqlQuery;

public class UserQuery extends MappingSqlQuery {
    public UserQuery(DataSource dataSource) {
        super(dataSource, "SELECT * FROM user");
        compile();
    }

      protected Object mapRow(ResultSet rs,



                                                                        33
Spring 2.0   良信林(冊手術技        – http://openhome.cc    )

                                    int rowNum) throws SQLException {
          User user = new User();

          user.setId(new Integer(rs.getInt("id")));
          user.setName(rs.getString("name"));
          user.setAge(new Integer(rs.getInt("age")));

          return user;
      }
 }



      : 它 用 使 麼 這 以 可,後 之 別 類 個 這 好 計 設
...
SqlQuery userQuery = new UserQuery(dataSource);
...
List users = userQuery.execute();


的回傳上際實,後法方   execute()    完行執              List   有會中   User   ,例實的別類
     。 料 資 筆 一 每的後 詢 查 了 裝 封 並 中 當
下 一 寫 改 再 以 可,作 實 個 幾 的 上 以 合 配             IUserDAO    與面介     UserDAO
                       :如例,作實
     RdbmsDemo                                            IUserDAO.java
 package onlyfun.caterpillar;

 import java.util.List;

 public interface IUserDAO {
     public void insert(User user);
     public List allUser();
     public int count();
 }




34
Chapter 5 JDBC     援支易交、

程的面方取存庫料資責負員人發開的他其有,員人發開式程是您設假
您 則,別 類   與     、      的 上 以 了 供 提 並,式
                    UserFunction   U serUpdate   UserQuery
        、   用重以可,寫撰何如是 的際實心關用不就
                  SQL                        UserFunction    U serUpdate
            :別類
    UserQuery      的您計設來別類           與
                               UserDAO

    RdbmsDemo                                             UserDAO.java
package onlyfun.caterpillar;

import java.util.List;

import javax.sql.DataSource;

import org.springframework.jdbc.object.SqlFunction;
import org.springframework.jdbc.object.SqlQuery;
import org.springframework.jdbc.object.SqlUpdate;

public class UserDAO implements IUserDAO {
    private SqlUpdate userUpdate;
    private SqlQuery userQuery;
    private SqlFunction userFunction;

     public void setDataSource(DataSource dataSource) {
         userUpdate = new UserUpdate(dataSource);
         userQuery = new UserQuery(dataSource);
         userFunction = new UserFunction(dataSource);
     }

     public void insert(User user) {
         userUpdate.update(
           new Object[] {user.getName(), user.getAge()});
     }

     public List allUser() {
         return userQuery.execute();
     }

     public int count() {
         return userFunction.run();
     }
}



                                                                           3
Spring 2.0   良信林(冊手術技         – http://openhome.cc        )

物是 全 完 , 看 來 度 角 的 寫 撰 式 程
          SQL              從,後之用重裝封 將
                                  UserDAO
作運看看來式程的單簡個寫以可,改修的式程合配,行進來式方的作操件
                                   :常正否是
     RdbmsDemo                                          SpringDAODemo.java
 package onlyfun.caterpillar;

 import org.springframework.context.ApplicationContext;
 import org.springframework.context.
               support.ClassPathXmlApplicationContext;
 import java.util.List;

 public class SpringDAODemo {
     public static void main(String[] args) {
         ApplicationContext context =
             new ClassPathXmlApplicationContext(
                     "beans-config.xml");

           User user = new User();
           user.setName("just933");
           user.setAge(new Integer(26));

           IUserDAO userDAO =
               (IUserDAO) context.getBean("userDAO");

           userDAO.insert(user);

           System.out.println("   數筆   : " + userDAO.count());

           List list = userDAO.allUser();
           for(int i = 0; i < list.size(); i++) {
               User next = (User) list.get(i);
               System.out.println("ntId:t" + next.getId());
               System.out.println("tName:t" + next.getName());
               System.out.println("tAge:t" + next.getAge());
           }
      }
 }




36
Chapter 5 JDBC     援支易交、


                 、
              UserDAO        、          的中
                                 UserUpdate         麼什為
                                              U serQuery   U serFunction
      觀 個 一 有 還,外 之 作 實 例 範 化 簡 了 除 ? 呢 入 注 賴 依 用 使 不 等
               IoC
      依 個 來 要 都 一 十 二 七 三 管 不 件 物 個 每 ! 而 了 為 要 不:念
                     IoC    IoC
            的 長 冗 堆 大 一 有 會 將,上 件 物 的 賴 依 入 注 被,話 的 入 注 賴        Setter
      ,時賴依的同相入注要需件物的上以個兩有,是的議建。法方
                    。入注賴依行進來器容
                    Spring IoC                  用使慮考才

5.2.6 DataFieldMaxValueIncrementer
與是好最置設的鍵主,鍵主定設要需會您,時中庫料資至料資入插在
             用使以可您,中   在,關無值鍵務商
                        Spring                     org.springframework.jdbc.
,值鍵主生產您為來
support.incrementer.DataFieldMaxValueIncrementer
如例,例實的庫料資同不對針多許有
DataFieldMaxValueIncrementer
    、            、
DB2SequenceMaxValueIncrementer H sqlMaxValueIncrementer M ySQL-
    、
MaxValueIncrementer  、     OracleSequenceMaxValueIncrementer          Postgre-
、        的它作操以可您,
SQLSequenceMaxValueIncrementer                               nextIntValue()
      。值鍵主個一下生產來
nextLongValue()        或
                     nextStringValue()




5.2.7 Spring 2.0 的 NamedParameterJdbcTemplate

您讓,別類  Spring 2.0                了增新中            在
                                 NamedParameterJdbcTemplate
名命的際實用使是而, 元字位佔用使必不,時述陳 的
       JDBC       SQL                            寫撰在' ?'
您本原 如 例 , 份 部 料 資 的 動 變 會 中 留 保 來 )
      N amed parameter                SQL        (數參
                                    :詢 查 個 一 寫 撰 麼 這 是
String sql = "SELECT * FROM user WHERE id=?";
List rows = jdbcTemplate.queryForList(sql,
          new Object[] {id.intValue()});


                                                                              37
Spring 2.0   良信林(冊手術技        – http://openhome.cc         )

     用使以可在現        NamedParameterJdbcTemplate             :式方的下以為寫改
String sql = "SELECT * FROM user WHERE id=:userId";
SqlParameterSource namedParameters =
        new MapSqlParameterSource("userId", id);

NamedParameterJdbcTemplate jdbcTemplate =
                new NamedParameterJdbcTemplate(dataSource);
List rows = jdbcTemplate.queryForList(sql, namedParameters);

用使是邊這在,式方定指的值際實       ":userId"  數參名命到意注
以可也您。值際實與數參名命定指接直時構建在,
SqlParameterSource
     Map : 如 例,值 際 實 的 數 參 名 命 個 多 定 指 來 件 物 用 使
String sql = "INSERT INTO user (name,age) VALUES(:userName, :userAge)";
Map namedParameters = new HashMap();
namedParameters.put("userName", name);
namedParameters.put("userAge", age);

NamedParameterJdbcTemplate jdbcTemplate =
                new NamedParameterJdbcTemplate(dataSource);
jdbcTemplate.update(sql, namedParameters);

個一據根以可也您              POJO   (   P lain Old Java Object   名命為作值的件物)
:如 例 , 據 依 的 值 數 參
String sql = "INSERT INTO user (name,age) VALUES(:name, :age)";
SqlParameterSource namedParameters =
           new BeanPropertySqlParameterSource(user);
NamedParameterJdbcTemplate jdbcTemplate =
                new NamedParameterJdbcTemplate(dataSource);
jdbcTemplate.update(sql, namedParameters);

 中其     " user"   是件物的考參所        JdbcTemplateDemo    。例實 的中案專 User
將體具下以                        的案專
              JdbcTemplateDemo              UserDAO  用使為寫改,別類
NameParameterJdbcTemplate     :式方的



38
Chapter 5 JDBC   援支易交、

 NamedParameterDemo                                      UserDAO.java
package onlyfun.caterpillar;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.jdbc.core.namedparam
                        .BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam
                        .MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam
                        .NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;

public class UserDAO implements IUserDAO {
    private NamedParameterJdbcTemplate jdbcTemplate;

    public void setDataSource(DataSource dataSource) {
        jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
    }

    public void insert(User user) {
       String sql = "INSERT INTO user (name,age) VALUES(:name, :age)";
       SqlParameterSource namedParameters =
           new BeanPropertySqlParameterSource(user);

         jdbcTemplate.update(sql, namedParameters);
    }

    public User find(Integer id) {
        String sql = "SELECT * FROM user WHERE id=:userId";
        SqlParameterSource namedParameters =
                 new MapSqlParameterSource("userId", id);
        List rows = jdbcTemplate.queryForList(sql, namedParameters);

         Iterator it = rows.iterator();
         if(it.hasNext()) {
             Map userMap = (Map) it.next();

             Integer i = new Integer(userMap.get("id").toString());



                                                                         3
Spring 2.0       良信林(冊手術技        – http://openhome.cc   )

                  String name = userMap.get("name").toString();
                  Integer age =
                        new Integer(userMap.get("age").toString());

                  User user = new User();
                  user.setId(i);
                  user.setName(name);
                  user.setAge(age);

                  return user;
             }

             return null;
         }
    }




5.2.8 Spring 2.0 的 SimpleJdbcTemplate

中      用利以可則,本版的上以 是 的用使您果如
                        JDK      5.0                         Spring 2.0
這是能可您來原如例,能功)   (型泛的供提所
SimpleJdbcTemplate                     G eneric
                        :料資詢查麼
public User find(Integer id) {
   String sql = "SELECT * FROM user WHERE id=?";

        RowMapper mapper = new RowMapper() {
             public Object mapRow(ResultSet rs, int rowNum)
                                                  throws SQLException {
                 User user = new User();
                 user.setId(new Integer(rs.getInt("id")));
                 user.setName(rs.getString("name"));
                 user.setAge(new Integer(rs.getInt("age")));
                 return user;
             }
         };

        JdbcTemplate simpleJdbcTemplate =
              new JdbcTemplate(this.getDataSource());




4
Chapter 5 JDBC     援支易交、

     return (User) jdbcTemplate.queryForObject(sql, mapper, id);
}

     用改若        SimpleJdbcTemplate   :寫撰下如以可則,
public User find(Integer id) {
   String sql = "SELECT * FROM user WHERE id=?";

    ParameterizedRowMapper<User> mapper =
     new ParameterizedRowMapper<User>() {
         public User mapRow(ResultSet rs, int rowNum)
                                              throws SQLException {
             User user = new User();
             user.setId(new Integer(rs.getInt("id")));
             user.setName(rs.getString("name"));
             user.setAge(new Integer(rs.getInt("age")));
             return user;
         }
     };

     SimpleJdbcTemplate simpleJdbcTemplate =
         new SimpleJdbcTemplate(this.getDataSource());

     return simpleJdbcTemplate.queryForObject(sql, mapper, id);
}

在接直以可,能功的型泛到用使中當,到意注以可                                   mapRow()之法方
     的   User  而,例實 回傳後 SimpleJdbcTemplate    queryForObject()   以可也法方
     將下以。例實   的果結詢查回傳接直   User                 JdbcTemplateDemo  的案專
 :式方的
UserDAO        用使為寫改     SimpleJdbcTemplate


    SimpleJdbcTemplateDemo                                 UserDAO.java
package onlyfun.caterpillar;

import   java.sql.ResultSet;
import   java.sql.SQLException;
import   javax.sql.DataSource;
import   org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import   org.springframework.jdbc.core.simple.SimpleJdbcTemplate;




                                                                        41
Spring 2.0    良信林(冊手術技          – http://openhome.cc    )

 public class UserDAO implements IUserDAO {
     private SimpleJdbcTemplate jdbcTemplate;

     public void setDataSource(DataSource dataSource) {
         jdbcTemplate = new SimpleJdbcTemplate(dataSource);
     }

     public void insert(User user) {
         String sql = "INSERT INTO user (name,age) VALUES(?, ?)";
         String name = user.getName();
         Integer age = user.getAge();

             jdbcTemplate.update(sql, new Object[] {name, age});
         }

     public User find(Integer id) {
         String sql = "SELECT * FROM user WHERE id=?";

             ParameterizedRowMapper<User> mapper =
                new ParameterizedRowMapper<User>() {
                  public User mapRow(ResultSet rs, int rowNum)
                                                  throws SQLException {
                      User user = new User();
                      user.setId(new Integer(rs.getInt("id")));
                      user.setName(rs.getString("name"));
                      user.setAge(new Integer(rs.getInt("age")));
                      return user;
                  }
             };

             return jdbcTemplate.queryForObject(sql, mapper, id);
     }
 }




42
43
                                                          :如例
 ,行執的有所消撤來              rollback()
                             行執 則 , 誤 錯 生 發間中 果 如 , 更 變 出 送 來
 commit()的      Connection
                     行執行自,後句語 的串連一達下在,數引       SQL                           false
 它 定 給,法 方       setAutoCommit()
                            的        Connection
                                         作 操 以 可,中        在,現      JDBC
 實性 子 原 的 易 交 看 看 來先首 。 理 管 易 交 用 使 何 如         紹介將邊這在JDBC
                                       。 的 來下錄 記 被 是 須 必 易 交 筆
 這,後之易交筆一某在,)                 D urable
                               (的續持可是須必還易交。在存的此彼
 到識意需不上本基易交個兩,作動的款提與款存行進時同易交筆兩有能可
        A
 中戶帳 在如例,)               I solated
                           ( 的 離 隔 是 須 必 間 之此 彼 易 交 個 每 。 額 金 的
            A                             B
 款 存 戶 帳 於 大 能 不 額 金 的 款 取 戶 帳 ,額 金 帳 轉的 戶 帳個 兩 ,中 子 例 的
 戶帳行銀在如例,)             C onsistent
                           (性致一的源資與參所持保須必還易交
                             。 敗 失 帳 轉 次 此 則,敗 失 作 動 個 一 有 果 如
 ,功成須必作動個兩,額金的帳轉上加戶帳的行銀 在、款扣戶帳的行銀                     B                         A
                          B
 從為作動的作要,行銀 至帳轉行銀 從戶客個一,子例的單簡個舉           A
            SQL
 。消撤令指 的過行執有所前先則, 誤錯有 行一中其如例(因原個 )                   SQL
                                         SQL
 某為因 若 , 功 成 行 執 部 全 須 必 令 指 組 一 這 , 令 指 組 一 是 就 , 說         SQL
 來 例 實 的 取 存 庫 料 資 以 , 元 單 作 工 的 作 操)           A tomic
                                            (子 原 組 一 是 易 交
                                           5.3.1 Spring 對交易的支援
                                                。理管易交的                    Spring
 紹介,例為易交           JDBC   以 節這, 型 模 程 編 的 致 一 了供提 作 實 易 交 的 同 不 為
 ,)  D eclarative transaction management (理管易交的式告宣與)                       ment
 P rogrammatic transaction manage-  (理 管易 交 的式 程編供提                 Spring
                                               5.3 JDBC 交易管理
 援支易交、      Chapter 5 JDBC
Spring 2.0   良信林(冊手術技          – http://openhome.cc         )

try {
    .....
    connection.setAutoCommit(false);
    .....
    // 串連一  SQL    作操
    connection.commit();
} catch(SQLException) {
    // 更變有所消撤,誤錯生發
    connection.rollback();
}


   在   Spring   對中    JDBC   ,裝封以加理管易交的               S pring   其象抽的理管易交
  於在 鍵關   org.springframework.transaction.PlatformTransactionManager
:現實的面介
...
public interface PlatformTransactionManager {
    TransactionStatus getTransaction(TransactionDefinition
                    definition) throws TransactionException;
    void commit(TransactionStatus status)
                                   throws TransactionException;
    void rollback(TransactionStatus status)
                                   throws TransactionException;
}


如例,別類現實易交的體具多許有面介
     PlatformTransactionManager
       、                        、
DataSourceTransactionManager H ibernateTransactionManager J doTrans-
            於賴依由藉,等
actionManager      J taTransactionManager   、                     PlatformTran-
發 開讓 以 可 上 理 管 易 交 在
sactionManager           ,現實術技的種各及面介        S pring
     。 術 技 理 管 易 交 的 同不是 的 用 使 所 使 即 , 型模程 編 的 致 一 用 使 員 人
是都 常 通 敗 失 的 易 交 。
     TransactionException           是
                              Unchecked Exception
例 捉捕要 否 是 擇 選 行 自 您 讓而, 理 處 要 定 一 您 迫 強 不
                S pring                        ,誤錯的命致
                                                       。外

44
4
             。務服理管易交去移可即,定設下一改修上案檔定設在要
只,候時的理管易交要需不在,中之理管易交入納被正它道知不並,看來
                                         API
度 角 的 件 物 從,中 之 式 程 入 介 用 不 以 可 關 相 的 理 管 易 交          是處好      Spring
,理 管 易 交 的 式 告 宣 用 採,制 控 的 度 粒 細 要 需 不 並 易 交,下 況 情 的 數 多 而 然
                                             理管易交的式告宣
                                                    。制控易
交的度粒細現實以可,等束結時何易交、機時的作操消撤、始開時何易
交現實行自您讓是就也,界邊的易交制控的楚清以可理管易交的式程編
                                             理管易交的式程編
             :)   D eclarative transaction management
                                                 (理 管 易 交 的 式 告 宣 與
)   P rogrammatic transaction management   (理管易交的式程編供提                Spring
                                        }
                                            boolean isRollbackOnly();
                                            void setRollbackOnly();
                                            boolean isNewTransaction();
                                        public interface TransactionStatus {
                                        ...
                                  :態狀
    的易交查調或行執的易交制控它由藉以可您,易交的在存經已或起發易交
    的新個一著表代        T ransactionStatus
                   ,等)     (讀唯、)    (          R ead-only                T imeout
    時超、)   P ropagation behavior
                 (為行播傳、)       (度程離隔的              I solation level
    易交了義定例實的面介         ,件物T ransactionDefinition
                                    個                    TransactionStatus
    一傳回來件物      TransactionDefinition
                    個一據根法方                                  getTransaction()
    援支易交、    Chapter 5 JDBC
Spring 2.0    良信林(冊手術技        – http://openhome.cc    )

5.3.2 JDBC 編程交易管理

    用使接直是一,理管易交的式程編現實式方種兩供提
     Spring                                                     Platform-
               用使是二,現實
TransactionManager                       org.springframework.transaction.
                   。
support.TransactionTemplate

實的它用使邊這在,              用使何如看看來先
                        PlatformTransactionManager
中   的前之下一寫改以可,                別類現
          DataSourceTransactionManager                           5.2.1
類     下一改修,能功理管易交有具它讓,案專
JdbcTemplateDemo                                             UserDAO
     insert()       :範示作來法方     的別
  ProgrammaticTransactionDemo                              UserDAO.java
 package onlyfun.caterpillar;

 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import javax.sql.DataSource;
 import org.springframework.dao.DataAccessException;
 import org.springframework.jdbc.core.JdbcTemplate;
 import org.springframework.jdbc.
             datasource.DataSourceTransactionManager;
 import org.springframework.transaction.TransactionDefinition;
 import org.springframework.transaction.TransactionStatus;
 import org.springframework.transaction.
             support.DefaultTransactionDefinition;

 public class UserDAO implements IUserDAO {
     private DataSourceTransactionManager transactionManager;
     private DefaultTransactionDefinition def;
     private JdbcTemplate jdbcTemplate;

     public void setDataSource(DataSource dataSource) {
         jdbcTemplate = new JdbcTemplate(dataSource);
         transactionManager =
             new DataSourceTransactionManager(dataSource);
         //     義定的易交立建

46
Chapter 5 JDBC     援支易交、

    def = new DefaultTransactionDefinition();
    def.setPropagationBehavior(
            TransactionDefinition.PROPAGATION_REQUIRED);
}

public void insert(User user) {
   String name = user.getName();
   int age = user.getAge().intValue();

    TransactionStatus status =
        transactionManager.getTransaction(def);
    try {
        jdbcTemplate.update("INSERT INTO user (name,age) "
                 + "VALUES('" + name + "'," + age + ")");
        //的面下    SQL
                   易交試測以用,誤錯有
        jdbcTemplate.update("INSER INTO user (name,age) "
                 + "VALUES('" + name + "'," + age + ")");
    }
    catch(DataAccessException e) {
        transactionManager.rollback(status);
        throw e;
    }
    transactionManager.commit(status);
}

public User find(Integer id) {
    List rows = jdbcTemplate.queryForList(
      "SELECT * FROM user WHERE id=" + id.intValue());

    Iterator it = rows.iterator();
    if(it.hasNext()) {
        Map userMap = (Map) it.next();
        Integer i = new Integer(
                userMap.get("id").toString());
        String name = userMap.get("name").toString();
        Integer age = new Integer(
                userMap.get("age").toString());

        User user = new User();

        user.setId(i);
        user.setName(name);



                                                             47
Spring 2.0     良信林(冊手術技          – http://openhome.cc   )

                user.setAge(age);

                return user;
           }

           return null;
     }
 }



易交行進來    insert()            了用使中法方            在
                                  DataSourceTransactionManager
      在,       的易交行進會中塊區 則,外例了生發果如,理管
                               catch                  Rollback     insert()
實 此 因 ,) 個 一 了 寫 少 法 方  意 注 ( 的誤 錯 入 寫 意 故 中 法 方
                          SQL          INSERT                  T
                       。 中 庫 料 資 至存儲 被 會 不 並 料 資 上 際

         格 表 的 易 交 援 支 立 建 須 必,理 處 易 交 行 進 庫 料 資
                MySQL                              用使要
         如 的格 表立建來用邊這,型類格表的
                    InnoDB                       如例,型類      SQL
                                                  :示所下
          CREATE TABLE user (
             id INT(11) NOT NULL auto_increment PRIMARY KEY,
             name VARCHAR(100) NOT NULL default '',
             age INT
         ) TYPE = InnoDB;



  用 使 是 法 方 的 理 管易交 式 程 編 現 實 個 一 另             TransactionTemplate   它,
:示所下如,例實   TransactionManager  個一要需
...
TransactionTemplate transactionTemplate =
        new TransactionTemplate(transactionManager);
...
transactionTemplate.execute(new TransactionCallback() {
    public Object doInTransaction(TransactionStatus status) {
         return jdbcTemplate.update("INSERT INTO user (name,age) "
               + "VALUES('" + name + "'," + age + ")");


48
Chapter 5 JDBC   援支易交、

      }
});


行 進會則 , 外 例 了 生 發 果 如              Rollback   傳回 有 沒 果 如 , 易 交 交 提 則 否 ,
         用使以可也則,值   TransactionCallbackWithoutResult      :
...
transactionTemplate.execute(
        new TransactionCallbackWithoutResult() {
                public void doInTransactionWithoutResult(
                                TransactionStatus status) {
            .        ...
                }
            });




5.3.3 JDBC 宣告交易管理

易交告宣用使。成完來架框 的它於賴依理管易交的式告宣
      Spring                                  AOP
不件物 ,說來體具,件組的發開所您入侵不理管易交,是處好的理管                               D AO
系於屬是理管易交為因,此如當應也上實事,中之理管易交在正到識意會
的略策理管易交變改要想果如,份部一的輯邏務商是不而,務服的面層統
                          。 可 即 態 組 新 重 中檔義 定 在 要 需 只 也 , 話
在,下一改修案專                       中 將以可,說來子例個舉
                           5.2.1     JdbcTemplateDemo
簡 個一, 務 服 的 理 管 易 交 入加它 為 以 可 , 下 況 情 的 別 類
          UserDAO                                     改修不
對 理 管 易 交 的 入 介 要 定 指,
                TransactionProxyFactoryBean   用使是法方的單
                    : 示所下 如 , 改 修 案 檔 義 定在要 需 這 , 法 方 其 及 象
  DeclarativeTransactionDemo                             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



                                                                            4
Spring 2.0   良信林(冊手術技      – http://openhome.cc   )

  http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <bean id="dataSource"
          class="org.springframework.jdbc.
                   → datasource.DriverManagerDataSource"
          destroy-method="close">
        <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="transactionManager"
          class="org.springframework.jdbc.
                   → datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="userDAO"
          class="onlyfun.caterpillar.UserDAO">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="userDAOProxy"
          class="org.springframework.transaction.
                    → interceptor.TransactionProxyFactoryBean">
        <property name="proxyInterfaces">
            <list>
                <value>onlyfun.caterpillar.IUserDAO</value>
            </list>
        </property>
        <property name="target" ref="userDAO"/>
        <property name="transactionManager"
                   ref="transactionManager"/>
        <property name="transactionAttributes">
            <props>
                <prop key="insert*">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>
Chapter 5 JDBC   援支易交、

</beans>



    TransactionProxyFactoryBean       個一要需         TransactionManager   這於由,
         ,
       JDBC                             用使以所, 用使邊
                            DataSourceTransactionManager T ransaction-
易交,象對的理代要定指性屬
ProxyFactoryBean             ,件物理代個是   " target"
屬                     用使 是 邊 這 , 後 前 法 方的定 指 入 介 動 自 會 理 管
                                                     "transactionAttributes"
您 ,理管 易 交 入 納 要 都 的 頭 開 稱 名 法 方 定 指 示 表
        " insert*"                       insert    ,定指性
操的前先有所則,誤錯生發中程過行執法方在果如,名全法方定指以可也
                                   。 交 提常正 則 否 , 回 撤 動 自 作
目在示表,
    "insert*"                      了定指上法方等
                                    "PROPAGATION_REQUIRED"
義意數常的關相,的新個一立建就在存不易交果如,作操行執中易交的前
個多上加以可您。到找中面介
           API                           中件文 在以可都
                       TransactionDefinition
個某定指是者或,讀唯上加以可如例,隔區 號逗用使間中,義定易交
                              ","
                                        :作 操 回 撤 時 生 發 外 例
PROPAGATION_REQUIRED,readOnly,-MyCheckedException


操消撤時外例定指生發示表,時 上加面前
    MyCheckedException                  "-"
          。 交提即 立 時 外 例 生 發 示 表 , 上 加 面 前 果 如 , 作
                     "+"

   得取是的做要以所,了理代
        " userDAO"               被
                           " userDAOProxy"於由                             " user-
DAOProxy"        :如例, " userDAO"  是不而,
  DeclarativeTransactionDemo                               SpringDAODemo.java
package onlyfun.caterpillar;

import org.springframework.context.ApplicationContext;
import org.springframework.context.
              support.ClassPathXmlApplicationContext;

public class SpringDAODemo {


                                                                                   1
Spring 2.0   良信林(冊手術技      – http://openhome.cc    )

    public static void main(String[] args) {
        ApplicationContext context =
            new ClassPathXmlApplicationContext(
                    "beans-config.xml");

        User user = new User();

        user.setName("caterpillar");
        user.setAge(new Integer(30));

        IUserDAO userDAO =
            (IUserDAO) context.getBean("userDAOProxy");

        userDAO.insert(user);

        user = userDAO.find(new Integer(1));

        System.out.println("name: " + user.getName());
    }
}



的同不定設以可也您               TransactionInterceptor   ,節細理管的多更到得來
        :如例
<?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"
          destroy-method="close">
        <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"/>



2
Chapter 5 JDBC       援支易交、

    </bean>

    <bean id="transactionManager"
          class="org.springframework.jdbc.
                   → datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="userDAO"
          class="onlyfun.caterpillar.UserDAO">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="transactionInterceptor"
          class="org.springframework.transaction.
                   → interceptor.TransactionInterceptor">
        <property name="transactionManager" ref="transactionManager"/>
        <property name="transactionAttributeSource"
                  value="onlyfun.caterpillar.UserDAO.insert*=
                            → PROPAGATION_REQUIRED "/>
    </bean>

    <bean id="userDAOProxy"
           class="org.springframework.aop.
                     → framework.ProxyFactoryBean">
         <property name="proxyInterfaces">
             <list>
                 <value>onlyfun.caterpillar.IUserDAO</value>
             </list>
         </property>
         <property name="target" ref="userDAO"/>
         <property name="interceptorNames">
             <list>
                 <value>transactionInterceptor</value>
             </list>
         </property>
    </bean>
</beans>


在接直則,理管易交要需再不來後使即                        Bean   ,可 即 置 配 改 修 中 檔 義 定
  。 作 動 等 譯 編 新重行 進 式 程 改 修 用 不 而
                                                                         3
4
                      易交的存現
停暫就 話的有果 如,行進中 易交在 應不出指                    PROPAGATION_NOT_SUPPORTED
                          外例
出丟就 話的有果 如,行進中 易交在 應不出指                                PROPAGATION_NEVER
                          同則
        PROPAGATION_REQUIRED
, 話 的 是 不 果 如,行 進中易 交的狀 巢個一在                         PROPAGATION_NESTED
                         外例出
丟 則否,行進中 易交 的存現 個一在 須必法方                          PROPAGATION_MANDATORY
                          明說                                           為行播傳
                                                   明說為行播傳易交             5.1   表
                     :個幾出列下以,明說與數常的應對相到找上明
說件文 的 API     TransactionDefinition
                              在 以 可 ,為 行 播 傳 個 幾 了 義 定             Spring
。行 進 中 易 交 在 要 否 是 法 方 者 或,停 暫 被 該 易 交 時 何 或,易 交 的 新 個 一 始 開
該時何知告它,)          B oundaries
                         (界邊之上法方於用應易交了義定為行播傳
                               )        P ropagation behavior
                                                   (為行播傳
  :數 參 個 幾 的 下 以 作 分 性 屬 易 交 中           Spring
                                在 ,略策 的 上 法 方 至 用 應 易
交述描於在就然自)             T ransaction attribute
                               (性屬易交的         ,界邊為           S pring
法方以是易交式告宣而因,理管易交的式告宣成完來 用使                             AOP        Spring
                                               5.3.4 交易的屬性介紹
        。              括包須必中定設
            spring-aop.jar                 Classpath 的您得記請,時
      式 程 的 上 以 行 執 以 所 ,成 達 來        Spring AOP   用利是理管易交告宣
                 )   – http://openhome.cc      良信林(冊手術技           Spring 2.0
Spring 2.0 技術手冊第五章 - JDBC、交易支援
Spring 2.0 技術手冊第五章 - JDBC、交易支援
Spring 2.0 技術手冊第五章 - JDBC、交易支援
Spring 2.0 技術手冊第五章 - JDBC、交易支援
Spring 2.0 技術手冊第五章 - JDBC、交易支援
Spring 2.0 技術手冊第五章 - JDBC、交易支援
Spring 2.0 技術手冊第五章 - JDBC、交易支援
Spring 2.0 技術手冊第五章 - JDBC、交易支援
Spring 2.0 技術手冊第五章 - JDBC、交易支援
Spring 2.0 技術手冊第五章 - JDBC、交易支援
Spring 2.0 技術手冊第五章 - JDBC、交易支援
Spring 2.0 技術手冊第五章 - JDBC、交易支援
Spring 2.0 技術手冊第五章 - JDBC、交易支援
Spring 2.0 技術手冊第五章 - JDBC、交易支援

Contenu connexe

Tendances

Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring FrameworkHùng Nguyễn Huy
 
Spring boot
Spring bootSpring boot
Spring bootsdeeg
 
Ch12 Spring 起步走
Ch12 Spring 起步走Ch12 Spring 起步走
Ch12 Spring 起步走Justin Lin
 
Java spring framework
Java spring frameworkJava spring framework
Java spring frameworkRajiv Gupta
 
Spring Framework
Spring Framework  Spring Framework
Spring Framework tola99
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOPDzmitry Naskou
 
Spring core module
Spring core moduleSpring core module
Spring core moduleRaj Tomar
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework Serhat Can
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introductionRasheed Waraich
 
Graal in GraalVM - A New JIT Compiler
Graal in GraalVM - A New JIT CompilerGraal in GraalVM - A New JIT Compiler
Graal in GraalVM - A New JIT CompilerKoichi Sakata
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring FrameworkDineesha Suraweera
 
Spring framework Introduction
Spring framework IntroductionSpring framework Introduction
Spring framework IntroductionAnuj Singh Rajput
 
Spring Framework
Spring FrameworkSpring Framework
Spring Frameworknomykk
 

Tendances (20)

Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Java Spring Framework
Java Spring FrameworkJava Spring Framework
Java Spring Framework
 
Spring boot
Spring bootSpring boot
Spring boot
 
Ch12 Spring 起步走
Ch12 Spring 起步走Ch12 Spring 起步走
Ch12 Spring 起步走
 
Java spring framework
Java spring frameworkJava spring framework
Java spring framework
 
Spring Framework
Spring Framework  Spring Framework
Spring Framework
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOP
 
Spring core module
Spring core moduleSpring core module
Spring core module
 
Spring & hibernate
Spring & hibernateSpring & hibernate
Spring & hibernate
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introduction
 
Graal in GraalVM - A New JIT Compiler
Graal in GraalVM - A New JIT CompilerGraal in GraalVM - A New JIT Compiler
Graal in GraalVM - A New JIT Compiler
 
Spring framework core
Spring framework coreSpring framework core
Spring framework core
 
Spring Boot Tutorial
Spring Boot TutorialSpring Boot Tutorial
Spring Boot Tutorial
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework
 
Spring framework Introduction
Spring framework IntroductionSpring framework Introduction
Spring framework Introduction
 
Spring Framework
Spring FrameworkSpring Framework
Spring Framework
 
Spring data jpa
Spring data jpaSpring data jpa
Spring data jpa
 
Spring boot
Spring bootSpring boot
Spring boot
 

En vedette

Spring 2.0 技術手冊第九章 - API 封裝
Spring 2.0 技術手冊第九章 - API 封裝Spring 2.0 技術手冊第九章 - API 封裝
Spring 2.0 技術手冊第九章 - API 封裝Justin Lin
 
Spring 2.0 技術手冊第十章 - 專案:線上書籤
Spring 2.0 技術手冊第十章 - 專案:線上書籤Spring 2.0 技術手冊第十章 - 專案:線上書籤
Spring 2.0 技術手冊第十章 - 專案:線上書籤Justin Lin
 
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合Justin Lin
 
Spring 2.0 技術手冊導讀
Spring 2.0 技術手冊導讀Spring 2.0 技術手冊導讀
Spring 2.0 技術手冊導讀Justin Lin
 
Spring 2.0 技術手冊目錄
Spring 2.0 技術手冊目錄Spring 2.0 技術手冊目錄
Spring 2.0 技術手冊目錄Justin Lin
 
Spring 2.0 技術手冊書名頁
Spring 2.0 技術手冊書名頁Spring 2.0 技術手冊書名頁
Spring 2.0 技術手冊書名頁Justin Lin
 
Spring 2.0 技術手冊再版序
Spring 2.0 技術手冊再版序Spring 2.0 技術手冊再版序
Spring 2.0 技術手冊再版序Justin Lin
 
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應Justin Lin
 
Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式
Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式
Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式Justin Lin
 
Java SE 7 技術手冊投影片第 12 章 - 通用API
Java SE 7 技術手冊投影片第 12 章  - 通用APIJava SE 7 技術手冊投影片第 12 章  - 通用API
Java SE 7 技術手冊投影片第 12 章 - 通用APIJustin Lin
 
Servlet & JSP 教學手冊第二版 - 第 11 章:簡介 JavaMail
Servlet & JSP 教學手冊第二版 - 第 11 章:簡介 JavaMailServlet & JSP 教學手冊第二版 - 第 11 章:簡介 JavaMail
Servlet & JSP 教學手冊第二版 - 第 11 章:簡介 JavaMailJustin Lin
 
Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫
Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫
Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫Justin Lin
 
Servlet & JSP 教學手冊第二版 - 第 8 章:自訂標籤
Servlet & JSP 教學手冊第二版 - 第 8 章:自訂標籤Servlet & JSP 教學手冊第二版 - 第 8 章:自訂標籤
Servlet & JSP 教學手冊第二版 - 第 8 章:自訂標籤Justin Lin
 
Servlet & JSP 教學手冊第二版 - 第 10 章:Web 容器安全管理
Servlet & JSP 教學手冊第二版 - 第 10 章:Web 容器安全管理Servlet & JSP 教學手冊第二版 - 第 10 章:Web 容器安全管理
Servlet & JSP 教學手冊第二版 - 第 10 章:Web 容器安全管理Justin Lin
 
Servlet & JSP 教學手冊第二版 - 第 12 章:從模式到框架
Servlet & JSP 教學手冊第二版 - 第 12 章:從模式到框架Servlet & JSP 教學手冊第二版 - 第 12 章:從模式到框架
Servlet & JSP 教學手冊第二版 - 第 12 章:從模式到框架Justin Lin
 
Servlet & JSP 教學手冊第二版 - 第 4 章:會話管理
Servlet & JSP 教學手冊第二版 - 第 4 章:會話管理Servlet & JSP 教學手冊第二版 - 第 4 章:會話管理
Servlet & JSP 教學手冊第二版 - 第 4 章:會話管理Justin Lin
 
Servlet & JSP 教學手冊第二版 - 第 2 章:撰寫與設定 Servlet
Servlet & JSP 教學手冊第二版 - 第 2 章:撰寫與設定 ServletServlet & JSP 教學手冊第二版 - 第 2 章:撰寫與設定 Servlet
Servlet & JSP 教學手冊第二版 - 第 2 章:撰寫與設定 ServletJustin Lin
 
類別的繼承
類別的繼承類別的繼承
類別的繼承Justin Lin
 
除錯、測試與效能
除錯、測試與效能除錯、測試與效能
除錯、測試與效能Justin Lin
 

En vedette (20)

Spring 2.0 技術手冊第九章 - API 封裝
Spring 2.0 技術手冊第九章 - API 封裝Spring 2.0 技術手冊第九章 - API 封裝
Spring 2.0 技術手冊第九章 - API 封裝
 
Spring 2.0 技術手冊第十章 - 專案:線上書籤
Spring 2.0 技術手冊第十章 - 專案:線上書籤Spring 2.0 技術手冊第十章 - 專案:線上書籤
Spring 2.0 技術手冊第十章 - 專案:線上書籤
 
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合
Spring 2.0 技術手冊第八章 - View 層方案、Web 框架整合
 
Spring 2.0 技術手冊導讀
Spring 2.0 技術手冊導讀Spring 2.0 技術手冊導讀
Spring 2.0 技術手冊導讀
 
Spring 2.0 技術手冊目錄
Spring 2.0 技術手冊目錄Spring 2.0 技術手冊目錄
Spring 2.0 技術手冊目錄
 
Spring 2.0 技術手冊書名頁
Spring 2.0 技術手冊書名頁Spring 2.0 技術手冊書名頁
Spring 2.0 技術手冊書名頁
 
Spring 2.0 技術手冊再版序
Spring 2.0 技術手冊再版序Spring 2.0 技術手冊再版序
Spring 2.0 技術手冊再版序
 
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
 
Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式
Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式
Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式
 
進階主題
進階主題進階主題
進階主題
 
Java SE 7 技術手冊投影片第 12 章 - 通用API
Java SE 7 技術手冊投影片第 12 章  - 通用APIJava SE 7 技術手冊投影片第 12 章  - 通用API
Java SE 7 技術手冊投影片第 12 章 - 通用API
 
Servlet & JSP 教學手冊第二版 - 第 11 章:簡介 JavaMail
Servlet & JSP 教學手冊第二版 - 第 11 章:簡介 JavaMailServlet & JSP 教學手冊第二版 - 第 11 章:簡介 JavaMail
Servlet & JSP 教學手冊第二版 - 第 11 章:簡介 JavaMail
 
Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫
Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫
Servlet & JSP 教學手冊第二版 - 第 9 章:整合資料庫
 
Servlet & JSP 教學手冊第二版 - 第 8 章:自訂標籤
Servlet & JSP 教學手冊第二版 - 第 8 章:自訂標籤Servlet & JSP 教學手冊第二版 - 第 8 章:自訂標籤
Servlet & JSP 教學手冊第二版 - 第 8 章:自訂標籤
 
Servlet & JSP 教學手冊第二版 - 第 10 章:Web 容器安全管理
Servlet & JSP 教學手冊第二版 - 第 10 章:Web 容器安全管理Servlet & JSP 教學手冊第二版 - 第 10 章:Web 容器安全管理
Servlet & JSP 教學手冊第二版 - 第 10 章:Web 容器安全管理
 
Servlet & JSP 教學手冊第二版 - 第 12 章:從模式到框架
Servlet & JSP 教學手冊第二版 - 第 12 章:從模式到框架Servlet & JSP 教學手冊第二版 - 第 12 章:從模式到框架
Servlet & JSP 教學手冊第二版 - 第 12 章:從模式到框架
 
Servlet & JSP 教學手冊第二版 - 第 4 章:會話管理
Servlet & JSP 教學手冊第二版 - 第 4 章:會話管理Servlet & JSP 教學手冊第二版 - 第 4 章:會話管理
Servlet & JSP 教學手冊第二版 - 第 4 章:會話管理
 
Servlet & JSP 教學手冊第二版 - 第 2 章:撰寫與設定 Servlet
Servlet & JSP 教學手冊第二版 - 第 2 章:撰寫與設定 ServletServlet & JSP 教學手冊第二版 - 第 2 章:撰寫與設定 Servlet
Servlet & JSP 教學手冊第二版 - 第 2 章:撰寫與設定 Servlet
 
類別的繼承
類別的繼承類別的繼承
類別的繼承
 
除錯、測試與效能
除錯、測試與效能除錯、測試與效能
除錯、測試與效能
 

Similaire à Spring 2.0 技術手冊第五章 - JDBC、交易支援

Java华为面试题
Java华为面试题Java华为面试题
Java华为面试题yiditushe
 
J2ee面试知识
J2ee面试知识J2ee面试知识
J2ee面试知识yiditushe
 
线程与并发
线程与并发线程与并发
线程与并发Tony Deng
 
由一个简单的程序谈起――之二
由一个简单的程序谈起――之二由一个简单的程序谈起――之二
由一个简单的程序谈起――之二yiditushe
 
Jdbc中驱动加载的过程分析(下)
Jdbc中驱动加载的过程分析(下)Jdbc中驱动加载的过程分析(下)
Jdbc中驱动加载的过程分析(下)yiditushe
 
深入淺出 Web 容器 - Tomcat 原始碼分析
深入淺出 Web 容器  - Tomcat 原始碼分析深入淺出 Web 容器  - Tomcat 原始碼分析
深入淺出 Web 容器 - Tomcat 原始碼分析Justin Lin
 
J2ee经典学习笔记
J2ee经典学习笔记J2ee经典学习笔记
J2ee经典学习笔记yiditushe
 
Jsp面试知识
Jsp面试知识Jsp面试知识
Jsp面试知识yiditushe
 
千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7javatwo2011
 
學好 node.js 不可不知的事
學好 node.js 不可不知的事學好 node.js 不可不知的事
學好 node.js 不可不知的事Ben Lue
 
Mybatis学习培训
Mybatis学习培训Mybatis学习培训
Mybatis学习培训flynofry
 
异步编程与浏览器执行模型
异步编程与浏览器执行模型异步编程与浏览器执行模型
异步编程与浏览器执行模型keelii
 
Java面试知识
Java面试知识Java面试知识
Java面试知识yiditushe
 
第01章 绪论(java版)
第01章  绪论(java版)第01章  绪论(java版)
第01章 绪论(java版)Yan Li
 
Row Set初步学习V1.1
Row Set初步学习V1.1Row Set初步学习V1.1
Row Set初步学习V1.1Zianed Hou
 
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDE
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDEJava SE 7 技術手冊第二章草稿 - 從 JDK 到 IDE
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDEJustin Lin
 

Similaire à Spring 2.0 技術手冊第五章 - JDBC、交易支援 (20)

Java华为面试题
Java华为面试题Java华为面试题
Java华为面试题
 
J2ee面试知识
J2ee面试知识J2ee面试知识
J2ee面试知识
 
线程与并发
线程与并发线程与并发
线程与并发
 
由一个简单的程序谈起――之二
由一个简单的程序谈起――之二由一个简单的程序谈起――之二
由一个简单的程序谈起――之二
 
Jsp
JspJsp
Jsp
 
Jdbc中驱动加载的过程分析(下)
Jdbc中驱动加载的过程分析(下)Jdbc中驱动加载的过程分析(下)
Jdbc中驱动加载的过程分析(下)
 
Sun java
Sun javaSun java
Sun java
 
深入淺出 Web 容器 - Tomcat 原始碼分析
深入淺出 Web 容器  - Tomcat 原始碼分析深入淺出 Web 容器  - Tomcat 原始碼分析
深入淺出 Web 容器 - Tomcat 原始碼分析
 
J2ee经典学习笔记
J2ee经典学习笔记J2ee经典学习笔记
J2ee经典学习笔记
 
Jsp面试知识
Jsp面试知识Jsp面试知识
Jsp面试知识
 
千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7千呼萬喚始出來的Java SE 7
千呼萬喚始出來的Java SE 7
 
學好 node.js 不可不知的事
學好 node.js 不可不知的事學好 node.js 不可不知的事
學好 node.js 不可不知的事
 
Mybatis学习培训
Mybatis学习培训Mybatis学习培训
Mybatis学习培训
 
异步编程与浏览器执行模型
异步编程与浏览器执行模型异步编程与浏览器执行模型
异步编程与浏览器执行模型
 
Java面试知识
Java面试知识Java面试知识
Java面试知识
 
第01章 绪论(java版)
第01章  绪论(java版)第01章  绪论(java版)
第01章 绪论(java版)
 
Row Set初步学习V1.1
Row Set初步学习V1.1Row Set初步学习V1.1
Row Set初步学习V1.1
 
Java annotation
Java annotationJava annotation
Java annotation
 
Js培训
Js培训Js培训
Js培训
 
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDE
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDEJava SE 7 技術手冊第二章草稿 - 從 JDK 到 IDE
Java SE 7 技術手冊第二章草稿 - 從 JDK 到 IDE
 

Plus de Justin Lin

Ch14 簡介 Spring Boot
Ch14 簡介 Spring BootCh14 簡介 Spring Boot
Ch14 簡介 Spring BootJustin Lin
 
Ch11 簡介 JavaMail
Ch11 簡介 JavaMailCh11 簡介 JavaMail
Ch11 簡介 JavaMailJustin Lin
 
Ch10 Web 容器安全管理
Ch10 Web 容器安全管理Ch10 Web 容器安全管理
Ch10 Web 容器安全管理Justin Lin
 
Ch09 整合資料庫
Ch09 整合資料庫Ch09 整合資料庫
Ch09 整合資料庫Justin Lin
 
Ch08 自訂標籤
Ch08 自訂標籤Ch08 自訂標籤
Ch08 自訂標籤Justin Lin
 
Ch07 使用 JSTL
Ch07 使用 JSTLCh07 使用 JSTL
Ch07 使用 JSTLJustin Lin
 
Ch06 使用 JSP
Ch06 使用 JSPCh06 使用 JSP
Ch06 使用 JSPJustin Lin
 
Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器Justin Lin
 
Ch04 會話管理
Ch04 會話管理Ch04 會話管理
Ch04 會話管理Justin Lin
 
Ch03 請求與回應
Ch03 請求與回應Ch03 請求與回應
Ch03 請求與回應Justin Lin
 
Ch02 撰寫與設定 Servlet
Ch02 撰寫與設定 ServletCh02 撰寫與設定 Servlet
Ch02 撰寫與設定 ServletJustin Lin
 
CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式Justin Lin
 
14. 進階主題
14. 進階主題14. 進階主題
14. 進階主題Justin Lin
 
13.並行、平行與非同步
13.並行、平行與非同步13.並行、平行與非同步
13.並行、平行與非同步Justin Lin
 
12. 除錯、測試與效能
12. 除錯、測試與效能12. 除錯、測試與效能
12. 除錯、測試與效能Justin Lin
 
11. 常用內建模組
11. 常用內建模組11. 常用內建模組
11. 常用內建模組Justin Lin
 
10. 資料永續與交換
10. 資料永續與交換10. 資料永續與交換
10. 資料永續與交換Justin Lin
 
9. 資料結構
9. 資料結構9. 資料結構
9. 資料結構Justin Lin
 
8. open() 與 io 模組
8. open() 與 io 模組8. open() 與 io 模組
8. open() 與 io 模組Justin Lin
 
7. 例外處理
7. 例外處理7. 例外處理
7. 例外處理Justin Lin
 

Plus de Justin Lin (20)

Ch14 簡介 Spring Boot
Ch14 簡介 Spring BootCh14 簡介 Spring Boot
Ch14 簡介 Spring Boot
 
Ch11 簡介 JavaMail
Ch11 簡介 JavaMailCh11 簡介 JavaMail
Ch11 簡介 JavaMail
 
Ch10 Web 容器安全管理
Ch10 Web 容器安全管理Ch10 Web 容器安全管理
Ch10 Web 容器安全管理
 
Ch09 整合資料庫
Ch09 整合資料庫Ch09 整合資料庫
Ch09 整合資料庫
 
Ch08 自訂標籤
Ch08 自訂標籤Ch08 自訂標籤
Ch08 自訂標籤
 
Ch07 使用 JSTL
Ch07 使用 JSTLCh07 使用 JSTL
Ch07 使用 JSTL
 
Ch06 使用 JSP
Ch06 使用 JSPCh06 使用 JSP
Ch06 使用 JSP
 
Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器
 
Ch04 會話管理
Ch04 會話管理Ch04 會話管理
Ch04 會話管理
 
Ch03 請求與回應
Ch03 請求與回應Ch03 請求與回應
Ch03 請求與回應
 
Ch02 撰寫與設定 Servlet
Ch02 撰寫與設定 ServletCh02 撰寫與設定 Servlet
Ch02 撰寫與設定 Servlet
 
CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式CH1. 簡介 Web 應用程式
CH1. 簡介 Web 應用程式
 
14. 進階主題
14. 進階主題14. 進階主題
14. 進階主題
 
13.並行、平行與非同步
13.並行、平行與非同步13.並行、平行與非同步
13.並行、平行與非同步
 
12. 除錯、測試與效能
12. 除錯、測試與效能12. 除錯、測試與效能
12. 除錯、測試與效能
 
11. 常用內建模組
11. 常用內建模組11. 常用內建模組
11. 常用內建模組
 
10. 資料永續與交換
10. 資料永續與交換10. 資料永續與交換
10. 資料永續與交換
 
9. 資料結構
9. 資料結構9. 資料結構
9. 資料結構
 
8. open() 與 io 模組
8. open() 與 io 模組8. open() 與 io 模組
8. open() 與 io 模組
 
7. 例外處理
7. 例外處理7. 例外處理
7. 例外處理
 

Spring 2.0 技術手冊第五章 - JDBC、交易支援

  • 1. 。援支些一的 上易交及以取存 JDBC 於 紹介來子例的際實些一以將,中節 Spring 章 個 這 在。能 功 的 務 服 關 相 等 易 交 得 獲 易 輕 並,式 方 用 運 的 化 JDBC 簡 以 可,能 功 的 供 提 所 架 框 與 器 容 AOP 合 結,之 言 而 總 Spring IoC 。) ( D eclarative transaction management 理管易交式告宣與) ( P rogrammatic transaction management 理管易交式程編了供提 ,面方理處的易交於關。用使 Spring 作操的上 在 API JDBC 化簡以別類等 了供提也 JdbcTemplate Spring ,上用使的 JDBC API 在。外例的定特理處否是擇選以可您,裝封新 重以加 外例些一 的時取 存庫料資對 。節細術技的庫料資層底 S pring 觸 接 用 不 以 可 您 ,架 框 了 供 提 DAO ,援 支 的 取 存 庫 料 資 於 對 S pring JDBC、交易支援 5
  • 2. 2 } public void delete(User user); public void update(User user); public User find(Integer id); public void insert(User user); public interface IUserDAO { package onlyfun.caterpillar; :面介 IUserDAO 個 一 如例, 面 介 個 一 賴 依 它 讓以可 而 , 作 實 別 類 的 際 實個一於賴依應不式程用應,) 、 、 、 如例(時取 d elete u pdate i nsert select User 存 庫 料 資 行 進 在, 件 物 個 有 中 式 程 用 應 設 假, 子 例 的 個 舉 DAO 。節細關相的 時取存作實,中之法方的範規在並,面介該作實要件物的取存庫料資行進 上際實而,作操來面介取存料資個一過透是,時取存料資到用使要需,中 式程用應在, Data Access Object D AO 為 名 全 的 ,節 細 術 技 庫 料 資 定 特 的用 使 所 到 觸 接 須 無 ,時取 存 庫 料 資 行 進 在 您 讓 架 框 的 DAO Spring 5.1.1 Spring 的 DAO 支持 。層久持 Spring 門入來子例的際實以並,計 設 DAO 的 Spring 介簡來先節小個這,術技 庫料 資 定 特 於 合 耦 須 無時發 開 式 程 用 應 讓 , 架 框 了供提 DAO Spring 5.1 Spring 持久層入門 ) – http://openhome.cc 良信林(冊手術技 Spring 2.0
  • 3. Chapter 5 JDBC 援支易交、 作 實 以 可 別 類 的取存 庫 料 資 行 進 上 際 實 IUserDAO 一義定如例,面介 :別類 UserDAO 的單簡個 package onlyfun.caterpillar; ... public class UserDAO implements IUserDAO { private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public void insert(User user) { String name = user.getName(); int age = user.getAge().intValue(); Connection conn = null; PreparedStatement stmt = null; try { conn = dataSource.getConnection(); stmt = conn.prepareStatement ( "INSERT INTO user (name,age) VALUES(?,?)"); stmt.setString(1, name); stmt.setInt(2, age); stmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { if(stmt != null) { try { stmt.close(); } catch(SQLException e) { e.printStackTrace(); } } if(conn != null) { try { conn.close(); } 3
  • 4. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) catch(SQLException e) { e.printStackTrace(); } } } } public User find(Integer id) { ... return user; } public void update(User user) { ... } public void delete(User user) { ... } } 用 使以可 , 時 取 存 料 資 行 進在程 流 主 式 程 用 應 的 您 IUserDAO 告宣來 :如例,面介作操 ... User user = new User(); user.setName("caterpillar"); user.setAge(new Integer(30)); IUserDAO userDao = getUserDAO(); userDao.insert(user); ... 而,別類作實的 換替時隨以可以所,面介於賴依於由 IUserDAO 術技的取存庫料資層底與何任有沒並,上法方作操的告宣面介 IUserDAO 層 底與式 程 用 應 將 , 理 原 本基的 樣 這 於 基 是 正 架 框 S pring DAO 的 ,節細 :來開離隔術技取存 4
  • 5. Chapter 5 JDBC 援支易交、 圖 5.1 DAO 圖意示作運 如例(法方的關無術技取存庫料資定特與有只上面介取存料資 不 也,試 測 於 易 也 式 程 , 面介於 賴 依 上 計 設 , ) 等 update i nsert d elete 、 、 。術 技 庫 料 資 一 某 用 使能只 於 限 受 式 程 用 應 讓 驟步個幾有,說來程流取存庫料資的際實於對,中式程範示的前之在 不 於 對, 等 外 例 理 處、 得 取、 DataSource 得 取 如 例, 的 定 固 是 Connection 設就,同不程流份部少有只,的同相是上致大驟步些這,術技庫料資的同 於寫撰程流的定固將,式模 用使以可,言而上計 Template-Callback 來件物 Template 由委則,驟步節細些一的同不於對而,中之別類 Callback 有中其於對,程流的定固是份部字體粗非,中段片式程的下以如例,成完 :件物 的 當 適 回 傳 或 行 執 來 件 物 的 別 個作實 以 可 , 份 部 的 異 差 Callback ... Connection conn = null; PreparedStatement stmt = null; try { conn = dataSource.getConnection(); stmt = callback.createPreparedStatement(conn); stmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { if(stmtCallback != null) { try { stmt.close(); }
  • 6. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) catch(SQLException e) { e.printStackTrace(); } } if(conn != null) { try { conn.close(); } catch(SQLException e) { e.printStackTrace(); } } } 於寫撰程流的定固將,式模 Spring 了用運就 Template-Callback 而,)別類 Template 、 如例(中之別類 JdbcTemplate H ibernateTemplate 定 自以可 ( 理 處 來 件 物 援 支 定 特 託 委 則 , 驟步節 細 些 一 的 同 不 於 對 DAO Spring :)生產動自 由或義 圖 5.2 DAO Template 與 DAO Support 應讓,系體理處外例的關無術技定特與供提也 ,面方理處外例在 S pring ,) 、 是像( 外例定特 理處因會不式 程用 SQLException H ibernateException 。術技層 久持或庫 料資種某於合 耦而 6
  • 7. 7 類子的 org.springframework.dao.DataAccessException 是都外例的 有所 S pring , 外 例 的 關相術 技 庫 料 資 與 出 丟 不 並 架 框 的 DAO Spring 。 續 手 的 道 多更要 就 , 層 上 至 出 丟 外例些 這 讓 要 想 果 如 , 掉 理處自暗來 try..catch 些一寫撰行自能只, 之將法無就,) throw Hibernate 是或 JDBC是像,況情種這有而同不術技層底的用使於由能可( 外例的明聲上法方是不些某了生發中法方些這在果如而然,外例的型類些 某 throws 明聲上法方於,時面介義定在會也們它,息訊外例的關相些一括 包,別類外例的關相承繼行自會架框或式程些有,面方一另,意主的好個 一是不也播傳層上向以可外例讓,外例告宣上法方在 用使接直 throws 。 外 例些這 掉 理 處 來 法 語 理 處 外例些一寫撰的何奈可莫好只員人計設式程,理處要定一求要器譯編於由 ,Checked exception 對 面 而然, ) ? 息 訊 的 線 連 法無下 錄 記 如 例 ( 理 處 的 力為能無些一作,中式程取存庫料資的層底在是不而,邊哪在出題問知得 者用使讓,息訊關相示顯以捉捕式程用應層上由,式程用應層上至播傳外 例讓,理處不是就式方理處的好最,)線連得取法無如例(時生發取存庫 料資的層底在外例的類這當,作運常正至復回力無往往 Checked exception 於對,候時有而然,作運常正復回能式程至理處以加以可員人計設式程是 的 望 希, 時 生 發 外 例 類 這 於 對, 的 好 是 來 本 意 立 的 Checked exception 。)面 介 形 圖 者 用 使 如 例(理 處 層 上 最 式 程 用 應至出 丟 接 直 外 例 讓 是 或 ,理處作來 try...catch 用使擇選以可,時生發的真外例,外例的發引所期時 行 執 在 ,誤 錯 的 上 輯 邏 式 程 於 由 是 常 通 , 別 類 子 的 別 類 RuntimeException java.lang. 是上構架承繼外例在,) Runtime exception (外例期時 行執是則 U nckecked exception ;理處以加 try...catch 以上法語在須必此因 ,理處要定一求要器譯編,的生發期預以可是常通外例些這為因,外例的 理 處須必 上 法 語 在 期 時 譯 編 是 C hecked exception 。 Unchecked exception 與 Checked exception 有外例的 ,理處外例解瞭來先首 Java 援支易交、 Chapter 5 JDBC
  • 8. 8 取來 org.springframework.jdbc.datasource.DriverManagerDataSource 供提 Spring ,面介作操的入注 Datasource 個一留保上件物 Bean 的源來接連得取要需在以可,此為,輯邏務商的層上到響影應不為行些這 ,為行的層底是動更的源來料資,等 過透是或、池接連過透、 用 JNDI JDBC 使的綷純如例,源來料資的同不用使能可式程用應,統系的同不應因 。式程行 一 何任改 修 用 不 而 , 置 配 改 修 中 檔 義 定 Bean 在 要只源 來 料 資 換 更 , 入 注 javax.sql.DataSource 了供提 S pring ,求需源來接連料資的同不於對 5.1.2 DataSource 注入 。圖承繼別類的 DataAccessException 個有也,明說的理處 外例對些一有中當,節章 DAO support 的中件文考參 看看以可。捉 Spring 捕 以加外 例 的 理 處 想 對 針 以 可 您 , 等 BadSqlGrammarException 的時誤 錯法語 、 S QL DataAccessResourceFailureException 的出丟會時誤錯結 連庫 料 資 如 例 , 類 分 了 好 作 外 例 將 也 S pring ,外例 的 定 特 理 處 要 果 如 JVM 。 理 處 來 由 後 最 是 或 式程用 應 的 層 上 最 由 , 它 略 忽 者 或 ,它 理 處 擇 選 以 可 您 , 外 例 些 一 於 對 , RuntimeException 自承繼 NestedRuntimeException 而, NestedRuntimeException 的件套 work.core org.springframe- 自 承 繼 它,別 類 礎 基 的 次 層 個 這 是 DataAccessException ,次層理處外例的性致一供提下件套 o rg.springframework.dao ,件物 DAO 外例 的己自為化轉等 SQLException 將 ,取存 S pring 於對 JDBC 。 式程用 應 的 層 上 至 播 傳 外例將 的 單 簡 很 以 可 也 ,下況 情 的 外 例 理 處 不 在 ,理處 要 不 要 擇 選 己 自 以 可 而 , 外 例 理 處 來 try...catch 用使迫強被用不您 ,Unchecked exception 於屬是 它 說 是 就 也 , 別 類 子 的 RuntimeException 是 DataAccessException 且而,外例用通的關無術技庫料資與個一,別 ) – http://openhome.cc 良信林(冊手術技 Spring 2.0
  • 9. Chapter 5 JDBC 援支易交、 ,例實的它得 D riverManagerDataSource 了作實 javax.sql.DataSource 您, :寫撰麼這中檔義定 在以可 Bean ... <beans...> <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> ... </beans> 屬個四 "driverClassName" 、 " url"中其、 、 " username" " password" JDBC 定設來用是別分性 、稱名者用使、定協 庫料資、別類式程動驅 URL 。碼密 前之範示並,範示的入注 為 作 來 式程個 一 用 使 際 實 邊 這 在DataSource :下如面介作操的 個一了義定您設假,作實的紹介 於關有 DAO DAO DataSourceDemo IUserDAO.java package onlyfun.caterpillar; public interface IUserDAO { public void insert(User user); public User find(Integer id); } 有 只 義 定 面 介 的 於 關 邊 這,制 限 的 幅 篇 於 基 DAO insert() 與 find() 兩 : 義 定 下 如 則 別 類 的 到 用 使 所中面 介 個 這 在 。 法 方 個 User
  • 10. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) DataSourceDemo 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; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } 了作實它,別類 個一義定以可著接 UserDAO IUserDAO 實是,面介 : 示 所 下 如 , 件 物 的務服 取 存 庫 料 資 行 進 際 1
  • 11. Chapter 5 JDBC 援支易交、 DataSourceDemo UserDAO.java package onlyfun.caterpillar; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource; public class UserDAO implements IUserDAO { private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public void insert(User user) { String name = user.getName(); int age = user.getAge().intValue(); Connection conn = null; PreparedStatement stmt = null; try { conn = dataSource.getConnection(); stmt = conn.prepareStatement ( "INSERT INTO user (name,age) VALUES(?,?)"); stmt.setString(1, name); stmt.setInt(2, age); stmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { if(stmt != null) { try { stmt.close(); } catch(SQLException e) { e.printStackTrace(); } } 11
  • 12. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) if(conn != null) { try { conn.close(); } catch(SQLException e) { e.printStackTrace(); } } } } 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; } } catch (SQLException e) { e.printStackTrace(); } finally { if(stmt != null) { try { stmt.close(); } 12
  • 13. Chapter 5 JDBC 援支易交、 catch(SQLException e) { e.printStackTrace(); } } if(conn != null) { try { conn.close(); } catch(SQLException e) { e.printStackTrace(); } } } return null; } } UserDAO 入注您讓以可,法方 個一告宣上別類 setDataSource() DataSource :示所下如,義定的入注賴依行進中檔義定 在以可,例實的 Bean DataSourceDemo 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"/> </bean> 13
  • 14. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) <bean id="userDAO" class="onlyfun.caterpillar.UserDAO"> <property name="dataSource" ref="dataSource"/> </bean> </beans> 作 操 來 式 程 試測的 單 簡 個 一 寫 撰 以 可 UserDAO 能否是看看,例實的 :詢查 與 存 儲 的 料 資 行 進 DataSourceDemo SpringDAODemo.java package onlyfun.caterpillar; import org.springframework.context.ApplicationContext; import org.springframework.context. support.ClassPathXmlApplicationContext; public class SpringDAODemo { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "beans-config.xml"); User user = new User(); user.setName("caterpillar"); user.setAge(new Integer(30)); IUserDAO userDAO = (IUserDAO) context.getBean("userDAO"); userDAO.insert(user); user = userDAO.find(new Integer(1)); System.out.println("name: " + user.getName()); } } 14
  • 15. Chapter 5 JDBC 援支易交、 將並,務服庫料資啟開先要您,前之試測的式程行進在 beans- 與 稱 名 者 用 使、 庫 料 資、別 類 式 程 動 驅 的 關 相 中 config.xml URL 而,庫 料 資 是 的 用 使 所 邊 這 在,定 設 的 您 為 改 修 等 碼 密 MySQL user :的立建來 的下以用使是格表 的立建 SQL CREATE TABLE user ( id INT(11) NOT NULL auto_increment PRIMARY KEY, name VARCHAR(100) NOT NULL default '', age INT ); 據根著接,料資筆一入存中格表 的庫料資在先會果結行執的式程 user id 。字文的 示顯會果結後最,料資的入存所前先出詢查值 "name: caterpillar" 、 、 spring-core.jar 、 要需您 s pring-beans.jar s pring-context.jar spring-dao.jar spring-jdbc.jar 是 的 用 使 您 果 如,案 檔 個 幾 這 與 的依相要需也外另, 關相了括包經已中當, spring.jar API 有 要 須 必 您, 用 使 了 為,然 當, commons-logging.jar JDBC JDBC jar 。案檔 的式程動驅 5.1.3 DataSource 置換 單簡作來用是只,能功的池接連供提有沒並 DriverManagerDataSource 以 用 使 以 可 您。中 之 案 專 的 正 真 於 用 使 合 適 不 並,試 測 接 連 機 單 的 DBCP 程改修要需不並 換置則, 用使果如。能功的池接連得獲 Spring DataSource 下一改修如例,了以可就檔義定 改修要只,碼始原式 Bean DataSourceDemo beans-config.xml :下如 的中案專 1
  • 16. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) <?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.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <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="userDAO" class="onlyfun.caterpillar.UserDAO"> <property name="dataSource" ref="dataSource"/> </bean> </beans> 是的用使所在現 org.apache.commons.dbcp.BasicDataSource 作 在要需您,能功的 用使了為,例實 DataSource 的入注為 DBCP Classpath 與 、 定設中徑路 commons-dbcp.jar c ommons-pool.jar commonscollec- 。到找下錄目 的中本版依相的 tions.jar 在以可都些這, Spring lib 確以可此如,性屬 了定設上 dataSource在到意注 "destroy-method" 。 BeanFactory 閉關併一也時閉關在 保 BasicDataSource ) ( 了供提器容 Servlet 果如 JNDI J ava Naming and Directory Interface : DataSource個這上換的單簡以可也, 的 DataSource 16
  • 17. Chapter 5 JDBC 援支易交、 ... <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="jdbc/demo"/> </bean> ... 用使了為 org.springframework.indi.JndiObjectFactoryBean 需您, 要 , spring-context.jar " jndiName" 的定設所據根要上際實 JNDI ,稱名詢查 在如例 Tomcat 於以可中 server.xml :定設麼這 ... <!—- 是錄目式程用應設假 JSP --> <Context path="/JSP" docBase="JSP"> <!-- 是稱名庫料資用使 GUESTBOOK --> <Resource name="jdbc/demo" scope="Shareable" type="javax.sql.DataSource"/> <ResourceParams name="jdbc/demo"> <parameter> <name>factory</name> <value> org.apache.commons.dbcp.BasicDataSourceFactory </value> </parameter> <!-- DBCP database connection settings --> <!-- JDBC URL --> <parameter> <name>url</name> <value>jdbc:mysql://localhost/demo</value> </parameter> <!-- JDBC 式程動驅 --> <parameter> <name>driverClassName</name> <value>com.mysql.jdbc.Driver</value> </parameter> <!-- 碼密與者用使庫料資 --> <parameter> <name>username</name> <value>caterpillar</value> 17
  • 18. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) </parameter> <parameter> <name>password</name> <value>123456</value> </parameter> <!-- DBCP connection pooling options --> <!-- 待等 Connection 制限不表 , 位單,間時的ms -1 --> <parameter> <name>maxWait</name> <value>3000</value> </parameter> <!-- 可多最中池接連 idle ,數 Connection 的 的少最是就也 Connection 制限不表 ,數0 --> <parameter> <name>maxIdle</name> <value>10</value> </parameter> <!-- 的多至池接連 Connection 0 制限不示表 ,數 --> <parameter> <name>maxActive</name> <value>100</value> </parameter> </ResourceParams> </Context> ... 18
  • 19. Chapter 5 JDBC 援支易交、 5.2 JDBC 支援 用使在 JDBC 如例,節細的瑣繁理處要是總,時 、 Connection S tatement 、得獲的 、 S QLException 、理處的 C onnection S tatement ,題問等閉關的 在 Spring JDBC 化簡以可,別類個幾了供提上用使的 JDBC 。程流的時用使 5.2.1 使用 JdbcTemplate 使接直中 ,中案專 的紹 介 中 節 小 個 一 前 在 DataSourceDemo U serDAO 、得取的 JDBC 理處要中當,法方 insert() find()與 作實來 用 Connection ,等 閉關的 Statement 、閉關的 、理處的外例、立建的 S tatement C onnection 這 作須必 都 次 一 每 , 的 異 小同大 是 程 流 些 這 , 取 存 JDBC 的本基個一於對 。煩厭 人 令 實 著 程 流 的 樣 類 Spring 了供提 org.springframework.jdbc.core.JdbcTemplate 法 方作操 些 一 的 供 提 所 中 當 , ) ( 全 安緒行 執 為 計 設 被 它 , 別 T hread-safe 可別類 的中案專 如例,程流的上以似類了裝封 DataSourceDemo UserDAO 須必,例實的 立建要,寫改來 JdbcTemplate 用使的單簡以 JdbcTemplate :件 物 的 時 構 建 為 作 件 物 DataSource 個一有要 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); 到看以可,作實容內的 中案專 DataSourceDemo 下一寫改來UserDAO : 進 改 的 樣 麼 什 有會上 程 流 寫 撰 的 式 程 在 , 時 JdbcTemplate 用使 1
  • 20. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) JdbcTemplateDemo UserDAO.java package onlyfun.caterpillar; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; public class UserDAO implements IUserDAO { private JdbcTemplate jdbcTemplate; public void setDataSource(DataSource dataSource) { jdbcTemplate = new JdbcTemplate(dataSource); } public void insert(User user) { String name = user.getName(); int age = user.getAge().intValue(); jdbcTemplate.update("INSERT INTO user (name,age) " + "VALUES('" + name + "'," + age + ")"); } public User find(Integer id) { List rows = jdbcTemplate.queryForList( "SELECT * FROM user WHERE id=" + id.intValue()); Iterator it = rows.iterator(); if(it.hasNext()) { Map userMap = (Map) it.next(); Integer i = new Integer(userMap.get("id").toString()); String name = userMap.get("name").toString(); Integer age = new Integer(userMap.get("age").toString()); User user = new User(); user.setId(i); user.setName(name); user.setAge(age); 2
  • 21. Chapter 5 JDBC 援支易交、 return user; } return null; } } ,動變用不都檔定設與式程的它其,了以可就 寫改要只 UserDAO Spring 由藉是要主,的示所稱名其如一 JdbcTemplate 的 Template Method 。裝封程流理處的 JDBC 現實來式模 用使果如 Hibernate) ( 的類之 ORM O bject-Relational Mapping 則,具 工 find() 一進以可還換轉的型模式聯關與型模件物中法方 。化簡的步 了除,用使來 Spring 於立獨以可上本基能功等裝封 JDBC 的 Spring 對是像,別類 JdbcTemplate 的它其了供提還S pring ,外之 Template , 面方理 處 易 交 的 庫 料 資 在 。 現 實 Hibernate J DO i Batis 的等 、 、 Template 雜 複的式 程 層 久 持 了 化 簡 ,能功 理 管 易 交 的 式 告 宣 與 式 程 編 了 供 提 Spring 。 性 護維的 好 更 了 供 提 並 , 度 5.2.2 JdbcTemplate 執行與更新 用使以可您 JdbcTemplate 的 execute() 行執法方 SQL :如例,述陳 jdbcTemplate.execute( "CREATE TABLE USER (user_id integer, name varchar(100))"); 是果如 用使以可您, UPDATE 或 INSERT update() 重個數有它,法方 (載 Overload 作實受接如例,本版) org.springframework.jdbc. 21
  • 22. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) core.PreparedStatementCreator ,件物的面介 P reparedStatementCreator 介 :下如義定的面 package org.springframework.jdbc.core; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public interface PreparedStatementCreator { PreparedStatement createPreparedStatement(Connection con) throws SQLException; } 將以可如例 5.2.1 的 JdbcTemplateDemo 中案專 UserDAO 的 insert() 方 :下如寫改法 ... public void insert(User user) { final String name = user.getName(); final int age = user.getAge().intValue(); jdbcTemplate.update( new PreparedStatementCreator() { public PreparedStatement createPreparedStatement( Connection con) throws SQLException { String sql = "INSERT INTO user (name,age) VALUES(?,?)"; PreparedStatement ps = con.prepareStatement(sql); ps.setString(1, name); ps.setInt(2, age); return ps; } }); } ... 22
  • 23. Chapter 5 JDBC 援支易交、 備準 來 了用 使,中子例個 這在 PreparedStatement SQL , J dbcTemplate 而,程流 了現實中法 方 ,制機 Template-Callback 了現實 u pdate() Template ,中程流的 行執在,件物 PreparedStatementCreator了現 實則 Callback JDBC 方 是就也, 法 方 的義 定所行執會時 要必 callback createPreparedStatement() 的中 法 方 成完以,件 物 PreparedStatement 個一回傳 ,法 update() Template 。 程流 是面介的補互 PreparedStatementCreator 與 org.springframework.jdbc. :面介 core.PreparedStatementSetter package org.springframework.jdbc.core; import java.sql.PreparedStatement; import java.sql.SQLException; public interface PreparedStatementSetter { void setValues(PreparedStatement ps) throws SQLException; } 將以可如例 JdbcTemplateDemo 中案專 UserDAO 的 insert() :下如寫改法方 ... public void insert(User user) { final String name = user.getName(); final int age = user.getAge().intValue(); jdbcTemplate.update( "INSERT INTO user (name,age) VALUES(?,?)", new PreparedStatementSetter() { public void setValues(PreparedStatement ps) throws SQLException { ps.setString(1, name); ps.setInt(2, age); } }); } ... 23
  • 24. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 立建動自會JdbcTemplate PreparedStatementCreator 供提以,例實的 的法方 給遞傳 setValues() PreparedStatement 。件物 如就, 供提接直以可也您 SQL JdbcTemplateDemo 的範示所中案專 :法方 UserDAO 的中 insert() ... public void insert(User user) { String name = user.getName(); int age = user.getAge().intValue(); jdbcTemplate.update("INSERT INTO user (name,age) " + "VALUES('" + name + "'," + age + ")"); } ... 陣 件 物 用 使 並, 元 字 位 佔 為 作 用 使 以 可 也 , 時 句 語 下 接 直 在 SQL "?" 寫改如例,法方 的 JdbcTemplate 給遞 傳 數 引 為 作 列 update() JdbcTemplate- Demo :法方 的中 UserDAO 的範示所中案專 insert() ... public void insert(User user) { jdbcTemplate.update( "INSERT INTO user (name, age) VALUES(?,?)", new Object[] {user.getName(), user.getAge()}); } ... JdbcTemplate 與 立建動自會 PreparedStatementCreator Prepared- StatementSetter 數引與 供提要只,會理用不您節細些這而然,例實的 SQL 。了好就 作實以可,時理處次批要需果如 org.springframework.jdbc.core.Batch- :面介 PreparedStatementSetter 24
  • 25. Chapter 5 JDBC 援支易交、 package org.springframework.jdbc.core; import java.sql.PreparedStatement; import java.sql.SQLException; public interface BatchPreparedStatementSetter { void setValues(PreparedStatement ps, int i) throws SQLException; int getBatchSize(); } 在以可 如例 JdbcTemplateDemo 及面介 的中 案 專 IUserDAO UserDAO 個一加增上別類 insertUsers() : 容 內 的 下 以 是 像 ,作 實 與 義 定 的 法 方 ... public int[] insertUsers(final List users) { String sql = "INSERT INTO user (name,age) VALUES(?,?)"; BatchPreparedStatementSetter setter = new BatchPreparedStatementSetter() { public void setValues( PreparedStatement ps, int i) throws SQLException { User user = (User) users.get(i); ps.setString(1, user.getName()); ps.setInt(2, user.getAge().intValue()); } public int getBatchSize() { return users.size(); } }; return jdbcTemplate.batchUpdate(sql, setter); } ... 果如 JDBC 果如 , 能 功 的 它 用 使 接直則 , 話 的 理 處 次 批 援 支 式 程 動 驅 則,援支不 Spring 。 理 處 次 批 擬 模以新 更 理 處 個 一 個 一 動 自 會 2
  • 26. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 5.2.3 JdbcTemplate 查詢 用使 JdbcTemplate 用使以可,時詢查行進 queryForXXX() ,法方等 用使如例 queryForInt() :數筆料資的中格表 回傳法方 user jdbcTemplate.queryForInt("SELECT COUNT(*) FROM user"); 用使以可也 queryForObject() 回傳 如 例 , 件 物 果 結 的 後 詢 查 個 一 回 傳 :件物 個一 String String name = (String) jdbcTemplate.queryForObject( "SELECT name FROM USER WHERE id = ?", new Object[] {id}, java.lang.String.class); 使以可則,料資筆多回傳果如,料資筆一單是都的回傳子例個兩面上 :如例,法方 queryForList() 用 List rows = jdbcTemplate.queryForList( "SELECT * FROM user WHERE id=" + id.intValue()); 的中果結詢查表代件物 個每,件物 是的括包中 的回傳 List Map Map 位欄用使要,值的中位欄得取要,容內位欄個多括包料資筆每,料資筆一 " :如例, ) (鍵 為作稱名 K ey " ... Iterator it = rows.iterator(); while(it.hasNext()) { Map userMap = (Map) it.next(); System.out.println(userMap.get("id")); System.out.println(userMap.get("name")); System.out.println(userMap.get("age")); ... } ... 26
  • 27. Chapter 5 JDBC 援支易交、 作實以可您 org.springframework.jdbc.core.RowCallbackHandler 介 下一改修如例,回傳再理處些一作先後之料資到詢查在,面 5.2.1 的 在,下如法方 的 JdbcTemplateDemo中案專 UserDAO find() RowCallback- ( Handler 的單簡作實中法方 的 processRow() ORM O bject-Relational Mapping :作動) ... public User find(Integer id) { final User user = new User(); jdbcTemplate.query( "SELECT * FROM user WHERE id = ?", new Object[] {id}, new RowCallbackHandler() { public void processRow(ResultSet rs) throws SQLException { user.setId(new Integer(rs.getInt("id"))); user.setName(rs.getString("name")); user.setAge(new Integer(rs.getInt("age"))); } }); return user; } ... 作實先以可則,件物的果結詢查多很回取要次一果如 org.springframe- :如例,面介 work.jdbc.core.RowMapper package onlyfun.caterpillar; import java.sql.ResultSet; import java.sql.SQLException; import org.springframework.jdbc.core.RowMapper; public class UserRowMapper implements RowMapper { public Object mapRow(ResultSet rs, 27
  • 28. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) int rowNum) throws SQLException { User user = new User(); user.setId(new Integer(rs.getInt("id"))); user.setName(rs.getString("name")); user.setAge(new Integer(rs.getInt("age"))); return user; } } 在 Spring 2.0 ,中 詢查,除移被經已別類作實其與面介 R esultReader 受接接直在現法方 RowMapper :時法方 用使如例,例實 queryForObject() ... public User find(Integer id) { User user = (User) jdbcTemplate.queryForObject( "select * from user where id=?", new Object[] {id}, new UserRowMapper()); return user; } ... 用使已果結的回傳 UserRowMapper 為裝封之將,義定的 User 。件 物 :範示個一的時法方 用使是下以 query() List users = jdbcTemplate.query("select * from user", new UserRowMapper()); for(int i = 0; i < users.size(); i++) { User user = (User) users.get(i); System.out.println("tId:t" + user.getId()); System.out.println("tName:t" + user.getName()); System.out.println("tAge:n" + user.getAge()); } 28
  • 29. Chapter 5 JDBC 援支易交、 為 裝封 已 並,果 結 的 來出詢 查 中 庫 料 資 從 了 括 包,中 件 物 的 回 傳 List User 。例實的別類 5.2.4 JdbcTemplate 的 Lob 支援 ( 與 J DBC) ( 用使以可中 在 C lob C haracter large object B lob B inary large 透以可中 object 。存儲行進案檔位進二與案檔字文對針別分以,) S pring 如 例(庫 料 資 定 特 理 處 免 避 以 , JdbcTemplate 與 CLOB 理處來 BLOB 過 資 的 您 設 假 , 說 來 子 例 個 舉 。 題 問 異 差 、 的) Oracle 9i Clob B lob MySQL :下如格表庫料 CREATE TABLE test ( id INT AUTO_INCREMENT PRIMARY, txt TEXT, image BLOB ); 料資至存儲之將想並,案檔位進二與案檔字文個一進讀別分在現設假 :如例, 用使以可則,中庫 JdbcTemplate final File binaryFile = new File("wish.jpg"); final File txtFile = new File("test.txt"); final InputStream is = new FileInputStream(binaryFile); final Reader reader = new FileReader(txtFile); JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); final LobHandler lobHandler = new DefaultLobHandler(); jdbcTemplate.execute("INSERT INTO test (txt, image) VALUES(?, ?)", new AbstractLobCreatingPreparedStatementCallback(lobHandler) { protected void setValues(PreparedStatement pstmt, LobCreator lobCreator) throws SQLException,DataAccessException { lobCreator.setClobAsCharacterStream( pstmt, 1, reader, (int) txtFile.length()); 2
  • 30. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) lobCreator.setBlobAsBinaryStream( pstmt, 2, is, (int) binaryFile.length()); } }); reader.close(); is.close(); ,時件物 立建在 AbstractLobCreatingPreparedStatementCallback 或 ( 於對,例實 LobHandler 個一遞傳要 MySQL M S SQL Server Oracle 的定特 10g 於對,可即 用使邊這,) DefaultLobHandler Oracle 9i LOB 用使,中作實法方 在。 OracleLobHandler用使以可,理處 setValues() 與一第示表 、 引索,流串源來的 與 定設別分來 LogCreator Blob Clob 1 2 。度 長 取 讀 定 指 並 , 置 位 的 元 字 位 佔 個 二 第 ' ?' 的下以用使以可,案檔為存另並,來出取讀料資將中庫料資從要果如 :式程 final Writer writer = new FileWriter("test_bak.txt"); final OutputStream os = new FileOutputStream(new File(wish_bak.jpg")); jdbcTemplate.query("SELECT txt,image FROM test WHERE id = ?", new Object[] {new Integer(1)}, new AbstractLobStreamingResultSetExtractor() { protected void streamData(ResultSet rs) throws SQLException, IOException, DataAccessException { FileCopyUtils.copy( lobHandler.getClobAsCharacterStream(rs, 1), writer); FileCopyUtils.copy( lobHandler.getBlobAsBinaryStream(rs, 2), os); } }); writer.close(); os.close(); 用使邊這在 FileCopyUtils 的 copy() 將,法方 LogHandler 流串的得取 出輸案檔給接轉接直 FileWriter 、 F ileOutputStream 。件物 3
  • 31. 31 sf.run(); sf.compile(); dataSource, "SELECT COUNT(*) from user"); SqlFunction sf = new SqlFunction( : 子 例 個 一是面 下 , 數 筆 料 資 的 到詢查 示 表 數 整 個 一 傳 回 後然, COUNT() 行執以可如例, SQL Function 行執來用 SqlFunction 。例 實的 別類些這用使複重下境環的緒行執多在以可以所,) (全安緒行 T hread-safe 執為計設被們它,別類等 org.springframework.jdbc.object.MappingSqlQuery 、 org.springframework.jdbc.object.SqlUpdate 類 子其用使 以可您,作操 等序 程存 預、新更、詢 查的 ) R elational Database Management System ( RDBMS 表代,類象抽個是 org.springframework.jdbc.object.RdbmsOperation 。作操關相庫料 資行進來法方的它行執,例實個這用利複重以可就後之,譯編並別類的應 對相化例實接直或承繼先事要只,式程的面方作操庫料資計設來式方的向 導件物更以您讓,件套 org.springframework.jdbc.object 供提 Spring 。 式方作操的向 導件 物近接更 作操庫料資, 看來點觀 的們他從,節 細的 到 觸接須無就 們他 SQL ,用使員人發開給件物用重可的成完計設些這將,時計設庫料資行進在後之 立建, 件物作操的用 重可立建步一進以 可您, 中 在 , 些某 用重 Spring SQL SQL 是或,法語 到觸接用不員人發開式程些一讓想果如,法語 用使何 SQL 如悉熟須仍法方 個各的 JdbcTemplate 而然,術 技庫料資 的層底觸接用 不您 讓,節細 的理 處 JDBC 了裝 封它,看來法 方個各 的 上 就 JdbcTemplate 5.2.5 以物件方式進行操作 援支易交、 Chapter 5 JDBC
  • 32. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 數參關相及以 、 RdbmsOperation 好定設在別類子的 DataSource S QL 在 ,例實 個 這 用 使 複 重 以 可 就 後 之 , 譯 編 行 進 compile() 行執 先 須 必 , 後 中 改修如例, 裝封來 SqlFunction SQL 承繼以可時計設 5.2.1 JdbcTemplate- Demo :示 所 下 如 別 類 個 一 增 新 , 容 內 的 案 專 RdbmsDemo UserFunction.java package onlyfun.caterpillar; import javax.sql.DataSource; import org.springframework.jdbc.object.SqlFunction; public class UserFunction extends SqlFunction { public UserFunction(DataSource dataSource) { super(dataSource, "SELECT COUNT(*) from user"); compile(); } } 參關相定設以可也您,作操新更的 個一示表來用別類 SqlUpdate SQL : 如 例 , 裝 封 的 行 進 來 它承繼 以 可 也 時 計 設 , 數 SQL RdbmsDemo UserUpdate.java package onlyfun.caterpillar; import java.sql.Types; import javax.sql.DataSource; import org.springframework.jdbc.object.SqlUpdate; public class UserUpdate extends SqlUpdate { public UserUpdate(DataSource dataSource) { super(dataSource, "INSERT INTO user (name,age) VALUES(?,?)"); int[] types = {Types.VARCHAR, Types.INTEGER}; 32
  • 33. Chapter 5 JDBC 援支易交、 setTypes(types); compile(); } } ,型 類 據 數 的 入 插 要 所 元 字 位 佔 中 定 設 來 用 法 方 setTypes() SQL "?" 每 ,詢查 行 進 來 數 引 為 作 列陣件 物 定 指 僅 以 可 , 時 法 方 update() 行執後之 : 用 使 麼 這 以 可 如 例 , 元 字 位 佔 代取 際 實 將 值 列 陣 個 一 "?" ... SqlUpdate userUpdate = new UserUpdate(dataSource); ... userUpdate.update( new Object[] {user.getName(), user.getAge()}); ,別類個這用使接直少很常通但,作操詢查 個一示表別類 SqlQuery SQL 以可,例實的別類 為裝封如例,理處些一作會,後之料資到詢查為因 User 來 別類子的它用使 org.springframework.jdbc.object.MappingSqlMapping :如 例 , 作 動 個 這 行 進 RdbmsDemo UserQuery.java package onlyfun.caterpillar; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource; import org.springframework.jdbc.object.MappingSqlQuery; public class UserQuery extends MappingSqlQuery { public UserQuery(DataSource dataSource) { super(dataSource, "SELECT * FROM user"); compile(); } protected Object mapRow(ResultSet rs, 33
  • 34. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) int rowNum) throws SQLException { User user = new User(); user.setId(new Integer(rs.getInt("id"))); user.setName(rs.getString("name")); user.setAge(new Integer(rs.getInt("age"))); return user; } } : 它 用 使 麼 這 以 可,後 之 別 類 個 這 好 計 設 ... SqlQuery userQuery = new UserQuery(dataSource); ... List users = userQuery.execute(); 的回傳上際實,後法方 execute() 完行執 List 有會中 User ,例實的別類 。 料 資 筆 一 每的後 詢 查 了 裝 封 並 中 當 下 一 寫 改 再 以 可,作 實 個 幾 的 上 以 合 配 IUserDAO 與面介 UserDAO :如例,作實 RdbmsDemo IUserDAO.java package onlyfun.caterpillar; import java.util.List; public interface IUserDAO { public void insert(User user); public List allUser(); public int count(); } 34
  • 35. Chapter 5 JDBC 援支易交、 程的面方取存庫料資責負員人發開的他其有,員人發開式程是您設假 您 則,別 類 與 、 的 上 以 了 供 提 並,式 UserFunction U serUpdate UserQuery 、 用重以可,寫撰何如是 的際實心關用不就 SQL UserFunction U serUpdate :別類 UserQuery 的您計設來別類 與 UserDAO RdbmsDemo UserDAO.java package onlyfun.caterpillar; import java.util.List; import javax.sql.DataSource; import org.springframework.jdbc.object.SqlFunction; import org.springframework.jdbc.object.SqlQuery; import org.springframework.jdbc.object.SqlUpdate; public class UserDAO implements IUserDAO { private SqlUpdate userUpdate; private SqlQuery userQuery; private SqlFunction userFunction; public void setDataSource(DataSource dataSource) { userUpdate = new UserUpdate(dataSource); userQuery = new UserQuery(dataSource); userFunction = new UserFunction(dataSource); } public void insert(User user) { userUpdate.update( new Object[] {user.getName(), user.getAge()}); } public List allUser() { return userQuery.execute(); } public int count() { return userFunction.run(); } } 3
  • 36. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 物是 全 完 , 看 來 度 角 的 寫 撰 式 程 SQL 從,後之用重裝封 將 UserDAO 作運看看來式程的單簡個寫以可,改修的式程合配,行進來式方的作操件 :常正否是 RdbmsDemo SpringDAODemo.java package onlyfun.caterpillar; import org.springframework.context.ApplicationContext; import org.springframework.context. support.ClassPathXmlApplicationContext; import java.util.List; public class SpringDAODemo { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "beans-config.xml"); User user = new User(); user.setName("just933"); user.setAge(new Integer(26)); IUserDAO userDAO = (IUserDAO) context.getBean("userDAO"); userDAO.insert(user); System.out.println(" 數筆 : " + userDAO.count()); List list = userDAO.allUser(); for(int i = 0; i < list.size(); i++) { User next = (User) list.get(i); System.out.println("ntId:t" + next.getId()); System.out.println("tName:t" + next.getName()); System.out.println("tAge:t" + next.getAge()); } } } 36
  • 37. Chapter 5 JDBC 援支易交、 、 UserDAO 、 的中 UserUpdate 麼什為 U serQuery U serFunction 觀 個 一 有 還,外 之 作 實 例 範 化 簡 了 除 ? 呢 入 注 賴 依 用 使 不 等 IoC 依 個 來 要 都 一 十 二 七 三 管 不 件 物 個 每 ! 而 了 為 要 不:念 IoC IoC 的 長 冗 堆 大 一 有 會 將,上 件 物 的 賴 依 入 注 被,話 的 入 注 賴 Setter ,時賴依的同相入注要需件物的上以個兩有,是的議建。法方 。入注賴依行進來器容 Spring IoC 用使慮考才 5.2.6 DataFieldMaxValueIncrementer 與是好最置設的鍵主,鍵主定設要需會您,時中庫料資至料資入插在 用使以可您,中 在,關無值鍵務商 Spring org.springframework.jdbc. ,值鍵主生產您為來 support.incrementer.DataFieldMaxValueIncrementer 如例,例實的庫料資同不對針多許有 DataFieldMaxValueIncrementer 、 、 DB2SequenceMaxValueIncrementer H sqlMaxValueIncrementer M ySQL- 、 MaxValueIncrementer 、 OracleSequenceMaxValueIncrementer Postgre- 、 的它作操以可您, SQLSequenceMaxValueIncrementer nextIntValue() 。值鍵主個一下生產來 nextLongValue() 或 nextStringValue() 5.2.7 Spring 2.0 的 NamedParameterJdbcTemplate 您讓,別類 Spring 2.0 了增新中 在 NamedParameterJdbcTemplate 名命的際實用使是而, 元字位佔用使必不,時述陳 的 JDBC SQL 寫撰在' ?' 您本原 如 例 , 份 部 料 資 的 動 變 會 中 留 保 來 ) N amed parameter SQL (數參 :詢 查 個 一 寫 撰 麼 這 是 String sql = "SELECT * FROM user WHERE id=?"; List rows = jdbcTemplate.queryForList(sql, new Object[] {id.intValue()}); 37
  • 38. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 用使以可在現 NamedParameterJdbcTemplate :式方的下以為寫改 String sql = "SELECT * FROM user WHERE id=:userId"; SqlParameterSource namedParameters = new MapSqlParameterSource("userId", id); NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource); List rows = jdbcTemplate.queryForList(sql, namedParameters); 用使是邊這在,式方定指的值際實 ":userId" 數參名命到意注 以可也您。值際實與數參名命定指接直時構建在, SqlParameterSource Map : 如 例,值 際 實 的 數 參 名 命 個 多 定 指 來 件 物 用 使 String sql = "INSERT INTO user (name,age) VALUES(:userName, :userAge)"; Map namedParameters = new HashMap(); namedParameters.put("userName", name); namedParameters.put("userAge", age); NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource); jdbcTemplate.update(sql, namedParameters); 個一據根以可也您 POJO ( P lain Old Java Object 名命為作值的件物) :如 例 , 據 依 的 值 數 參 String sql = "INSERT INTO user (name,age) VALUES(:name, :age)"; SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(user); NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource); jdbcTemplate.update(sql, namedParameters); 中其 " user" 是件物的考參所 JdbcTemplateDemo 。例實 的中案專 User 將體具下以 的案專 JdbcTemplateDemo UserDAO 用使為寫改,別類 NameParameterJdbcTemplate :式方的 38
  • 39. Chapter 5 JDBC 援支易交、 NamedParameterDemo UserDAO.java package onlyfun.caterpillar; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.springframework.jdbc.core.namedparam .BeanPropertySqlParameterSource; import org.springframework.jdbc.core.namedparam .MapSqlParameterSource; import org.springframework.jdbc.core.namedparam .NamedParameterJdbcTemplate; import org.springframework.jdbc.core.namedparam.SqlParameterSource; public class UserDAO implements IUserDAO { private NamedParameterJdbcTemplate jdbcTemplate; public void setDataSource(DataSource dataSource) { jdbcTemplate = new NamedParameterJdbcTemplate(dataSource); } public void insert(User user) { String sql = "INSERT INTO user (name,age) VALUES(:name, :age)"; SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(user); jdbcTemplate.update(sql, namedParameters); } public User find(Integer id) { String sql = "SELECT * FROM user WHERE id=:userId"; SqlParameterSource namedParameters = new MapSqlParameterSource("userId", id); List rows = jdbcTemplate.queryForList(sql, namedParameters); Iterator it = rows.iterator(); if(it.hasNext()) { Map userMap = (Map) it.next(); Integer i = new Integer(userMap.get("id").toString()); 3
  • 40. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) String name = userMap.get("name").toString(); Integer age = new Integer(userMap.get("age").toString()); User user = new User(); user.setId(i); user.setName(name); user.setAge(age); return user; } return null; } } 5.2.8 Spring 2.0 的 SimpleJdbcTemplate 中 用利以可則,本版的上以 是 的用使您果如 JDK 5.0 Spring 2.0 這是能可您來原如例,能功) (型泛的供提所 SimpleJdbcTemplate G eneric :料資詢查麼 public User find(Integer id) { String sql = "SELECT * FROM user WHERE id=?"; RowMapper mapper = new RowMapper() { public Object mapRow(ResultSet rs, int rowNum) throws SQLException { User user = new User(); user.setId(new Integer(rs.getInt("id"))); user.setName(rs.getString("name")); user.setAge(new Integer(rs.getInt("age"))); return user; } }; JdbcTemplate simpleJdbcTemplate = new JdbcTemplate(this.getDataSource()); 4
  • 41. Chapter 5 JDBC 援支易交、 return (User) jdbcTemplate.queryForObject(sql, mapper, id); } 用改若 SimpleJdbcTemplate :寫撰下如以可則, public User find(Integer id) { String sql = "SELECT * FROM user WHERE id=?"; ParameterizedRowMapper<User> mapper = new ParameterizedRowMapper<User>() { public User mapRow(ResultSet rs, int rowNum) throws SQLException { User user = new User(); user.setId(new Integer(rs.getInt("id"))); user.setName(rs.getString("name")); user.setAge(new Integer(rs.getInt("age"))); return user; } }; SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(this.getDataSource()); return simpleJdbcTemplate.queryForObject(sql, mapper, id); } 在接直以可,能功的型泛到用使中當,到意注以可 mapRow()之法方 的 User 而,例實 回傳後 SimpleJdbcTemplate queryForObject() 以可也法方 將下以。例實 的果結詢查回傳接直 User JdbcTemplateDemo 的案專 :式方的 UserDAO 用使為寫改 SimpleJdbcTemplate SimpleJdbcTemplateDemo UserDAO.java package onlyfun.caterpillar; import java.sql.ResultSet; import java.sql.SQLException; import javax.sql.DataSource; import org.springframework.jdbc.core.simple.ParameterizedRowMapper; import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; 41
  • 42. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) public class UserDAO implements IUserDAO { private SimpleJdbcTemplate jdbcTemplate; public void setDataSource(DataSource dataSource) { jdbcTemplate = new SimpleJdbcTemplate(dataSource); } public void insert(User user) { String sql = "INSERT INTO user (name,age) VALUES(?, ?)"; String name = user.getName(); Integer age = user.getAge(); jdbcTemplate.update(sql, new Object[] {name, age}); } public User find(Integer id) { String sql = "SELECT * FROM user WHERE id=?"; ParameterizedRowMapper<User> mapper = new ParameterizedRowMapper<User>() { public User mapRow(ResultSet rs, int rowNum) throws SQLException { User user = new User(); user.setId(new Integer(rs.getInt("id"))); user.setName(rs.getString("name")); user.setAge(new Integer(rs.getInt("age"))); return user; } }; return jdbcTemplate.queryForObject(sql, mapper, id); } } 42
  • 43. 43 :如例 ,行執的有所消撤來 rollback() 行執 則 , 誤 錯 生 發間中 果 如 , 更 變 出 送 來 commit()的 Connection 行執行自,後句語 的串連一達下在,數引 SQL false 它 定 給,法 方 setAutoCommit() 的 Connection 作 操 以 可,中 在,現 JDBC 實性 子 原 的 易 交 看 看 來先首 。 理 管 易 交 用 使 何 如 紹介將邊這在JDBC 。 的 來下錄 記 被 是 須 必 易 交 筆 這,後之易交筆一某在,) D urable (的續持可是須必還易交。在存的此彼 到識意需不上本基易交個兩,作動的款提與款存行進時同易交筆兩有能可 A 中戶帳 在如例,) I solated ( 的 離 隔 是 須 必 間 之此 彼 易 交 個 每 。 額 金 的 A B 款 存 戶 帳 於 大 能 不 額 金 的 款 取 戶 帳 ,額 金 帳 轉的 戶 帳個 兩 ,中 子 例 的 戶帳行銀在如例,) C onsistent (性致一的源資與參所持保須必還易交 。 敗 失 帳 轉 次 此 則,敗 失 作 動 個 一 有 果 如 ,功成須必作動個兩,額金的帳轉上加戶帳的行銀 在、款扣戶帳的行銀 B A B 從為作動的作要,行銀 至帳轉行銀 從戶客個一,子例的單簡個舉 A SQL 。消撤令指 的過行執有所前先則, 誤錯有 行一中其如例(因原個 ) SQL SQL 某為因 若 , 功 成 行 執 部 全 須 必 令 指 組 一 這 , 令 指 組 一 是 就 , 說 SQL 來 例 實 的 取 存 庫 料 資 以 , 元 單 作 工 的 作 操) A tomic (子 原 組 一 是 易 交 5.3.1 Spring 對交易的支援 。理管易交的 Spring 紹介,例為易交 JDBC 以 節這, 型 模 程 編 的 致 一 了供提 作 實 易 交 的 同 不 為 ,) D eclarative transaction management (理管易交的式告宣與) ment P rogrammatic transaction manage- (理 管易 交 的式 程編供提 Spring 5.3 JDBC 交易管理 援支易交、 Chapter 5 JDBC
  • 44. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) try { ..... connection.setAutoCommit(false); ..... // 串連一 SQL 作操 connection.commit(); } catch(SQLException) { // 更變有所消撤,誤錯生發 connection.rollback(); } 在 Spring 對中 JDBC ,裝封以加理管易交的 S pring 其象抽的理管易交 於在 鍵關 org.springframework.transaction.PlatformTransactionManager :現實的面介 ... public interface PlatformTransactionManager { TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; void commit(TransactionStatus status) throws TransactionException; void rollback(TransactionStatus status) throws TransactionException; } 如例,別類現實易交的體具多許有面介 PlatformTransactionManager 、 、 DataSourceTransactionManager H ibernateTransactionManager J doTrans- 於賴依由藉,等 actionManager J taTransactionManager 、 PlatformTran- 發 開讓 以 可 上 理 管 易 交 在 sactionManager ,現實術技的種各及面介 S pring 。 術 技 理 管 易 交 的 同不是 的 用 使 所 使 即 , 型模程 編 的 致 一 用 使 員 人 是都 常 通 敗 失 的 易 交 。 TransactionException 是 Unchecked Exception 例 捉捕要 否 是 擇 選 行 自 您 讓而, 理 處 要 定 一 您 迫 強 不 S pring ,誤錯的命致 。外 44
  • 45. 4 。務服理管易交去移可即,定設下一改修上案檔定設在要 只,候時的理管易交要需不在,中之理管易交入納被正它道知不並,看來 API 度 角 的 件 物 從,中 之 式 程 入 介 用 不 以 可 關 相 的 理 管 易 交 是處好 Spring ,理 管 易 交 的 式 告 宣 用 採,制 控 的 度 粒 細 要 需 不 並 易 交,下 況 情 的 數 多 而 然 理管易交的式告宣 。制控易 交的度粒細現實以可,等束結時何易交、機時的作操消撤、始開時何易 交現實行自您讓是就也,界邊的易交制控的楚清以可理管易交的式程編 理管易交的式程編 :) D eclarative transaction management (理 管 易 交 的 式 告 宣 與 ) P rogrammatic transaction management (理管易交的式程編供提 Spring } boolean isRollbackOnly(); void setRollbackOnly(); boolean isNewTransaction(); public interface TransactionStatus { ... :態狀 的易交查調或行執的易交制控它由藉以可您,易交的在存經已或起發易交 的新個一著表代 T ransactionStatus ,等) (讀唯、) ( R ead-only T imeout 時超、) P ropagation behavior (為行播傳、) (度程離隔的 I solation level 易交了義定例實的面介 ,件物T ransactionDefinition 個 TransactionStatus 一傳回來件物 TransactionDefinition 個一據根法方 getTransaction() 援支易交、 Chapter 5 JDBC
  • 46. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) 5.3.2 JDBC 編程交易管理 用使接直是一,理管易交的式程編現實式方種兩供提 Spring Platform- 用使是二,現實 TransactionManager org.springframework.transaction. 。 support.TransactionTemplate 實的它用使邊這在, 用使何如看看來先 PlatformTransactionManager 中 的前之下一寫改以可, 別類現 DataSourceTransactionManager 5.2.1 類 下一改修,能功理管易交有具它讓,案專 JdbcTemplateDemo UserDAO insert() :範示作來法方 的別 ProgrammaticTransactionDemo UserDAO.java package onlyfun.caterpillar; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.sql.DataSource; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc. datasource.DataSourceTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction. support.DefaultTransactionDefinition; public class UserDAO implements IUserDAO { private DataSourceTransactionManager transactionManager; private DefaultTransactionDefinition def; private JdbcTemplate jdbcTemplate; public void setDataSource(DataSource dataSource) { jdbcTemplate = new JdbcTemplate(dataSource); transactionManager = new DataSourceTransactionManager(dataSource); // 義定的易交立建 46
  • 47. Chapter 5 JDBC 援支易交、 def = new DefaultTransactionDefinition(); def.setPropagationBehavior( TransactionDefinition.PROPAGATION_REQUIRED); } public void insert(User user) { String name = user.getName(); int age = user.getAge().intValue(); TransactionStatus status = transactionManager.getTransaction(def); try { jdbcTemplate.update("INSERT INTO user (name,age) " + "VALUES('" + name + "'," + age + ")"); //的面下 SQL 易交試測以用,誤錯有 jdbcTemplate.update("INSER INTO user (name,age) " + "VALUES('" + name + "'," + age + ")"); } catch(DataAccessException e) { transactionManager.rollback(status); throw e; } transactionManager.commit(status); } public User find(Integer id) { List rows = jdbcTemplate.queryForList( "SELECT * FROM user WHERE id=" + id.intValue()); Iterator it = rows.iterator(); if(it.hasNext()) { Map userMap = (Map) it.next(); Integer i = new Integer( userMap.get("id").toString()); String name = userMap.get("name").toString(); Integer age = new Integer( userMap.get("age").toString()); User user = new User(); user.setId(i); user.setName(name); 47
  • 48. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) user.setAge(age); return user; } return null; } } 易交行進來 insert() 了用使中法方 在 DataSourceTransactionManager 在, 的易交行進會中塊區 則,外例了生發果如,理管 catch Rollback insert() 實 此 因 ,) 個 一 了 寫 少 法 方 意 注 ( 的誤 錯 入 寫 意 故 中 法 方 SQL INSERT T 。 中 庫 料 資 至存儲 被 會 不 並 料 資 上 際 格 表 的 易 交 援 支 立 建 須 必,理 處 易 交 行 進 庫 料 資 MySQL 用使要 如 的格 表立建來用邊這,型類格表的 InnoDB 如例,型類 SQL :示所下 CREATE TABLE user ( id INT(11) NOT NULL auto_increment PRIMARY KEY, name VARCHAR(100) NOT NULL default '', age INT ) TYPE = InnoDB; 用 使 是 法 方 的 理 管易交 式 程 編 現 實 個 一 另 TransactionTemplate 它, :示所下如,例實 TransactionManager 個一要需 ... TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); ... transactionTemplate.execute(new TransactionCallback() { public Object doInTransaction(TransactionStatus status) { return jdbcTemplate.update("INSERT INTO user (name,age) " + "VALUES('" + name + "'," + age + ")"); 48
  • 49. Chapter 5 JDBC 援支易交、 } }); 行 進會則 , 外 例 了 生 發 果 如 Rollback 傳回 有 沒 果 如 , 易 交 交 提 則 否 , 用使以可也則,值 TransactionCallbackWithoutResult : ... transactionTemplate.execute( new TransactionCallbackWithoutResult() { public void doInTransactionWithoutResult( TransactionStatus status) { . ... } }); 5.3.3 JDBC 宣告交易管理 易交告宣用使。成完來架框 的它於賴依理管易交的式告宣 Spring AOP 不件物 ,說來體具,件組的發開所您入侵不理管易交,是處好的理管 D AO 系於屬是理管易交為因,此如當應也上實事,中之理管易交在正到識意會 的略策理管易交變改要想果如,份部一的輯邏務商是不而,務服的面層統 。 可 即 態 組 新 重 中檔義 定 在 要 需 只 也 , 話 在,下一改修案專 中 將以可,說來子例個舉 5.2.1 JdbcTemplateDemo 簡 個一, 務 服 的 理 管 易 交 入加它 為 以 可 , 下 況 情 的 別 類 UserDAO 改修不 對 理 管 易 交 的 入 介 要 定 指, TransactionProxyFactoryBean 用使是法方的單 : 示所下 如 , 改 修 案 檔 義 定在要 需 這 , 法 方 其 及 象 DeclarativeTransactionDemo 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 4
  • 50. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> <bean id="dataSource" class="org.springframework.jdbc. → datasource.DriverManagerDataSource" destroy-method="close"> <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="transactionManager" class="org.springframework.jdbc. → datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="userDAO" class="onlyfun.caterpillar.UserDAO"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="userDAOProxy" class="org.springframework.transaction. → interceptor.TransactionProxyFactoryBean"> <property name="proxyInterfaces"> <list> <value>onlyfun.caterpillar.IUserDAO</value> </list> </property> <property name="target" ref="userDAO"/> <property name="transactionManager" ref="transactionManager"/> <property name="transactionAttributes"> <props> <prop key="insert*">PROPAGATION_REQUIRED</prop> </props> </property> </bean>
  • 51. Chapter 5 JDBC 援支易交、 </beans> TransactionProxyFactoryBean 個一要需 TransactionManager 這於由, , JDBC 用使以所, 用使邊 DataSourceTransactionManager T ransaction- 易交,象對的理代要定指性屬 ProxyFactoryBean ,件物理代個是 " target" 屬 用使 是 邊 這 , 後 前 法 方的定 指 入 介 動 自 會 理 管 "transactionAttributes" 您 ,理管 易 交 入 納 要 都 的 頭 開 稱 名 法 方 定 指 示 表 " insert*" insert ,定指性 操的前先有所則,誤錯生發中程過行執法方在果如,名全法方定指以可也 。 交 提常正 則 否 , 回 撤 動 自 作 目在示表, "insert*" 了定指上法方等 "PROPAGATION_REQUIRED" 義意數常的關相,的新個一立建就在存不易交果如,作操行執中易交的前 個多上加以可您。到找中面介 API 中件文 在以可都 TransactionDefinition 個某定指是者或,讀唯上加以可如例,隔區 號逗用使間中,義定易交 "," :作 操 回 撤 時 生 發 外 例 PROPAGATION_REQUIRED,readOnly,-MyCheckedException 操消撤時外例定指生發示表,時 上加面前 MyCheckedException "-" 。 交提即 立 時 外 例 生 發 示 表 , 上 加 面 前 果 如 , 作 "+" 得取是的做要以所,了理代 " userDAO" 被 " userDAOProxy"於由 " user- DAOProxy" :如例, " userDAO" 是不而, DeclarativeTransactionDemo SpringDAODemo.java package onlyfun.caterpillar; import org.springframework.context.ApplicationContext; import org.springframework.context. support.ClassPathXmlApplicationContext; public class SpringDAODemo { 1
  • 52. Spring 2.0 良信林(冊手術技 – http://openhome.cc ) public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext( "beans-config.xml"); User user = new User(); user.setName("caterpillar"); user.setAge(new Integer(30)); IUserDAO userDAO = (IUserDAO) context.getBean("userDAOProxy"); userDAO.insert(user); user = userDAO.find(new Integer(1)); System.out.println("name: " + user.getName()); } } 的同不定設以可也您 TransactionInterceptor ,節細理管的多更到得來 :如例 <?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" destroy-method="close"> <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"/> 2
  • 53. Chapter 5 JDBC 援支易交、 </bean> <bean id="transactionManager" class="org.springframework.jdbc. → datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="userDAO" class="onlyfun.caterpillar.UserDAO"> <property name="dataSource" ref="dataSource"/> </bean> <bean id="transactionInterceptor" class="org.springframework.transaction. → interceptor.TransactionInterceptor"> <property name="transactionManager" ref="transactionManager"/> <property name="transactionAttributeSource" value="onlyfun.caterpillar.UserDAO.insert*= → PROPAGATION_REQUIRED "/> </bean> <bean id="userDAOProxy" class="org.springframework.aop. → framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <list> <value>onlyfun.caterpillar.IUserDAO</value> </list> </property> <property name="target" ref="userDAO"/> <property name="interceptorNames"> <list> <value>transactionInterceptor</value> </list> </property> </bean> </beans> 在接直則,理管易交要需再不來後使即 Bean ,可 即 置 配 改 修 中 檔 義 定 。 作 動 等 譯 編 新重行 進 式 程 改 修 用 不 而 3
  • 54. 4 易交的存現 停暫就 話的有果 如,行進中 易交在 應不出指 PROPAGATION_NOT_SUPPORTED 外例 出丟就 話的有果 如,行進中 易交在 應不出指 PROPAGATION_NEVER 同則 PROPAGATION_REQUIRED , 話 的 是 不 果 如,行 進中易 交的狀 巢個一在 PROPAGATION_NESTED 外例出 丟 則否,行進中 易交 的存現 個一在 須必法方 PROPAGATION_MANDATORY 明說 為行播傳 明說為行播傳易交 5.1 表 :個幾出列下以,明說與數常的應對相到找上明 說件文 的 API TransactionDefinition 在 以 可 ,為 行 播 傳 個 幾 了 義 定 Spring 。行 進 中 易 交 在 要 否 是 法 方 者 或,停 暫 被 該 易 交 時 何 或,易 交 的 新 個 一 始 開 該時何知告它,) B oundaries (界邊之上法方於用應易交了義定為行播傳 ) P ropagation behavior (為行播傳 :數 參 個 幾 的 下 以 作 分 性 屬 易 交 中 Spring 在 ,略策 的 上 法 方 至 用 應 易 交述描於在就然自) T ransaction attribute (性屬易交的 ,界邊為 S pring 法方以是易交式告宣而因,理管易交的式告宣成完來 用使 AOP Spring 5.3.4 交易的屬性介紹 。 括包須必中定設 spring-aop.jar Classpath 的您得記請,時 式 程 的 上 以 行 執 以 所 ,成 達 來 Spring AOP 用利是理管易交告宣 ) – http://openhome.cc 良信林(冊手術技 Spring 2.0