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


轉自:https://blog.csdn.net/yuyulover/article/details/5826948

一、spring JDBC 概述

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

 

 1 <!--         Oracle數據源           -->  
 2 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
 3         <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>  
 4         <property name="url" value="jdbc:oracle:thin:@oracle.devcake.co.uk:1521:INTL"/>  
 5         <property name="username" value="sa"/>  
 6         <property name="password" value=""/>  
 7 </bean>  
 8   
 9   
10 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">  
11         <property name="dataSource" ref="dataSource"/>  
12  </bean>  
13 <!--  set注入方式獲取jdbcTemplate -->  
14 <bean id="customerDao" class="JdbcCustomerDao" >  
15          <property name="jdbcTemplate" ref="jdbcTemplate"/>  
16 </bean>  
17 <!-- 注入dataSource,customerDao通過繼承JdbcDaoSupport ,使用this.getJdbcTemplate()獲取JdbcTemplate   -->  
18 <bean id="customerDao" class="JdbcCustomerDao" >  
19          <property name="dataSource" ref="dataSource"/>  
20 </bean>  

 

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

 

 1 public class JdbcCustomerDao extends JdbcDaoSupport implements CustomerDao {
 2 }
 3 
 4 public class JdbcCustomerDao implements CustomerDao {
 5 
 6           private JdbcTemplate jdbcTemplate
 7 
 8          public void setJdbcTemplate()JdbcTemplate jdbcTemplate{
 9                this.jdbcTemplate=jdbcTemplate
10          }
11 }

 

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

 

 

 

 

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

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

 1 public List<Book> queryByAuthor(String author) {
 2         String sql = "select * from book where author=?";
 3         Collection c = getJdoTemplate().find(sql,
 4                 new Object[] { author },new BookRowMapper());
 5         List<Book> books = new ArrayList<Book>();
 6         books.addAll(c);
 7         return books;
 8 }
 9 
10 class BookRowMapper implements RowMapper{
11      public Object mapRow(ResultSet res, int index) throws SQLException {
12           Book book = new Book();
13           book.setId(rs.getInt("id"));
14           //省略set
15        return book;
16     }
17 }

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

 

 1 //返回值為一個長整形
 2 public long getAverageAge() {
 3     return getJdbcTemplate().queryForLong("SELECT AVG(age) FROM employee");
 4   }
 5 //返回一個整數
 6 public int getTotalNumberOfEmployees() {
 7     return getJdbcTemplate().queryForInt("SELECT COUNT(0) FROM employees");
 8   }
 9 
10 //更新操作
11 this.jdbcTemplate.update(
12         "insert into t_actor (first_name, surname) values (?, ?)", 
13         new Object[] {"Leonor", "Watling"});

 

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

 

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

 1 //使用ParameterizedBeanPropertyRowMapper
 2 @SuppressWarnings({"unchecked"})
 3   public List<Customer> getAll() {
 4       return getJdbcTemplate().query("select * from t_customer", ParameterizedBeanPropertyRowMapper.newInstance(Customer.class));
 5   }
 6 
 7 //使用BeanPropertyRowMapper
 8 @SuppressWarnings({"unchecked"})
 9   public List<Customer> getAll() {
10       return getJdbcTemplate().query("select * from t_customer", new BeanPropertyRowMapper(Customer.class));
11   }

 

注意: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,性能較上着有所提高。

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

 

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

 

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

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

 1 class BatchInsert extends BatchSqlUpdate {
 2   private static final String SQL = "insert into t_customer (id, first_name, last_name, last_login, "
 3       + "comments) values (?, ?, ?, ?, null)";
 4 
 5   BatchInsert(DataSource dataSource) {
 6     super(dataSource, SQL);
 7     declareParameter(new SqlParameter(Types.INTEGER));
 8     declareParameter(new SqlParameter(Types.VARCHAR));
 9     declareParameter(new SqlParameter(Types.VARCHAR));
10     declareParameter(new SqlParameter(Types.TIMESTAMP));
11 
12     setBatchSize(10);
13   }
14 
15 }

 

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

 

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

 

一、spring JDBC 概述

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

 

[xhtml]  view plain  copy
 
  1. <!--         Oracle數據源           -->    
  2. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">    
  3.         <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>    
  4.         <property name="url" value="jdbc:oracle:thin:@oracle.devcake.co.uk:1521:INTL"/>    
  5.         <property name="username" value="sa"/>    
  6.         <property name="password" value=""/>    
  7. </bean>    
  8.     
  9.     
  10. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">    
  11.         <property name="dataSource" ref="dataSource"/>    
  12.  </bean>    
  13. <!--  set注入方式獲取jdbcTemplate -->    
  14. <bean id="customerDao" class="JdbcCustomerDao" >    
  15.          <property name="jdbcTemplate" ref="jdbcTemplate"/>    
  16. </bean>    
  17. <!-- 注入dataSource,customerDao通過繼承JdbcDaoSupport ,使用this.getJdbcTemplate()獲取JdbcTemplate   -->    
  18. <bean id="customerDao" class="JdbcCustomerDao" >    
  19.          <property name="dataSource" ref="dataSource"/>    
  20. </bean>    

 

 

 

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

Java代碼 
  1. public class JdbcCustomerDao extends JdbcDaoSupport implements CustomerDao {  
  2. }  
  3.   
  4. public class JdbcCustomerDao implements CustomerDao {  
  5.   
  6.           private JdbcTemplate jdbcTemplate  
  7.   
  8.          public void setJdbcTemplate()JdbcTemplate jdbcTemplate{  
  9.                this.jdbcTemplate=jdbcTemplate  
  10.          }  
  11. }  

 

 

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

 

 

 

 

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

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

Java代碼 
  1. public List<Book> queryByAuthor(String author) {  
  2.         String sql = "select * from book where author=?";  
  3.         Collection c = getJdoTemplate().find(sql,  
  4.                 new Object[] { author },new BookRowMapper());  
  5.         List<Book> books = new ArrayList<Book>();  
  6.         books.addAll(c);  
  7.         return books;  
  8. }  
  9.   
  10. class BookRowMapper implements RowMapper{  
  11.      public Object mapRow(ResultSet res, int index) throws SQLException {  
  12.           Book book = new Book();  
  13.           book.setId(rs.getInt("id"));  
  14.           //省略set  
  15.        return book;  
  16.     }  
  17. }  

 

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

 

Java代碼 
  1. //返回值為一個長整形  
  2. public long getAverageAge() {  
  3.     return getJdbcTemplate().queryForLong("SELECT AVG(age) FROM employee");  
  4.   }  
  5. //返回一個整數  
  6. public int getTotalNumberOfEmployees() {  
  7.     return getJdbcTemplate().queryForInt("SELECT COUNT(0) FROM employees");  
  8.   }  
  9.   
  10. //更新操作  
  11. this.jdbcTemplate.update(  
  12.         "insert into t_actor (first_name, surname) values (?, ?)",   
  13.         new Object[] {"Leonor""Watling"});  

 

 

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

 

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

 

 

Java代碼 
  1. //使用ParameterizedBeanPropertyRowMapper  
  2. @SuppressWarnings({"unchecked"})  
  3.   public List<Customer> getAll() {  
  4.       return getJdbcTemplate().query("select * from t_customer", ParameterizedBeanPropertyRowMapper.newInstance(Customer.class));  
  5.   }  
  6.   
  7. //使用BeanPropertyRowMapper  
  8. @SuppressWarnings({"unchecked"})  
  9.   public List<Customer> getAll() {  
  10.       return getJdbcTemplate().query("select * from t_customer"new BeanPropertyRowMapper(Customer.class));  
  11.   }  

 

 

注意: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,性能較上着有所提高。

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

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

 

 

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

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

Java代碼 
  1. class BatchInsert extends BatchSqlUpdate {  
  2.   private static final String SQL = "insert into t_customer (id, first_name, last_name, last_login, "  
  3.       + "comments) values (?, ?, ?, ?, null)";  
  4.   
  5.   BatchInsert(DataSource dataSource) {  
  6.     super(dataSource, SQL);  
  7.     declareParameter(new SqlParameter(Types.INTEGER));  
  8.     declareParameter(new SqlParameter(Types.VARCHAR));  
  9.     declareParameter(new SqlParameter(Types.VARCHAR));  
  10.     declareParameter(new SqlParameter(Types.TIMESTAMP));  
  11.   
  12.     setBatchSize(10);  
  13.   }  
  14.   
  15. }  

 

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

 

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM