Spring3核心技术之JdbcTemplate

Spring3核心技术之JdbcTemplate

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. public void setDadasource(DataSource dataSource) {
  10. super.setDataSource(dataSource);
  11. }

  12. public void commonSql() {
  13. String insertSql = "insert into tab_item values(?,?,?)";
  14. String updateSql = "update tab_item set itemno = ?, itemname = ? where id = ?";
  15. String deleteSql = "delete tab_item where id = ?";

  16. Assert.isTrue(
  17. getJdbcTemplate().update(insertSql, new Object[]{4, "HP", "PT540"}) == 1, "插入失败");
  18. Assert.isTrue(
  19. getJdbcTemplate().update(updateSql, new Object[]{"HP", "PT555", 4}) == 1, "修改失败");
  20. Assert.isTrue(
  21. getJdbcTemplate().update(deleteSql, new Object[]{4}) == 1, "删除失败");
  22. }

  23. /**
  24. * 预编译语句设值回调使用
  25. * 通过JdbcTemplate的int update(String sql, PreparedStatementSetter pss)执行预编译sql
  26. */
  27. public void preparedStatementSql() {
  28. String sql = "insert into tab_item values(?,?,?)";
  29. int row = getJdbcTemplate().update(sql, new PreparedStatementSetter() {
  30. @Override
  31. public void setValues(PreparedStatement ps) throws SQLException {
  32. ps.setInt(1, 101);// JDBC占位符集合的序号是从1开始的,而不是0
  33. ps.setObject(2, "Apple");
  34. ps.setString(3, "Ipad4");
  35. }
  36. });
  37. Assert.isTrue(row == 1, "插入失败");

  38. // JdbcTemplate也提供一种更简单的方式设值相应的占位符位置的值
  39. sql = "delete from tab_item where id = ?";
  40. row = getJdbcTemplate().update(sql, new Object[] { 101 });
  41. Assert.isTrue(row == 1, "删除失败");
  42. }

  43. public void queryCallback() {
  44. String listSql = "select * from player";

  45. /**
  46. * RowMapper接口提供mapRow(ResultSet rs, int rowNum)
  47. * 方法将结果集的每一行转换为一个Map,当然可以转换为其他类,如表的对象化形式。
  48. */
  49. List<Map> result = getJdbcTemplate().query(listSql, new RowMapper<Map>() {
  50. @Override
  51. public Map mapRow(ResultSet rs, int rowNum) throws SQLException {
  52. System.out.println(rowNum);
  53. Map<Long,String> map = new HashMap<Long, String>();
  54. map.put(rs.getLong("id"), rs.getString("name"));
  55. return map;
  56. }
  57. });
  58. Iterator it = result.iterator();
  59. while (it.hasNext()) {
  60. Map<Long,String> map = (Map<Long, String>) it.next();
  61. System.out.println(map.values());
  62. }

  63. /**
  64. * RowCallbackHandler接口也提供方法processRow(ResultSet rs),
  65. * 能将结果集的行转换为需要的形式。
  66. */
  67. getJdbcTemplate().query(listSql, new RowCallbackHandler() {
  68. @Override
  69. public void processRow(ResultSet rs) throws SQLException {
  70. System.out.println("处理结果集");
  71. System.out.print("id:" + rs.getInt("id") + "***");
  72. System.out.println("name:" + rs.getString("name"));
  73. }
  74. });

  75. /**
  76. * ResultSetExtractor使用回调方法extractData(ResultSet rs)提供整个结果集,
  77. * 让用户决定如何处理该结果集
  78. */
  79. List list = getJdbcTemplate().query(listSql, new ResultSetExtractor<List>() {
  80. @Override
  81. public List extractData(ResultSet rs) throws SQLException,DataAccessException {
  82. List result = new ArrayList();
  83. while(rs.next()) {
  84. Map row = new HashMap();
  85. row.put(rs.getInt("id"), rs.getString("name"));
  86. result.add(row);
  87. System.out.println(row);
  88. }
  89. return result;
  90. }
  91. });
  92. }

  93. /**
  94. * JdbcTemplate提供更简单的queryForXXX方法,来简化开发:
  95. */
  96. private void queryForSimple() {
  97. //1.查询一行数据并返回int型结果
  98. int countRs = getJdbcTemplate().queryForInt("select count(*) from player");
  99. System.out.println(countRs);

  100. //2. 查询一行数据并将该行数据转换为Map返回
  101. Map map = getJdbcTemplate().queryForMap("select * from tab_item where id = ?", new Object[]{100});
  102. System.out.println(map.values());

  103. //3.查询一行任何类型的数据,最后一个参数指定返回结果类型
  104. countRs = getJdbcTemplate().queryForObject("select count(*) from player", Integer.class);
  105. System.out.println(countRs);

  106. //4.查询一批数据,默认将每行数据转换为Map
  107. List<Map<String, Object>> list = getJdbcTemplate().queryForList("select * from player");
  108. System.out.println(list.get(0).values());

  109. //5.只查询一列数据列表,列类型是String类型,列名字是name
  110. List<String> names = getJdbcTemplate().queryForList("select itemname from tab_item where itemname=?", new Object[]{"雷蛇鼠标"}, String.class);
  111. System.out.println(names.size());

  112. //6.查询一批数据,返回为SqlRowSet,类似于ResultSet,但不再绑定到连接上
  113. SqlRowSet rs = getJdbcTemplate().queryForRowSet("select * from player");
  114. }

  115. /**
  116. * 调用建表,删表语句
  117. * 数据库不同,创建存储过程的SQL也不同
  118. */
  119. public void createProcedure() {
  120. String createTableSql = "create memory table test" +
  121. "(id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, " +
  122. "name varchar(100))";

  123. String dropTableSql = "drop table test";

  124. String createHsqldbFunctionSql =
  125. "CREATE FUNCTION FUNCTION_TEST(str CHAR(100)) " +
  126. "returns INT begin atomic return length(str);end";
  127. getJdbcTemplate().update(createHsqldbFunctionSql);

  128. String createProcedureSql =
  129. "CREATE PROCEDURE PROCEDURE_TEST" +
  130. "(INOUT inOutName VARCHAR(100), OUT outId INT) " +
  131. "MODIFIES SQL DATA " +
  132. "BEGIN ATOMIC " +
  133. " insert into test(name) values (inOutName); " +
  134. " SET outId = IDENTITY(); " +
  135. " SET inOutName = 'Hello,' + inOutName; " +
  136. "END";

  137. getJdbcTemplate().update(createTableSql);
  138. getJdbcTemplate().execute(createProcedureSql);

  139. getJdbcTemplate().execute("DROP FUNCTION FUNCTION_TEST");
  140. getJdbcTemplate().execute("DROP PROCEDURE PROCEDURE_TEST");

  141. getJdbcTemplate().execute(dropTableSql);
  142. }
  143. /**
  144. * @return DriverManagerDataSource 返回数据源对象dataSource
  145. */
  146. public static DriverManagerDataSource getMyDataSource() {
  147. DriverManagerDataSource dataSource = new DriverManagerDataSource(url,
  148. username, password);
  149. dataSource.setDriverClassName(driver);
  150. return dataSource;
  151. }
  152. }

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. public void setDadasource(DataSource dataSource) {
  7. super.setDataSource(dataSource);
  8. }

  9. public void commonSql() {
  10. //可以使用DataSource或JdbcTemplate对象作为构造器参数初始化
  11. namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(getJdbcTemplate());
  12. String insertSql = "insert into tab_item values(:id, :itemno, :itemname)";
  13. String deleteSql = "delete from tab_item where id = :id";
  14. String selectSql = "select * from player where place = :place";

  15. //NamedParameterJdbcTemplate类为命名参数设值有两种方式:java.util.Map和SqlParameterSource
  16. Map<String, Object> paramMap = new HashMap<String, Object>();
  17. paramMap.put("id", 101);
  18. paramMap.put("itemno", "Menzu");
  19. paramMap.put("itemname", "MP4");
  20. int row = namedParameterJdbcTemplate.update(insertSql, paramMap);
  21. Assert.isTrue(row == 1, "插入失败");

  22. /**
  23. * 可以使用SqlParameterSource实现作为来实现为命名参数设值,默认有MapSqlParameterSource
  24. * 和BeanPropertySqlParameterSource实现;MapSqlParameterSource实现非常简单,
  25. * 只是封装了java.util.Map;而BeanPropertySqlParameterSource封装了一个JavaBean对象,
  26. * 通过JavaBean对象属性来决定命名参数的值。
  27. * 可以看出BeanPropertySqlParameterSource使用能减少很多工作量,
  28. * 但命名参数必须和JavaBean属性名称相对应才可以。
  29. */
  30. //Map<String, Object> paramMap2 = new HashMap<String, Object>();
  31. //paramMap2.put("id", 1);
  32. //SqlParameterSource paramSource = new MapSqlParameterSource(paramMap2);

  33. Item model = new Item();
  34. model.setId(101l);
  35. SqlParameterSource paramSource = new BeanPropertySqlParameterSource(model);

  36. row = namedParameterJdbcTemplate.update(deleteSql, paramSource);
  37. Assert.isTrue(row == 1, "删除失败");

  38. Map<String, Object> paramMap1 = new HashMap<String, Object>();
  39. paramMap1.put("place","PG ");
  40. namedParameterJdbcTemplate.query(selectSql, paramMap1, new RowCallbackHandler() {
  41. @Override
  42. public void processRow(ResultSet rs) throws SQLException {
  43. System.out.println(rs.getString("name"));
  44. }
  45. });
  46. }
  47. }

  48. public class Item {
  49. private Long id;
  50. private String itemno;
  51. private String itemname;

  52. //省略get和set方法
  53. }

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. public void setDadasource(DataSource dataSource) {
  7. super.setDataSource(dataSource);
  8. }

  9. public void commonSql() {
  10. String insertSql = "update tab_item set itemno = :itemno where itemno = :itemno2";
  11. int rows = getSimpleJdbcTemplate().update(insertSql, "APPLE", "Apple");
  12. System.out.println(rows);
  13. }
  14. }

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. private static SimpleJdbcInsert insert;

  8. public static void main(String[] args) {
  9. insert = new SimpleJdbcInsert(JdbcTemplateTest.getMyDataSource());
  10. simpleInsetId()
  11. System.out.println(insert.getInsertString());
  12. }

  13. public static void simpleInsetId() {
  14. insert.withTableName("tab_item");
  15. //主键是数据库自动生成的情况下
  16. insert.setGeneratedKeyName("id");

  17. Map<String, Object> args = new HashMap<String, Object>();
  18. args.put("itemno", "SONY");
  19. args.put("itemname", "SONY");

  20. /**
  21. * executeAndReturnKey用于执行并获取自动生成主键(注意是Number类型),
  22. * 必须首先通过setGeneratedKeyName设置主键然后才能获取,如果想获取复
  23. * 合主键请使用setGeneratedKeyNames描述主键然后通过executeReturningKeyHolder
  24. * 获取复合主键KeyHolder对象;
  25. */
  26. Number id = insert.executeAndReturnKey(args);
  27. System.out.println(id);
  28. }
  29. }


SpringJdbc批量操作
Java代码 复制代码 收藏代码
  1. public class BatchExecuteDao extends JdbcDaoSupport{

  2. public void setDadasource(DataSource dataSource) {
  3. super.setDataSource(dataSource);
  4. }

  5. @SuppressWarnings("unchecked")
  6. public void batchBySimpleJdbcInsert() {
  7. SimpleJdbcInsert insert = new SimpleJdbcInsert(getJdbcTemplate());
  8. insert.withTableName("tab_item");
  9. Map<String, Object> valueMap = new HashMap<String, Object>();
  10. valueMap.put("id", 101);
  11. valueMap.put("itemno", "SONY");
  12. valueMap.put("itemname", "SONY");
  13. Map<String, Object> valueMap2 = new HashMap<String, Object>();
  14. valueMap2.put("id", 102);
  15. valueMap2.put("itemno", "SONY");
  16. valueMap2.put("itemname", "SONY");
  17. insert.executeBatch(new Map[] {valueMap, valueMap2});
  18. System.out.println(insert.getInsertString());
  19. }

  20. /**
  21. * 使用batchUpdate(String sql, List<Object[]> batchArgs)方法完成占位符批处理,
  22. * 当然也支持命名参数批处理等
  23. */
  24. public void batchBySimpleJdbcTemplate() {
  25. SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(getJdbcTemplate());
  26. String deleteSql = "delete tab_item where id = :id";
  27. List<Object[]> params = new ArrayList<Object[]>();
  28. params.add(new Object[]{101});
  29. params.add(new Object[]{102});
  30. params.add(new Object[]{103});
  31. params.add(new Object[]{104});
  32. simpleJdbcTemplate.batchUpdate(deleteSql, params);

  33. }

  34. public void batchByNamedParameterJdbcTemplate() {
  35. NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(getJdbcTemplate());
  36. String updateSql = "update tab_item set itemname = :itemname where id = :id";
  37. Item model1 = new Item();
  38. Item model2 = new Item();
  39. Item model3 = new Item();
  40. Item model4 = new Item();
  41. model1.setId(101l);
  42. model2.setId(102l);
  43. model3.setId(103l);
  44. model4.setId(104l);

  45. model1.setItemname("I9100");
  46. model2.setItemname("I9101");
  47. model3.setItemname("I9102");
  48. model4.setItemname("I9103");

  49. SqlParameterSource[] params = SqlParameterSourceUtils.createBatch(new Object[] {model1, model2, model3, model4});
  50. namedParameterJdbcTemplate.batchUpdate(updateSql, params);

  51. }

  52. /**
  53. * 通过batchUpdate(String sql, final BatchPreparedStatementSetter pss)方法进行批处理,
  54. * 该方式使用预编译语句,然后通过BatchPreparedStatementSetter实现进行设值(setValues)
  55. * 及指定批处理大小(getBatchSize)。
  56. */
  57. public void batchByJdbcTemplate() {
  58. String insertSql = "insert into tab_item values(?,?,?)";
  59. Object[] arg1 = {101, "SUMSUNG", "GAS1"};
  60. Object[] arg2 = {102, "SUMSUNG", "GAS2"};
  61. Object[] arg3 = {103, "SUMSUNG", "GAS3"};
  62. Object[] arg4 = {104, "SUMSUNG", "GAS4"};
  63. final List<Object[]> list = new ArrayList<Object[]>();
  64. list.add(arg1);
  65. list.add(arg2);
  66. list.add(arg3);
  67. list.add(arg4);

  68. int[] rows = getJdbcTemplate().batchUpdate(insertSql, new BatchPreparedStatementSetter() {

  69. @Override
  70. public void setValues(PreparedStatement ps, int i) throws SQLException {
  71. Object[] obj = list.get(i);
  72. ps.setInt(1, (Integer) obj[0]);
  73. ps.setString(2, (String) obj[1]);
  74. ps.setString(3, (String)obj[2]);
  75. }

  76. @Override
  77. public int getBatchSize() {//返回批量操作数最大值
  78. return list.size();
  79. }
  80. });
  81. System.out.println(getJdbcTemplate().getFetchSize());
  82. System.out.println(getJdbcTemplate().getQueryTimeout());
  83. for (int i = 0; i < rows.length; i++) {
  84. System.out.println(rows[i]);
  85. }

  86. Assert.isTrue(list.size() == getJdbcTemplate().queryForInt("select count(1) from tab_item where itemno = 'SUMSUNG'"), "批量更新失败");
  87. }
  88. }

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. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  10. <!-- Connection Info -->
  11. <property name="driverClassName" value="${db.driver.class}" />
  12. <property name="url" value="${db.url}" />
  13. <property name="username" value="${db.username}" />
  14. <property name="password" value="${db.password}" />

  15. <!-- Connection Pooling Info -->
  16. <property name="initialSize" value="${proxool.initialSize}" />
  17. <property name="maxActive" value="${proxool.maxActive}" />
  18. <property name="maxIdle" value="${proxool.maxIdle}" />
  19. <property name="minIdle" value="${proxool.minIdle}" />
  20. <property name="maxWait" value="500" />
  21. <property name="poolPreparedStatements" value="false" />
  22. </bean>

  23. <bean id="abstractDao" abstract="true">
  24. <property name="dataSource" ref="dataSource"/>
  25. </bean>

  26. <bean id="dao1" class="com.chou.jdbc.JdbcTemplateDao" parent="abstractDao"/>
  27. <bean id="dao2" class="com.chou.jdbc.NamedParameterJdbcTemplateDao" parent="abstractDao"/>
  28. <bean id="dao3" class="com.chou.jdbc.SimpleJdbcTemplateDao" parent="abstractDao"/>
  29. <bean id="dao4" class="com.chou.jdbc.BatchExecuteDao" parent="abstractDao"/>
  30. ...

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. proxool.initialSize=2

  7. #连接池最大连接数量
  8. proxool.maxActive=10

  9. #连接池最大空闲值,释放多余的不用的连接,释放到多少为止
  10. proxool.maxIdle=5

  11. #连接池最小空闲值,当空闲连接数小于这个数的时候,连接池就会去申请一些连接以免高峰期来不及申请
  12. 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
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值