Spring JDBC Framework詳解——批量JDBC操作、ORM映射

          作者:niumd,轉載請注明出處,謝謝   

          發(fā)表時間:2010 年 03 月 17 日  

          原文鏈接:http://ari.iteye.com/admin/blogs/618449


          一、Spring JDBC 概述

               Spring 提供了一個強有力的模板類JdbcTemplate簡化JDBC操作,DataSource,JdbcTemplate都可以以Bean的方式定義在想xml配置文件,JdbcTemplate創(chuàng)建只需注入一個DataSource,應用程序Dao層只需要繼承JdbcDaoSupport, 或者注入JdbcTemplate,便可以獲取JdbcTemplate,JdbcTemplate是一個線程安全的類,多個Dao可以注入一個JdbcTemplate;



          <!--         Oracle數(shù)據(jù)源           -->
          <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
          <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
          <property name="url" value="jdbc:oracle:thin:@oracle.devcake.co.uk:1521:INTL"/>
          <property name="username" value="sa"/>
          <property name="password" value=""/>
          </bean>
          <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
          <property name="dataSource" ref="dataSource"/>
          </bean>
          <!--  set注入方式獲取jdbcTemplate -->
          <bean id="customerDao" class="JdbcCustomerDao" >
          <property name="jdbcTemplate" ref="jdbcTemplate"/>
          </bean>
          <!-- 注入dataSource,customerDao通過繼承JdbcDaoSupport ,使用this.getJdbcTemplate()獲取JdbcTemplate   -->
          <bean id="customerDao" class="JdbcCustomerDao" >
          <property name="dataSource" ref="dataSource"/>
          </bean>
          


          然后將jdbcTemplate對象注入自定義的Dao、或者繼承JdbcDaoSupport,例如:

          public class JdbcCustomerDao extends JdbcDaoSupport implements CustomerDao {
          }
          public class JdbcCustomerDao implements CustomerDao {
          private JdbcTemplate jdbcTemplate
          public void setJdbcTemplate()JdbcTemplate jdbcTemplate{
          this.jdbcTemplate=jdbcTemplate
          }
          }


          二、 JdbcTemplate 提供以下主要方法簡化JDBC操作:

          2.1、List query(String sql,Ojbect[] args,RowMapper rowMapper)

               說明:常用的查詢,sql待執(zhí)行的sql語句,args是sql語句的參數(shù),rowMapper負責將每一行記錄轉化為java對象存放在list,并最終返回,例如:

          public List<Book> queryByAuthor(String author) {
          String sql = "select * from book where author=?";
          Collection c = getJdoTemplate().find(sql,
          new Object[] { author },new BookRowMapper());
          List<Book> books = new ArrayList<Book>();
          books.addAll(c);
          return books;
          }
          class BookRowMapper implements RowMapper{
          public Object mapRow(ResultSet res, int index) throws SQLException {
          Book book = new Book();
          book.setId(rs.getInt("id"));
          //省略set
          return book;
          }
          }


             更新、刪除、其他查詢操作類似,舉例如下,詳細細節(jié)請參考spring api:


          //返回值為一個長整形
          public long getAverageAge() {
          return getJdbcTemplate().queryForLong("SELECT AVG(age) FROM employee");
          }
          //返回一個整數(shù)
          public int getTotalNumberOfEmployees() {
          return getJdbcTemplate().queryForInt("SELECT COUNT(0) FROM employees");
          }
          //更新操作
          this.jdbcTemplate.update(
          "insert into t_actor (first_name, surname) values (?, ?)",
          new Object[] {"Leonor", "Watling"});
          



           2.2、spring 2.5新功能,另類的jdbc ORM:BeanPropertyRowMapper


                上面我們檢索時必須實現(xiàn)RowMapper,將結果集轉化為java對象。Spring2.5 簡化了這一操作,使得我們不必再實現(xiàn)RowMapper,實現(xiàn)此功能的倆個神奇東東便是:ParameterizedRowMapper,ParameterizedBeanPropertyRowMapper,貌似通過java反射機制實現(xiàn)了將resultset字段映射到java對象,但是數(shù)據(jù)表的列必須和java對象的屬性對應,沒有研究源碼,有點類似于apache 的BeanUtil,不知為何這部分在spring開發(fā)參考手冊沒有,難道不是經(jīng)典。



          //使用ParameterizedBeanPropertyRowMapper
          @SuppressWarnings({"unchecked"})
          public List<Customer> getAll() {
          return getJdbcTemplate().query("select * from t_customer", ParameterizedBeanPropertyRowMapper.newInstance(Customer.class));
          }
          //使用BeanPropertyRowMapper
          @SuppressWarnings({"unchecked"})
          public List<Customer> getAll() {
          return getJdbcTemplate().query("select * from t_customer", new BeanPropertyRowMapper(Customer.class));
          }
          



          注意:ParameterizedBeanPropertyRowMapper是BeanPropertyRowMapper子類。另外表的字段名稱必須和實體類的成員變量名稱一致;


          2.3、spring之JDBC批量操作

                jdbcTemplate.batchUpdate(final String[] sql) ,API解釋:Issue multiple SQL updates on a single JDBC Statement using batching,翻譯過來大致為:解決多個sql的插入、更新、刪除操作在一個Statement中。性能一般。

             jdbcTemplate.batchUpdate(String sql, final BatchPreparedStatementSetter pss),類似于JDBC的PreparedStatement,性能較上著有所提高。

             我們舉例說明如何使用,示例如下:

          final int count = 2000;
          final List<String> firstNames = new ArrayList<String>(count);
          final List<String> lastNames = new ArrayList<String>(count);
          for (int i = 0; i < count; i++) {
          firstNames.add("First Name " + i);
          lastNames.add("Last Name " + i);
          }
          jdbcTemplate.batchUpdate(
          "insert into customer (id, first_name, last_name, last_login, comments) values (?, ?, ?, ?, ?)",
          new BatchPreparedStatementSetter() {
          //為prepared statement設置參數(shù)。這個方法將在整個過程中被調用的次數(shù)
          public void setValues(PreparedStatement ps, int i) throws SQLException {
          ps.setLong(1, i + 10);
          ps.setString(2, firstNames.get(i));
          ps.setString(3, lastNames.get(i));
          ps.setNull(4, Types.TIMESTAMP);
          ps.setNull(5, Types.CLOB);
          }
          //返回更新的結果集條數(shù)
          public int getBatchSize() {
          return count;
          }
          });
          }
          



            BatchSqlUpdate類是SqlUpdate 的子類,適用于插入、刪除、更新批量操作,內部使用PreparedStatement,所以效率很高,批量語句達到設定的batchSize,或者手動調用flush才會執(zhí)行批量操作。注意:此類是非線程安全的,必須為每個使用者創(chuàng)建一個實例,或者在同一個線程中使用前調用reset。

             下面我們舉例說明如何使用BatchSqlUpdate,來執(zhí)行批量操作。示例如下:

          class BatchInsert extends BatchSqlUpdate {
          private static final String SQL = "insert into t_customer (id, first_name, last_name, last_login, "
          + "comments) values (?, ?, ?, ?, null)";
          BatchInsert(DataSource dataSource) {
          super(dataSource, SQL);
          declareParameter(new SqlParameter(Types.INTEGER));
          declareParameter(new SqlParameter(Types.VARCHAR));
          declareParameter(new SqlParameter(Types.VARCHAR));
          declareParameter(new SqlParameter(Types.TIMESTAMP));
          setBatchSize(10);
          }
          }
          


          int count = 5000;
          for (int i = 0; i < count; i++) {
          batchInsert.update(new Object[] { i + 100L, "a" + i, "b" + i, null });
          }
          


           至此,spring JDBC主要的應用基本上都簡單羅列一番,所有代碼均為文章舉例,不是很嚴謹,僅為演示每一種用法,拋磚引玉,希望有獨特見解的拍磚,有問題的請指明問題所在,謝謝

          posted on 2011-05-10 21:06 空白 閱讀(3274) 評論(0)  編輯  收藏 所屬分類: Java

          <2011年5月>
          24252627282930
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          導航

          統(tǒng)計

          常用鏈接

          留言簿(1)

          隨筆分類(15)

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 龙井市| 巍山| 东乡| 安义县| 玛曲县| 洛隆县| 册亨县| 平顺县| 岚皋县| 霍山县| 慈利县| 海城市| 洱源县| 德化县| 巩留县| 余江县| 泽普县| 仙居县| 报价| 博爱县| 承德市| 桑植县| 应用必备| 鄱阳县| 会理县| 麟游县| 环江| 新巴尔虎左旗| 四会市| 神农架林区| 滦南县| 天长市| 云和县| 于都县| 新昌县| 呼和浩特市| 深州市| 渭南市| 柘荣县| 灵石县| 合水县|