• 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主要的应用基本上都简单罗列一番,所有代码均为文章举例,不是很严谨,仅为演示每一种用法,抛砖引玉,希望有独特见解的拍砖,有问题的请指明问题所在,谢谢

  • 相关阅读:
    近期前端中的 一些常见的面试题
    一道前端学习题
    前端程序员容易忽视的一些基础知识
    web前端工程师入门须知
    Web前端知识体系精简
    面试分享:一年经验初探阿里巴巴前端社招
    抽象类、抽象函数/抽象方法详解
    C#语法-虚方法详解 Virtual 虚函数
    面向对象语言:继承关系教程
    C#动态创建Xml-LinQ方式
  • 原文地址:https://www.cnblogs.com/sharpest/p/5622684.html
Copyright © 2020-2023  润新知