博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring JDBC Framework详解——批量JDBC操作、ORM映射
阅读量:5796 次
发布时间:2019-06-18

本文共 10782 字,大约阅读时间需要 35 分钟。

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

一、 JDBC 概述

     Spring 提供了一个强有力的模板类JdbcTemplate简化JDBC操作,DataSource,JdbcTemplate都可以以Bean的方式定义在想xml配置文件,JdbcTemplate创建只需注入一个DataSource,应用程序Dao层只需要继承JdbcDaoSupport, 或者注入JdbcTemplate,便可以获取JdbcTemplate,JdbcTemplate是一个线程安全的类,多个Dao可以注入一个JdbcTemplate;

 

1 
2
3
4
5
6
7
8 9 10
11
12
13
14
15
16
17
18
19
20

 

然后将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=jdbcTemplate10          }11 }

 

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

 

 

 

 

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

     说明:常用的查询,sql待执行的sql语句,args是sql语句的参数,rowMapper负责将每一行记录转化为对象存放在list,并最终返回,例如:

1 public List
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
books = new ArrayList
(); 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 //省略set15 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
getAll() { 4 return getJdbcTemplate().query("select * from t_customer", ParameterizedBeanPropertyRowMapper.newInstance(Customer.class)); 5 } 6 7 //使用BeanPropertyRowMapper 8 @SuppressWarnings({"unchecked"}) 9 public List
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
firstNames = new ArrayList
(count); 3 final List
lastNames = new ArrayList
(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主要的应用基本上都简单罗列一番,所有代码均为文章举例,不是很严谨,仅为演示每一种用法,抛砖引玉,希望有独特见解的拍砖,有问题的请指明问题所在,谢谢

 

一、 JDBC 概述

     Spring 提供了一个强有力的模板类JdbcTemplate简化JDBC操作,DataSource,JdbcTemplate都可以以Bean的方式定义在想xml配置文件,JdbcTemplate创建只需注入一个DataSource,应用程序Dao层只需要继承JdbcDaoSupport, 或者注入JdbcTemplate,便可以获取JdbcTemplate,JdbcTemplate是一个线程安全的类,多个Dao可以注入一个JdbcTemplate;

 

[xhtml]   
 
  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负责将每一行记录转化为对象存放在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主要的应用基本上都简单罗列一番,所有代码均为文章举例,不是很严谨,仅为演示每一种用法,抛砖引玉,希望有独特见解的拍砖,有问题的请指明问题所在,谢谢

转载于:https://www.cnblogs.com/sharpest/p/5622684.html

你可能感兴趣的文章
Compare Version Numbers
查看>>
性能测试之稳定性测试
查看>>
ES6的 Iterator 遍历器
查看>>
2019届高二(下)半期考试题(文科)
查看>>
【REDO】删除REDO LOG重做日志组后需要手工删除对应的日志文件(转)
查看>>
nginx 301跳转到带www域名方法rewrite(转)
查看>>
AIX 配置vncserver
查看>>
windows下Python 3.x图形图像处理库PIL的安装
查看>>
【IL】IL生成exe的方法
查看>>
network
查看>>
SettingsNotePad++
查看>>
centos7安装cacti-1.0
查看>>
3个概念,入门 Vue 组件开发
查看>>
没有JS的前端:体积更小、速度更快!
查看>>
数据指标/表现度量系统(Performance Measurement System)综述
查看>>
GitHub宣布推出Electron 1.0和Devtron,并将提供无限制的私有代码库
查看>>
Angular2, NativeScript 和 React Native比较[翻译]
查看>>
论模式在领域驱动设计中的重要性
查看>>
京东AI研究院何晓冬:将先进的技术和模型落地到产业
查看>>
国内首例:飞步无人卡车携手中国邮政、德邦投入日常运营
查看>>