现在的位置: 首页 > 综合 > 正文

Spring3核心技术之JdbcTemplate

2019年05月09日 ⁄ 综合 ⁄ 共 22016字 ⁄ 字号 评论关闭

转载:http://blog.csdn.net/z69183787/article/details/8548960

Spring对JDBC的支持 
       Spring通过抽象JDBC访问并提供一致的API来简化JDBC编程的工作量。我们只需要声明SQL、调用合适的Spring JDBC框架API、处理结果集即可。事务由Spring管理,并将JDBC受查异常转换为Spring一致的非受查异常,从而简化开发。
 

Java代码  收藏代码
  1. ....  
  2.     Connection conn = null;    
  3.     PreparedStatement pstmt = null;  
  4.     try {  
  5.       conn = getConnection();              //1.获取JDBC连接      
  6.       String sql = "select * from tableName"//2.声明SQL  
  7.       pstmt = conn.prepareStatement(sql);    //3.预编译SQL    
  8.       ResultSet rs = pstmt.executeQuery();   //4.执行SQL    
  9.       process(rs);                       //5.处理结果集    
  10.       closeResultSet(rs);                 //5.释放结果集    
  11.       closeStatement(pstmt);              //6.释放Statement    
  12.       conn.commit();                    //8.提交事务    
  13.     } catch (Exception e) {    
  14.       //9.处理异常并回滚事务    
  15.       conn.rollback();    
  16.       throw e;    
  17.     } finally {    
  18.       //10.释放JDBC连接,防止JDBC连接不关闭造成的内存泄漏    
  19.       closeConnection(conn);    
  20.     }  
  21. ....  


以上代码片段具有冗长、重复、容易忘记某一步骤从而导致出错、显示控制事务、显示处理受检查异常等等。 
       Spring主要提供JDBC模板方式、关系数据库对象化方式和SimpleJdbc方式三种方式来简化JDBC编程,这三种方式就是Spring JDBC的工作模式: 
Spring JDBC抽象框架core包提供了JDBC模板类,其中JdbcTemplate是core包的核心类,所以其他模板类都是基于它封装完成的,JDBC模板类是第一种工作模式。 

JdbcTemplate类通过模板设计模式帮助我们消除了冗长的代码,只做需要做的事情(即可变部分),并且帮我们做哪些固定部分,如连接的创建及关闭。 
 

  • JDBC模板方式:Spring JDBC框架提供以下几种模板类来简化JDBC编程,实现GoF模板设计模式,将可变部分和非可变部分分离,可变部分采用回调接口方式由用户来实现:如JdbcTemplate、NamedParameterJdbcTemplate、SimpleJdbcTemplate。
  • 关系数据库操作对象化方式:Spring JDBC框架提供了将关系数据库操作对象化的表示形式,从而使用户可以采用面向对象编程来完成对数据库的访问;如MappingSqlQuery、SqlUpdate、SqlCall、SqlFunction、StoredProcedure等类。这些类的实现一旦建立即可重用并且是线程安全的。
  • SimpleJdbc方式:Spring JDBC框架还提供了SimpleJdbc方式来简化JDBC编程,SimpleJdbcInsert 、 SimpleJdbcCall用来简化数据库表插入、存储过程或函数访问。

Spring JDBC还提供了一些强大的工具类,如DataSourceUtils来在必要的时候手工获取数据库连接等。 

Spring的JDBC架构 
Spring JDBC抽象框架由四部分组成:datasource、support、core、object如图所示。 
 

  • support包:提供将JDBC异常转换为DAO非检查异常转换类、一些工具类如JdbcUtils等。
  • datasource包:提供简化访问JDBC 数据源(javax.sql.DataSource实现)工具类,并提供了一些DataSource简单实现类从而能使从这些DataSource获取的连接能自动得到Spring管理事务支持。
  • core包:提供JDBC模板类实现及可变部分的回调接口,还提供SimpleJdbcInsert等简单辅助类。
  • object包:提供关系数据库的对象表示形式,如MappingSqlQuery、SqlUpdate、SqlCall、SqlFunction、StoredProcedure等类,该包是基于core包JDBC模板类实现。

 
SpringJDbc工程中需要引入以下JAR包: 
 

Spring JDBC提供如下DaoSupport实现: 
● JdbcDaoSupport:用于支持一致的JdbcTemplate访问; 
● NamedParameterJdbcDaoSupport:继承JdbcDaoSupport,同时提供NamedParameterJdbcTemplate访问; 
● SimpleJdbcDaoSupport:继承JdbcDaoSupport,同时提供SimpleJdbcTemplate访问。 
由于JdbcTemplate、NamedParameterJdbcTemplate、SimpleJdbcTemplate类使用DataSourceUtils获取及释放连接,而且连接是与线程绑定的,因此这些JDBC模板类是线程安全的,即JdbcTemplate对象可以在多线程中重用 

JdbcTemplate 
JdbcTemplate主要提供以下五类方法: 

  • execute():可以用于执行任何SQL语句,一般用于执行DDL语句;
  • update()及batchUpdate():update方法用于执行新增、修改、删除等语句;batchUpdate方法用于执行批处理相关语句;
  • query()及queryForXXX():用于执行查询相关语句;
  • call():用于执行存储过程、函数相关语句。


JdbcTemplate类支持的回调类: 
● 预编译语句及存储过程创建回调:用于根据JdbcTemplate提供的连接创建相应的语句; 
         PreparedStatementCreator:通过回调获取JdbcTemplate提供的Connection,由用户使用该Conncetion创建相关的PreparedStatement; 
         CallableStatementCreator:通过回调获取JdbcTemplate提供的Connection,由用户使用该Conncetion创建相关的CallableStatement; 
● 预编译语句设值回调:用于给预编译语句相应参数设值; 
         PreparedStatementSetter:通过回调获取JdbcTemplate提供的PreparedStatement,由用户来对相应的预编译语句相应参数设值; 
         BatchPreparedStatementSetter:;类似于PreparedStatementSetter,但用于批处理,需要指定批处理大小; 
● 自定义功能回调:提供给用户一个扩展点,用户可以在指定类型的扩展点执行任何数量需要的操作; 
         ConnectionCallback:通过回调获取JdbcTemplate提供的Connection,用户可在该Connection执行任何数量的操作; 
         StatementCallback:通过回调获取JdbcTemplate提供的Statement,用户可以在该Statement执行任何数量的操作; 
         PreparedStatementCallback:通过回调获取JdbcTemplate提供的PreparedStatement,用户可以在该PreparedStatement执行任何数量的操作; 
         CallableStatementCallback:通过回调获取JdbcTemplate提供的CallableStatement,用户可以在该CallableStatement执行任何数量的操作; 
● 结果集处理回调:通过回调处理ResultSet或将ResultSet转换为需要的形式; 
         RowMapper:用于将结果集每行数据转换为需要的类型,用户需实现方法mapRow(ResultSet rs, int rowNum)来完成将每行数据转换为相应的类型。 
         RowCallbackHandler:用于处理ResultSet的每一行结果,用户需实现方法processRow(ResultSet rs)来完成处理,在该回调方法中无需执行rs.next(),该操作由JdbcTemplate来执行,用户只需按行获取数据然后处理即可。 
         ResultSetExtractor:用于结果集数据提取,用户需实现方法extractData(ResultSet rs)来处理结果集,用户必须处理整个结果集; 

Java代码  收藏代码
  1. /** 
  2.  *  
  3.  * @author Chou 
  4.  * @since 2012-9-9 
  5.  * SpringJdbc并没有像Hibernate那样把AutoCommit设置为false, 
  6.  * 所以没有配置事务的情况下,默认是自动提交 
  7.  */  
  8. public class JdbcTemplateDao extends JdbcDaoSupport{  
  9.       
  10.     public void setDadasource(DataSource dataSource) {  
  11.         super.setDataSource(dataSource);  
  12.     }  
  13.   
  14.     public void commonSql() {  
  15.         String insertSql = "insert into tab_item values(?,?,?)";  
  16.         String updateSql = "update tab_item set itemno = ?, itemname = ? where id = ?";  
  17.         String deleteSql = "delete tab_item where id = ?";  
  18.   
  19.         Assert.isTrue(  
  20.         getJdbcTemplate().update(insertSql, new Object[]{4"HP""PT540"}) == 1"插入失败");  
  21.         Assert.isTrue(  
  22.         getJdbcTemplate().update(updateSql, new Object[]{"HP""PT555"4}) == 1"修改失败");  
  23.         Assert.isTrue(  
  24.         getJdbcTemplate().update(deleteSql, new Object[]{4}) == 1"删除失败");  
  25.     }  
  26.       
  27.     /** 
  28.      * 预编译语句设值回调使用 
  29.      * 通过JdbcTemplate的int update(String sql, PreparedStatementSetter pss)执行预编译sql 
  30.      */  
  31.     public void preparedStatementSql() {  
  32.         String sql = "insert into tab_item values(?,?,?)";  
  33.         int row = getJdbcTemplate().update(sql, new PreparedStatementSetter() {  
  34.             @Override  
  35.             public void setValues(PreparedStatement ps) throws SQLException {  
  36.                 ps.setInt(1101);// JDBC占位符集合的序号是从1开始的,而不是0  
  37.                 ps.setObject(2"Apple");  
  38.                 ps.setString(3"Ipad4");  
  39.             }  
  40.         });  
  41.         Assert.isTrue(row == 1"插入失败");  
  42.   
  43.         // JdbcTemplate也提供一种更简单的方式设值相应的占位符位置的值  
  44.         sql = "delete from tab_item where id = ?";  
  45.         row = getJdbcTemplate().update(sql, new Object[] { 101 });  
  46.         Assert.isTrue(row == 1"删除失败");  
  47.     }  
  48.   
  49.     public void queryCallback() {  
  50.         String listSql = "select * from player";  
  51.           
  52.         /** 
  53.          * RowMapper接口提供mapRow(ResultSet rs, int rowNum) 
  54.          * 方法将结果集的每一行转换为一个Map,当然可以转换为其他类,如表的对象化形式。 
  55.          */  
  56.         List<Map> result = getJdbcTemplate().query(listSql, new RowMapper<Map>() {  
  57.             @Override  
  58.             public Map mapRow(ResultSet rs, int rowNum) throws SQLException {  
  59.                 System.out.println(rowNum);  
  60.                 Map<Long,String> map = new HashMap<Long, String>();    
  61.                 map.put(rs.getLong("id"), rs.getString("name"));  
  62.                 return map;  
  63.             }  
  64.         });  
  65.         Iterator it = result.iterator();  
  66.         while (it.hasNext()) {  
  67.             Map<Long,String> map = (Map<Long, String>) it.next();  
  68.             System.out.println(map.values());  
  69.         }  
  70.           
  71.         /** 
  72.          * RowCallbackHandler接口也提供方法processRow(ResultSet rs), 
  73.          * 能将结果集的行转换为需要的形式。 
  74.          */  
  75.         getJdbcTemplate().query(listSql, new RowCallbackHandler() {  
  76.             @Override  
  77.             public void processRow(ResultSet rs) throws SQLException {  
  78.                 System.out.println("处理结果集");  
  79.                 System.out.print("id:" + rs.getInt("id") + "***");  
  80.                 System.out.println("name:" + rs.getString("name"));  
  81.             }  
  82.         });  
  83.           
  84.         /** 
  85.          * ResultSetExtractor使用回调方法extractData(ResultSet rs)提供整个结果集, 
  86.          * 让用户决定如何处理该结果集 
  87.          */  
  88.         List list = getJdbcTemplate().query(listSql, new ResultSetExtractor<List>() {  
  89.             @Override  
  90.             public List extractData(ResultSet rs) throws SQLException,DataAccessException {  
  91.                 List result = new ArrayList();    
  92.                 while(rs.next()) {  
  93.                     Map row = new HashMap();  
  94.                     row.put(rs.getInt("id"), rs.getString("name"));  
  95.                     result.add(row);  
  96.                     System.out.println(row);  
  97.                 }  
  98.                 return result;  
  99.             }  
  100.         });  
  101.     }  
  102.       
  103.     /** 
  104.      * JdbcTemplate提供更简单的queryForXXX方法,来简化开发: 
  105.      */  
  106.     private void queryForSimple() {  
  107.         //1.查询一行数据并返回int型结果    
  108.         int countRs = getJdbcTemplate().queryForInt("select count(*) from player");  
  109.         System.out.println(countRs);  
  110.           
  111.         //2. 查询一行数据并将该行数据转换为Map返回    
  112.         Map map = getJdbcTemplate().queryForMap("select * from tab_item where id = ?"new Object[]{100});  
  113.         System.out.println(map.values());  
  114.           
  115.         //3.查询一行任何类型的数据,最后一个参数指定返回结果类型    
  116.         countRs = getJdbcTemplate().queryForObject("select count(*) from player", Integer.class);  
  117.         System.out.println(countRs);  
  118.           
  119.         //4.查询一批数据,默认将每行数据转换为Map         
  120.         List<Map<String, Object>> list = getJdbcTemplate().queryForList("select * from player");  
  121.         System.out.println(list.get(0).values());  
  122.           
  123.         //5.只查询一列数据列表,列类型是String类型,列名字是name  
  124.         List<String> names = getJdbcTemplate().queryForList("select itemname from tab_item where itemname=?"new Object[]{"雷蛇鼠标"}, String.class);  
  125.         System.out.println(names.size());  
  126.           
  127.         //6.查询一批数据,返回为SqlRowSet,类似于ResultSet,但不再绑定到连接上    
  128.         SqlRowSet rs = getJdbcTemplate().queryForRowSet("select * from player");  
  129.     }  
  130.   
  131.     /** 
  132.      * 调用建表,删表语句 
  133.      * 数据库不同,创建存储过程的SQL也不同 
  134.      */  
  135.     public void createProcedure() {  
  136.             String createTableSql = "create memory table test" +    
  137.             "(id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, " +    
  138.             "name varchar(100))";    
  139.               
  140.             String dropTableSql = "drop table test";   
  141.                    
  142.             String createHsqldbFunctionSql =    
  143.               "CREATE FUNCTION FUNCTION_TEST(str CHAR(100)) " +    
  144.               "returns INT begin atomic return length(str);end";    
  145.             getJdbcTemplate().update(createHsqldbFunctionSql);  
  146.               
  147.             String createProcedureSql =    
  148.               "CREATE PROCEDURE PROCEDURE_TEST" +    
  149.               "(INOUT inOutName VARCHAR(100), OUT outId INT) " +    
  150.               "MODIFIES SQL DATA " +    
  151.               "BEGIN ATOMIC " +    
  152.               "  insert into test(name) values (inOutName); " +    
  153.               "  SET outId = IDENTITY(); " +    
  154.               "  SET inOutName = 'Hello,' + inOutName; " +    
  155.             "END";  
  156.               
  157.             getJdbcTemplate().update(createTableSql);    
  158.             getJdbcTemplate().execute(createProcedureSql);  
  159.               
  160.             getJdbcTemplate().execute("DROP FUNCTION FUNCTION_TEST");    
  161.             getJdbcTemplate().execute("DROP PROCEDURE PROCEDURE_TEST");    
  162.                
  163.             getJdbcTemplate().execute(dropTableSql);   
  164.     }  
  165. /** 
  166.      * @return DriverManagerDataSource 返回数据源对象dataSource 
  167.      */  
  168.     public static DriverManagerDataSource getMyDataSource() {  
  169.         DriverManagerDataSource dataSource = new DriverManagerDataSource(url,  
  170.                 username, password);  
  171.         dataSource.setDriverClassName(driver);  
  172.         return dataSource;  
  173.     }  
  174. }  


NamedParameterJdbcTemplate 
NamedParameterJdbcTemplate类是基于JdbcTemplate类,并对它进行了封装从而支持命名参数特性。NamedParameterJdbcTemplate主要提供以下三类方法: execute方法、 query及queryForXXX方法、update及batchUpdate方法。
 

Java代码  收藏代码
  1. /** 
  2.  * @author Chou 
  3.  * @since 2012-9-9 
  4.  */  
  5. public class NamedParameterJdbcTemplateDao extends NamedParameterJdbcDaoSupport{  
  6.       
  7.     public void setDadasource(DataSource dataSource) {  
  8.         super.setDataSource(dataSource);  
  9.     }  
  10.   
  11.     public void commonSql() {  
  12.         //可以使用DataSource或JdbcTemplate对象作为构造器参数初始化  
  13.         namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(getJdbcTemplate());  
  14.         String insertSql = "insert into tab_item values(:id, :itemno, :itemname)";  
  15.         String deleteSql = "delete from tab_item where id = :id";  
  16.         String selectSql = "select * from player where place = :place";  
  17.   
  18.         //NamedParameterJdbcTemplate类为命名参数设值有两种方式:java.util.Map和SqlParameterSource  
  19.         Map<String, Object> paramMap = new HashMap<String, Object>();  
  20.         paramMap.put("id"101);  
  21.         paramMap.put("itemno""Menzu");  
  22.         paramMap.put("itemname""MP4");  
  23.         int row = namedParameterJdbcTemplate.update(insertSql, paramMap);  
  24.         Assert.isTrue(row == 1"插入失败");  
  25.   
  26.         /** 
  27.          * 可以使用SqlParameterSource实现作为来实现为命名参数设值,默认有MapSqlParameterSource 
  28.          * 和BeanPropertySqlParameterSource实现;MapSqlParameterSource实现非常简单, 
  29.          * 只是封装了java.util.Map;而BeanPropertySqlParameterSource封装了一个JavaBean对象, 
  30.          * 通过JavaBean对象属性来决定命名参数的值。 
  31.          * 可以看出BeanPropertySqlParameterSource使用能减少很多工作量, 
  32.          * 但命名参数必须和JavaBean属性名称相对应才可以。 
  33.          */  
  34.         //Map<String, Object> paramMap2 = new HashMap<String, Object>();  
  35.         //paramMap2.put("id", 1);  
  36.         //SqlParameterSource paramSource = new MapSqlParameterSource(paramMap2);  
  37.           
  38.         Item model = new Item();  
  39.         model.setId(101l);  
  40.         SqlParameterSource paramSource = new BeanPropertySqlParameterSource(model);  
  41.           
  42.         row = namedParameterJdbcTemplate.update(deleteSql, paramSource);  
  43.         Assert.isTrue(row == 1"删除失败");  
  44.           
  45.         Map<String, Object> paramMap1 = new HashMap<String, Object>();  
  46.         paramMap1.put("place","PG   ");  
  47.         namedParameterJdbcTemplate.query(selectSql, paramMap1, new RowCallbackHandler() {  
  48.             @Override  
  49.             public void processRow(ResultSet rs) throws SQLException {  
  50.                 System.out.println(rs.getString("name"));  
  51.             }  
  52.         });  
  53.     }  
  54. }  
  55.   
  56. public class Item {  
  57.     private Long id;  
  58.     private String itemno;  
  59.     private String itemname;  
  60.       
  61.     //省略get和set方法  
  62. }  


SimpleJdbcTemplate 
SimpleJdbcTemplate类也是基于JdbcTemplate类,但利用Java5+的可变参数列表和自动装箱和拆箱从而获取更简洁的代码。但是SimpleJdbcDaoSupport在Spring3.X中已经不推荐使用了。
 

Java代码  收藏代码
  1. /** 
  2.  * @author Chou 
  3.  * @since 2012-9-9  
  4.  */  
  5. public class SimpleJdbcTemplateDao extends SimpleJdbcDaoSupport{  
  6.       
  7.     public void setDadasource(DataSource dataSource) {  
  8.         super.setDataSource(dataSource);  
  9.     }  
  10.   
  11.     public void commonSql() {  
  12.         String insertSql = "update tab_item set itemno = :itemno where itemno = :itemno2";  
  13.         int rows = getSimpleJdbcTemplate().update(insertSql, "APPLE""Apple");  
  14.         System.out.println(rows);  
  15.     }  
  16. }  


SimpleJdbc 
Spring JDBC抽象框架提供SimpleJdbcInsert和SimpleJdbcCall类,这两个类通过利用JDBC驱动提供的数据库元数据来简化JDBC操作。下面代码演示SimpleJdbcInsert用法,SimpleJdbcCall用于调用存储过程及自定义函数,可以参考博客:http://jinnianshilongnian.iteye.com/blog/1428149
 

Java代码  收藏代码
  1. /** 
  2.  * @author Chou 
  3.  * @since 2012-9-9  
  4.  */  
  5. @SuppressWarnings("deprecation")  
  6. public class SimpleJdbcTemplateDao{  
  7.   
  8.     private static SimpleJdbcInsert insert;  
  9.   
  10.     public static void main(String[] args) {  
  11.         insert = new SimpleJdbcInsert(JdbcTemplateTest.getMyDataSource());  
  12.         simpleInsetId()  
  13.         System.out.println(insert.getInsertString());  
  14.     }  
  15.       
  16.     public static void simpleInsetId() {  
  17.         insert.withTableName("tab_item");  
  18.         //主键是数据库自动生成的情况下  
  19.         insert.setGeneratedKeyName("id");  
  20.           
  21.         Map<String, Object> args = new HashMap<String, Object>();  
  22.         args.put("itemno""SONY");  
  23.         args.put("itemname""SONY");  
  24.           
  25.         /** 
  26.          * executeAndReturnKey用于执行并获取自动生成主键(注意是Number类型), 
  27.          * 必须首先通过setGeneratedKeyName设置主键然后才能获取,如果想获取复 
  28.          * 合主键请使用setGeneratedKeyNames描述主键然后通过executeReturningKeyHolder 
  29.          * 获取复合主键KeyHolder对象; 
  30.          */  
  31.         Number id = insert.executeAndReturnKey(args);  
  32.         System.out.println(id);  
  33.     }  
  34. }  



SpringJdbc批量操作 

Java代码  收藏代码
  1. public class BatchExecuteDao extends JdbcDaoSupport{  
  2.       
  3.     public void setDadasource(DataSource dataSource) {  
  4.         super.setDataSource(dataSource);  
  5.     }  
  6.       
  7.     @SuppressWarnings("unchecked")  
  8.     public void batchBySimpleJdbcInsert() {  
  9.          SimpleJdbcInsert insert = new SimpleJdbcInsert(getJdbcTemplate());    
  10.          insert.withTableName("tab_item");    
  11.          Map<String, Object> valueMap = new HashMap<String, Object>();    
  12.          valueMap.put("id"101);  
  13.          valueMap.put("itemno""SONY");  
  14.          valueMap.put("itemname""SONY");  
  15.          Map<String, Object> valueMap2 = new HashMap<String, Object>();    
  16.          valueMap2.put("id"102);  
  17.          valueMap2.put("itemno""SONY");  
  18.          valueMap2.put("itemname""SONY");  
  19.          insert.executeBatch(new Map[] {valueMap, valueMap2});  
  20.          System.out.println(insert.getInsertString());  
  21.     }  
  22.   
  23.     /** 
  24.      * 使用batchUpdate(String sql, List<Object[]> batchArgs)方法完成占位符批处理, 
  25.      * 当然也支持命名参数批处理等 
  26.      */  
  27.     public void batchBySimpleJdbcTemplate() {  
  28.         SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(getJdbcTemplate());    
  29.         String deleteSql = "delete tab_item where id = :id";    
  30.         List<Object[]> params = new ArrayList<Object[]>();    
  31.         params.add(new Object[]{101});  
  32.         params.add(new Object[]{102});  
  33.         params.add(new Object[]{103});  
  34.         params.add(new Object[]{104});  
  35.         simpleJdbcTemplate.batchUpdate(deleteSql, params);  
  36.           
  37.     }  
  38.   
  39.     public void batchByNamedParameterJdbcTemplate() {  
  40.         NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(getJdbcTemplate());  
  41.         String updateSql = "update tab_item set itemname = :itemname where id = :id";  
  42.         Item model1 = new Item();  
  43.         Item model2 = new Item();  
  44.         Item model3 = new Item();  
  45.         Item model4 = new Item();  
  46.         model1.setId(101l);  
  47.         model2.setId(102l);  
  48.         model3.setId(103l);  
  49.         model4.setId(104l);  
  50.           
  51.         model1.setItemname("I9100");  
  52.         model2.setItemname("I9101");  
  53.         model3.setItemname("I9102");  
  54.         model4.setItemname("I9103");  
  55.           
  56.         SqlParameterSource[] params = SqlParameterSourceUtils.createBatch(new Object[] {model1, model2, model3, model4});    
  57.         namedParameterJdbcTemplate.batchUpdate(updateSql, params);  
  58.           
  59.     }  
  60.   
  61.     /** 
  62.      * 通过batchUpdate(String sql, final BatchPreparedStatementSetter pss)方法进行批处理, 
  63.      * 该方式使用预编译语句,然后通过BatchPreparedStatementSetter实现进行设值(setValues) 
  64.      * 及指定批处理大小(getBatchSize)。 
  65.      */  
  66.     public void batchByJdbcTemplate() {  
  67.         String insertSql = "insert into tab_item values(?,?,?)";  
  68.         Object[] arg1 = {101"SUMSUNG""GAS1"};  
  69.         Object[] arg2 = {102"SUMSUNG""GAS2"};  
  70.         Object[] arg3 = {103"SUMSUNG""GAS3"};  
  71.         Object[] arg4 = {104"SUMSUNG""GAS4"};  
  72.         final List<Object[]> list = new ArrayList<Object[]>();  
  73.         list.add(arg1);  
  74.         list.add(arg2);  
  75.         list.add(arg3);  
  76.         list.add(arg4);  
  77.           
  78.         int[] rows = getJdbcTemplate().batchUpdate(insertSql, new BatchPreparedStatementSetter() {  
  79.               
  80.             @Override  
  81.             public void setValues(PreparedStatement ps, int i) throws SQLException {  
  82.                 Object[] obj = list.get(i);  
  83.                 ps.setInt(1, (Integer) obj[0]);  
  84.                 ps.setString(2, (String) obj[1]);  
  85.                 ps.setString(3, (String)obj[2]);  
  86.             }  
  87.               
  88.             @Override  
  89.             public int getBatchSize() {//返回批量操作数最大值  
  90.                 return list.size();  
  91.             }  
  92.         });  
  93.         System.out.println(getJdbcTemplate().getFetchSize());  
  94.         System.out.println(getJdbcTemplate().getQueryTimeout());  
  95.         for (int i = 0; i < rows.length; i++) {  
  96.             System.out.println(rows[i]);  
  97.         }  
  98.           
  99.         Assert.isTrue(list.size() == getJdbcTemplate().queryForInt("select count(1) from tab_item where itemno = 'SUMSUNG'"), "批量更新失败");  
  100.     }  
  101. }  


Xml代码  收藏代码
  1. ...  
  2. <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">    
  3.         <property name="locations">    
  4.           <list>    
  5.               <value>classpath:application.properties</value>    
  6.           </list>    
  7.         </property>  
  8.     </bean>  
  9.       
  10.     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
  11.         <!-- Connection Info -->  
  12.         <property name="driverClassName" value="${db.driver.class}" />  
  13.         <property name="url" value="${db.url}" />  
  14.         <property name="username" value="${db.username}" />  
  15.         <property name="password" value="${db.password}" />  
  16.   
  17.         <!-- Connection Pooling Info -->  
  18.         <property name="initialSize" value="${proxool.initialSize}" />  
  19.         <property name="maxActive" value="${proxool.maxActive}" />  
  20.         <property name="maxIdle" value="${proxool.maxIdle}" />  
  21.         <property name="minIdle" value="${proxool.minIdle}" />  
  22.         <property name="maxWait" value="500" />  
  23.         <property name="poolPreparedStatements" value="false" />  
  24.     </bean>  
  25.       
  26.     <bean id="abstractDao" abstract="true">    
  27.         <property name="dataSource" ref="dataSource"/>    
  28.     </bean>  
  29.       
  30.     <bean id="dao1" class="com.chou.jdbc.JdbcTemplateDao" parent="abstractDao"/>  
  31.     <bean id="dao2" class="com.chou.jdbc.NamedParameterJdbcTemplateDao" parent="abstractDao"/>  
  32.     <bean id="dao3" class="com.chou.jdbc.SimpleJdbcTemplateDao" parent="abstractDao"/>  
  33.     <bean id="dao4" class="com.chou.jdbc.BatchExecuteDao" parent="abstractDao"/>  
  34. ...  


Java代码  收藏代码
  1. db.driver.class=oracle.jdbc.driver.OracleDriver  
  2. db.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl  
  3. db.username=db_test  
  4. db.password=db_test  
  5.   
  6. #连接池连接数初始值  
  7. proxool.initialSize=2  
  8.   
  9. #连接池最大连接数量  
  10. proxool.maxActive=10  
  11.   
  12. #连接池最大空闲值,释放多余的不用的连接,释放到多少为止  
  13. proxool.maxIdle=5  
  14.   
  15. #连接池最小空闲值,当空闲连接数小于这个数的时候,连接池就会去申请一些连接以免高峰期来不及申请  
  16. proxool.minIdle=1  



Spring JDBC自身提供了以下DataSource实现: 

  • DriverManagerDataSource :简单封装了DriverManager获取数据库连接;通过DriverManager的getConnection方法获取数据库连接;
  • SingleConnectionDataSource :内部封装了一个连接,该连接使用后不会关闭,且不能在多线程环境中使用,一般用于测试;
  • LazyConnectionDataSourceProxy :包装一个DataSource,用于延迟获取数据库连接,只有在真正创建Statement等时才获取连接,因此再说实际项目中最后使用该代理包装原始DataSource从而使得只有在真正需要连接时才去获取。


Spring也能通过第三方提供的连接池实现主要有C3P0、Proxool、DBCP 
DBCP没有自动的去回收空闲连接的功能 
C3P0有自动回收空闲连接功能,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。 

DataSourceUtils: 
Spring JDBC抽象框架内部都是通过它的getConnection(DataSource dataSource)方法获取数据库连接,releaseConnection(Connection con, DataSource dataSource) 用于释放数据库连接,DataSourceUtils用于支持Spring管理事务,只有使用DataSourceUtils获取的连接才具有Spring管理事务。 

SpringJdbc在插入数据时也可以获取数据库自动生成的主键,具体用法可以参考博客:http://jinnianshilongnian.iteye.com/blog/1428149

抱歉!评论已关闭.