posts - 66,  comments - 11,  trackbacks - 0

              Spring的一個目標就是讓你遵循對接口編程的面向對象原則。DAO的存在提供了讀寫數據庫中數據的一種方

          法。只要把這個功能通過接口暴露,應用的其他部分就可以通過這些接口訪問數據庫了。
              在Spring的DAO框架里,Connection對象是通過DataSource獲得的。
              從JNDI得到DataSource,代碼:

          <?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">
              
          <!-- Spring應用經常運行在J2EE應用服務器上,或者是諸如Tomcat的Web服務器上。這些服務器都能提供的一件事:通過
              JNDI獲得DataSource.現在我們已經和服務器上的DataSource以及它的連接池功能連接上了。
               
          -->
              
          <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
                  
          <property name="jndiName">
                      
          <value>java:comp/env/jdbc/myDatasource</value>
                  
          </property>
              
          </bean>
              
          <!-- 加入Spring容器運行在一個不提供DataSource的環境中,但我們還希望擁有連接池的好處,我們要實現一個DataSource
              的連接池Bean,我們有了一個帶連接池的DataSource,它不依賴于任何應用服務器,代碼如下: 
          -->
              
          <bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource">
                  
          <property name="driverClassName">
                      
          <value>${db.driver}</value>
                  
          </property>
                  
          <property name="url">
                      
          <value>${db.url}</value>
                  
          </property>
                  
          <property name="username">
                      
          <value>${db.username}</value>
                  
          </property>
                  
          <property name="password">
                      
          <value>${db.password}</value>
                  
          </property>
              
          </bean>
          </beans>


              一個模版方法定義一個流程的骨架。在我們的例子中,這個流程就是把行李從出發地運送到目的地。流程本身是固定的,不會改變。處理行李的事件順序每一次都是一樣的:檢查行李、放到飛機上等等。當飛機到達目的地時,行李都被一件件的卸下來,放到傳送帶上,再運到行李提取處。流程是固定的,但是流程中的具體實現有些是可變的。一個模版方法將這部分可變流程的具體實現委托給一個接口,這個接口的不同實現定義了這部分流程的具體實現。
              Spring把這個模式應用到數據訪問上。不管我們采用什么技術,某些數據訪問步驟是必須的。例如:我們總是需要和數據庫建立連接,在操作完后釋放資源。這就是數據訪問流程中的固定步驟。但我們寫的每個數據訪問的實現都有略微不同,我們用不同的方式查詢不同的對象、更新數據。這些就是數據訪問流程中的可變步驟。
              Spring把數據訪問流程中的固定部分和可變部分分開,分別映射成2個截然不同的類:模版和回調。模版管理流程的固定部分,而在回調處填寫你的實現細節。
              在模版和回調的設計之上,每個框架都提供一個支撐類,以便讓你自己的數據訪問類來繼承它們。這些支撐類早已擁有一個指向模版類的屬性,所以不需要為每個DAO類創建這個屬性。另外,每個支撐類都允許你直接得到用于跟數據庫打交道的類。
              模版代碼使用如下:

          package com.testproject.spring.datasource;

          import java.sql.PreparedStatement;
          import java.sql.ResultSet;
          import java.sql.SQLException;
          import java.sql.Types;
          import java.util.List;

          import org.springframework.jdbc.core.BatchPreparedStatementSetter;
          import org.springframework.jdbc.core.JdbcTemplate;
          import org.springframework.jdbc.core.RowCallbackHandler;
          /*
           * 為了讓JdbcTemplate工作,它所需要的,只是一個DataSource實例。
           
          */

          public class StudentDaoJdbc implements StudentDao {
              
          private JdbcTemplate jdbcTemplate;
              
              
          public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
                  
          this.jdbcTemplate = jdbcTemplate;
              }

              
          /*
               * 先從SQL語句創建一個PreparedStatement,然后綁定參數。在幕后,JdbcTemplate
               * 類創建了PreparedStatementCreator和PreparedStatementSetter.這些我們都
               * 不用關心,我們只管提供SQL語句和參數。還可以提供類型支持。
               
          */

              
          public int insertPerson(Person person){
                  String sql 
          = "insert into person(id,firstName,lastName) values(?,?,?)";
                  Object[] params 
          = new Object[]{person.getId(),person.getFirstName(),person.getLastName()};
                  
          return jdbcTemplate.update(sql,params);
              }

              
          public int insertPerson2(Person person){
                  String sql 
          = "insert into person(id,firstName,lastName) values(?,?,?)";
                  Object[] params 
          = new Object[]{person.getId(),person.getFirstName(),person.getLastName()};
                  
          int[] types = new int[]{Types.INTEGER,Types.VARBINARY,Types.VARBINARY};
                  
          return jdbcTemplate.update(sql, params, types);
              }

              
          /*
               * 批量更新,我們講使用BatchPreparedStatementSetter,這個接口的2個方法
               * 1、getBatchSize()告訴JdbcTemplate類有多少個語句要創建,同時也決定了要調用多少次setValues()
               * 2、setValues負責創建參數
               * 所以你的JDBC驅動支持批量操作,這些更新講被批量執行,是的數據訪問更高效。
               
          */

              
          public int[] updatePersons(final List persons){
                  String sql 
          = "insert into person(id,firstName,lastName) values(?,?,?)";
                  BatchPreparedStatementSetter setter 
          = null;
                  setter 
          = new BatchPreparedStatementSetter(){
                      
          public int getBatchSize(){
                          
          return persons.size();
                      }

                      
          public void setValues(PreparedStatement ps,int index)throws SQLException{
                          Person person 
          = (Person)persons.get(index);
                          ps.setInt(
          0,person.getId().intValue());
                          ps.setString(
          1,person.getFirstName());
                          ps.setString(
          2,person.getLastName());
                      }

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

              
          /*
               * 當查詢數據庫時,我們需要通過ResultSet取得結果,Spring認識到這一步是任何查詢都需要的,所以它幫助
               * 我們處理了這些。取而代之,我們只需要簡單的告訴Spring要怎么處理ResultSet中的每一行記錄。我們通過
               * 實現RowCallbackHandler接口中僅有的一個方法來完成上述功能。
               * void processRow(java.sql.ResultSet rs)該方法將為ResultSet中的每條記錄調用一次
               * 這個方法只支持單對象的查詢
               
          */

              
          public Person getPerson(final Integer id){
                  String sql 
          = "select id,first_Name,last_Name from person where id=?";
                  
          final Person person = new Person();//創建查詢結果對象
                  final Object[] params = new Object[]{id};//創建查詢參數
                  
                  jdbcTemplate.query(sql,params,
          new RowCallbackHandler(){//處理查詢結果
                      public void processRow(ResultSet rs)throws SQLException{
                          person.setId(
          new Integer(rs.getInt("id")));
                          person.setFirstName(rs.getString(
          "first_name"));
                          person.setLastName(rs.getString(
          "last_name"));
                      }

                  }
          );
                  
          return person;//返回查詢結果對象
              }

              
          /*
               * 查詢所有記錄
               * RowMapper接口對從一個查詢結果中提取多個對象非常游泳。
               
          */

              
          public List getAllPersons(){
                  String sql 
          = "select id,first_name,last_name from person";
                  
          return jdbcTemplate.query(sql,new PersonRowMapper());
              }

              
          /*
               * 查找基本類型
               
          */

              
          public int getNumberOfPerson(){
                  
          return jdbcTemplate.queryForInt("select count(*) from person");
              }

              
          public String getLastNameForId(Integer id){
                  String sql 
          = "select last_name from person where id=?";
                  
          return (String)jdbcTemplate.queryForObject(sql,new Object[]{id},String.class);
              }

              
          }

          package com.testproject.spring.datasource;

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

          import org.springframework.jdbc.core.RowMapper;

          public class PersonRowMapper implements RowMapper {

              
          public Object mapRow(ResultSet rs, int index) throws SQLException {
                  Person person 
          = new Person();
                  person.setId(
          new Integer(rs.getInt("id")));
                  person.setFirstName(rs.getString(
          "first_name"));
                  person.setLastName(rs.getString(
          "last_name"));
                  
          return person;
              }


          }

          posted on 2009-11-12 19:46 王永慶 閱讀(189) 評論(0)  編輯  收藏 所屬分類: SPRING
          <2009年11月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          常用鏈接

          留言簿(1)

          隨筆分類

          隨筆檔案

          關注blogs

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 黔东| 泰兴市| 兴安县| 广饶县| 武强县| 镇安县| 什邡市| 日土县| 临泽县| 甘孜县| 龙州县| 高邮市| 奎屯市| 灌阳县| 宝坻区| 绥江县| 洪江市| 朝阳区| 莱州市| 保德县| 临海市| 吴旗县| 彰武县| 肥西县| 綦江县| 凤庆县| 陇川县| 车致| 齐齐哈尔市| 宜君县| 清水县| 湟源县| 太谷县| 商南县| 古浪县| 南昌县| 淮安市| 饶阳县| 那曲县| 鄢陵县| 常州市|