对spring JdbcTemplate的一个扩展(使其支持单Connection).
不怕大家笑话,以前一直没怎么使用过spring jdbc template,
印象中只用过
public List queryForList(String sql, Object[] args)
public Map queryForMap(String sql, Object[] args)
和SqlFunction
在orm大行其道,spring诞生快一个实际的今天,再来探讨jdbc的一些封装实在不知道有没有意义.
不过还是想把刚刚弄出来的一点东西和大家分享.
看了一下 JdbcTemplate,
发现起核心是那几个 execute 方法.
而那几个execute方法的机构大概是这样(重点讨论Connection,所以其他地方从简)
代码
- execute方法开始
-
- Connection con = DataSourceUtils.getConnection(getDataSource());
-
-
-
- DataSourceUtils.releaseConnection(con, getDataSource());
-
- execute方法结束
<script>render_code();</script>
当你要批量执行一些操作时(不是 每个操作使用不同的sql,或者是其他不适合 addBatch的情形).
如下:
代码
- JdbcTemplate jdbcTemplate=new JdbcTemplate(ds);
- jdbcTemplate.query(sql_1, args_1,rch_1);
- jdbcTemplate.query(sql_2, args_2,rch_2);
- jdbcTemplate.query(sql_3, args_3,rch_3);
- jdbcTemplate.query(sql_4, args_4,rch_4);
- ......
<script>render_code();</script>
此时,在内部实际上执行了,n次 getConnection,releaseConnection.
而这些操作,在很多时候,是可以通过一个Connection来完成的.
我的扩展就是实现了这个功能.
代码
-
- JdbcTemplatePlus jdbcTemplate=new JdbcTemplatePlus(ds);
-
- jdbcTemplate.setUseOneConnection(true);
- jdbcTemplate.query(sql_1, args_1,rch_1);
- jdbcTemplate.query(sql_2, args_2,rch_2);
- jdbcTemplate.query(sql_3, args_3,rch_3);
- jdbcTemplate.query(sql_4, args_4,rch_4);
- ......
-
-
- jdbcTemplate.releaseConnection();
-
<script>render_code();</script>
我们系统中,有大量的嵌套查询.使用该JdbcTemplatePlus的唯一Connection特性后,类似的操作速度提升明显.
(不过可能我们原先的做法不对,也许 spring内部已经实现这个机制了 这些我就不明白了,欢迎大家来指正)
我们原先的做法(伪代码):
代码
-
- public List queryNsubQueryUserList(Map param){
-
-
- final String bsql="select * from ......";
- final JdbcTemplate jdbcTemplate=createJdbcTemplate();
-
-
- final String subSql="select ............ ";
- final JdbcTemplate subJdbcTemplate=createJdbcTemplate();
-
- List rslist=jdbcTemplate.query(bsql.toString(),sqlArg,
- new ResultSetHandler(){
- public void processRow(ResultSet rs) throws SQLException {
- final 一个VO recordObj=new 一个VO();
-
- subJdbcTemplate.query(subSql, subQueryArgs,
- new ResultSetHandler(){
- public void processRow(ResultSet rs) throws SQLException {
-
- }
- }
- );
-
- recordObj.setXXXXX(rs.getString("XXXXX"));
- .........
-
- addRecord(recordObj);
- }
- }
- );
- return rslist;
- }
- }
-
<script>render_code();</script>
在使用 JdbcTemplatePlus 代替 JdbcTemplate,并设置.setUseOneConnection(true)后,
耗时变为原先的1/8左右.
扩展的 JdbcTemplatePlus 代码如下,欢迎大家拍砖,挑错.
对 execute方法的修改如下:
把所有的 this.ativeJdbcExtractor换成 getNativeJdbcExtractor(), 这个是必须的 呵呵.
把所有 Connection con = DataSourceUtils.getConnection(getDataSource()); 换成
Connection con = tryGetConnection();
把所有 DataSourceUtils.releaseConnection(con, getDataSource()); 换成
tryReleaseConnection(con);
代码
-
- package com.neusoft.tdframework.dao;
-
- import java.sql.CallableStatement;
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.SQLException;
- import java.sql.Statement;
-
- import javax.sql.DataSource;
-
- import org.springframework.dao.DataAccessException;
- import org.springframework.jdbc.core.CallableStatementCallback;
- import org.springframework.jdbc.core.CallableStatementCreator;
- import org.springframework.jdbc.core.ConnectionCallback;
- import org.springframework.jdbc.core.JdbcTemplate;
- import org.springframework.jdbc.core.ParameterDisposer;
- import org.springframework.jdbc.core.PreparedStatementCallback;
- import org.springframework.jdbc.core.PreparedStatementCreator;
- import org.springframework.jdbc.core.SqlProvider;
- import org.springframework.jdbc.core.StatementCallback;
- import org.springframework.jdbc.datasource.DataSourceUtils;
- import org.springframework.jdbc.support.JdbcUtils;
- import org.springframework.util.Assert;
-
- public class JdbcTemplatePlus extends JdbcTemplate {
-
- private Connection connection=null;
- private boolean useOneConnection=false;
-
- public JdbcTemplatePlus() {
- super();
- }
- public JdbcTemplatePlus(DataSource dataSource) {
- super(dataSource);
- }
- public JdbcTemplatePlus(DataSource dataSource, boolean lazyInit) {
- super(dataSource,lazyInit);
- }
-
- private Connection tryGetConnection(){
- if (useOneConnection){
- if (connection==null){
- connection= DataSourceUtils.getConnection(getDataSource());
- }
- return connection;
- }
- return DataSourceUtils.getConnection(getDataSource());
- }
-
- private void tryReleaseConnection(Connection con){
- if (!useOneConnection){
- DataSourceUtils.releaseConnection(con, getDataSource());
- }
- }
-
- public Connection getConnection(){
- return connection;
- }
-
- public void setConnection(Connection connection){
- this.connection=connection;
- }
-
- public boolean isUseOneConnection() {
- return useOneConnection;
- }
-
- public void setUseOneConnection(boolean useOneConnection) {
- this.useOneConnection = useOneConnection;
- }
-
- public void releaseConnection(){
- DataSourceUtils.releaseConnection(connection, getDataSource());
- }
-
-
-
-
- public static String getSql(Object sqlProvider) {
- if (sqlProvider instanceof SqlProvider) {
- return ((SqlProvider) sqlProvider).getSql();
- }
- else {
- return null;
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
- public Object execute(ConnectionCallback action) throws DataAccessException {
- Assert.notNull(action, "Callback object must not be null");
-
- Connection con = tryGetConnection();
- try {
- Connection conToUse = con;
- if (getNativeJdbcExtractor() != null) {
- conToUse = getNativeJdbcExtractor().getNativeConnection(con);
- } else {
- conToUse = createConnectionProxy(con);
- }
- return action.doInConnection(conToUse);
- } catch (SQLException ex) {
- tryReleaseConnection(con);
- con = null;
- throw getExceptionTranslator().translate("ConnectionCallback",
- getSql(action), ex);
- } finally {
- tryReleaseConnection(con);
- }
- }
-
- public Object execute(StatementCallback action) throws DataAccessException {
- Assert.notNull(action, "Callback object must not be null");
-
- Connection con = tryGetConnection();
- Statement stmt = null;
- try {
- Connection conToUse = con;
- if (getNativeJdbcExtractor() != null
- && getNativeJdbcExtractor()
- .isNativeConnectionNecessaryForNativeStatements()) {
- conToUse = getNativeJdbcExtractor().getNativeConnection(con);
- }
- stmt = conToUse.createStatement();
- applyStatementSettings(stmt);
- Statement stmtToUse = stmt;
- if (getNativeJdbcExtractor() != null) {
- stmtToUse = getNativeJdbcExtractor().getNativeStatement(stmt);
- }
- Object result = action.doInStatement(stmtToUse);
- handleWarnings(stmt.getWarnings());
- return result;
- } catch (SQLException ex) {
- JdbcUtils.closeStatement(stmt);
- stmt = null;
- tryReleaseConnection(con);
- con = null;
- throw getExceptionTranslator().translate("StatementCallback",
- getSql(action), ex);
- } finally {
- JdbcUtils.closeStatement(stmt);
- tryReleaseConnection(con);
- }
- }
-
- public Object execute(PreparedStatementCreator psc,
- PreparedStatementCallback action) throws DataAccessException {
-
- Assert.notNull(psc, "PreparedStatementCreator must not be null");
- Assert.notNull(action, "Callback object must not be null");
- if (logger.isDebugEnabled()) {
- String sql = getSql(psc);
- logger.debug("Executing prepared SQL statement"
- + (sql != null ? " [" + sql + "]" : ""));
- }
-
- Connection con = tryGetConnection();
- PreparedStatement ps = null;
- try {
- Connection conToUse = con;
- if (getNativeJdbcExtractor() != null
- && getNativeJdbcExtractor()
- .isNativeConnectionNecessaryForNativePreparedStatements()) {
- conToUse = getNativeJdbcExtractor().getNativeConnection(con);
- }
- ps = psc.createPreparedStatement(conToUse);
- applyStatementSettings(ps);
- PreparedStatement psToUse = ps;
- if (getNativeJdbcExtractor() != null) {
- psToUse = getNativeJdbcExtractor()
- .getNativePreparedStatement(ps);
- }
- Object result = action.doInPreparedStatement(psToUse);
- handleWarnings(ps.getWarnings());
- return result;
- } catch (SQLException ex) {
- if (psc instanceof ParameterDisposer) {
- ((ParameterDisposer) psc).cleanupParameters();
- }
- String sql = getSql(psc);
- psc = null;
- JdbcUtils.closeStatement(ps);
- ps = null;
- tryReleaseConnection(con);
- con = null;
- throw getExceptionTranslator().translate(
- "PreparedStatementCallback", sql, ex);
- } finally {
- if (psc instanceof ParameterDisposer) {
- ((ParameterDisposer) psc).cleanupParameters();
- }
- JdbcUtils.closeStatement(ps);
- tryReleaseConnection(con);
- }
- }
-
- public Object execute(CallableStatementCreator csc,
- CallableStatementCallback action) throws DataAccessException {
-
- Assert.notNull(csc, "CallableStatementCreator must not be null");
- Assert.notNull(action, "Callback object must not be null");
- if (logger.isDebugEnabled()) {
- String sql = getSql(csc);
- logger.debug("Calling stored procedure"
- + (sql != null ? " [" + sql + "]" : ""));
- }
-
- Connection con = tryGetConnection();
- CallableStatement cs = null;
- try {
- Connection conToUse = con;
- if (getNativeJdbcExtractor() != null) {
- conToUse = getNativeJdbcExtractor().getNativeConnection(con);
- }
- cs = csc.createCallableStatement(conToUse);
- applyStatementSettings(cs);
- CallableStatement csToUse = cs;
- if (getNativeJdbcExtractor() != null) {
- csToUse = getNativeJdbcExtractor()
- .getNativeCallableStatement(cs);
- }
- Object result = action.doInCallableStatement(csToUse);
- handleWarnings(cs.getWarnings());
- return result;
- } catch (SQLException ex) {
-
-
-
-
- if (csc instanceof ParameterDisposer) {
- ((ParameterDisposer) csc).cleanupParameters();
- }
- String sql = getSql(csc);
- csc = null;
- JdbcUtils.closeStatement(cs);
- cs = null;
- tryReleaseConnection(con);
- con = null;
- throw getExceptionTranslator().translate(
- "CallableStatementCallback", sql, ex);
- } finally {
- if (csc instanceof ParameterDisposer) {
- ((ParameterDisposer) csc).cleanupParameters();
- }
- JdbcUtils.closeStatement(cs);
- tryReleaseConnection(con);
- }
- }
-
- protected void finalize() throws Throwable{
- super.finalize();
- releaseConnection();
- }
-
-
- }
|
相关推荐
JdbcTemplate是Spring提供的一个用于简化数据库操作的API,它是Spring对JDBC(Java Database Connectivity)的轻量级封装。通过使用JdbcTemplate,开发者可以避免编写大量的样板代码,如打开和关闭连接、处理结果集...
9.9.1. 对一个特定的 DataSource 使用了错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 11.1. 简介 11.1.1. 选择一...
Spring-JDBC是Spring框架的一个重要模块,它提供了一种简化数据库操作的抽象层,使得开发者可以更加方便地进行数据访问。在本篇文章中,我们将深入探讨Spring-JdbcTemplate、DataSourceTransactionManager以及相关的...
9.9.1. 对一个特定的 DataSource 使用错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 11.1. 简介 11.1.1. Spring JDBC包结构...
3. **NamedParameterJdbcTemplate**:这是JdbcTemplate的一个扩展,允许使用命名参数代替占位符,使得SQL语句更易读和维护。 4. **Transaction Management**:Spring提供了声明式事务管理,通过在方法上添加@...
9.9.1. 对一个特定的 DataSource 使用错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 11.1. 简介 11.1.1. Spring ...
9.9.1. 对一个特定的 DataSource 使用了错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 11.1. 简介 11.1.1. 选择一种...
9.9.1. 对一个特定的 DataSource 使用错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 11.1. 简介 11.1.1. Spring ...
JMS 1.1 是其一个重要版本,它提供了应用程序间的可靠通信,使得消息的生产者和消费者可以在不同的时间进行交互,即使它们可能同时处于运行状态或暂时离线。以下是对 JMS 1.1 规范中的关键知识点的详细解释: 1. **...
c3p0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。配置信息通常放在`jdbc.properties`文件中,包括数据库URL、用户名、密码以及连接池的相关参数。 **1.2 配置JdbcTemplate...
`JdbcTemplate`是Spring框架提供的一个用于简化JDBC编程的工具类,它封装了许多常用的数据库操作,如查询、更新等,并且通过模板模式设计,提供了灵活的扩展机制。这使得开发者能够更专注于业务逻辑而非繁琐的JDBC...
DataSource可以配置在应用服务器中,这样多个应用程序可以共享同一个数据源,减少了资源消耗。同时,应用服务器会负责管理这些连接,包括连接池的创建、连接的分配和释放,确保了高效且线程安全的数据库访问。 在...
- C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。 - C3P0的优势在于其内置的自动检测和修复损坏的连接功能,以及对多线程环境的良好支持。 - 配置C3P0的步骤与DBCP...
**Spring** 是一个开源的轻量级Java开发框架,主要用于简化企业级应用的开发过程。它最初由Rod Johnson创建,并于2004年首次发布。Spring框架的核心特性是**控制反转(Inversion of Control, IoC)**和**面向切面...
在本课程"02-01-11-基于Spring JDBC手写定制自己的ORM框架1"中,我们将探讨如何利用Spring的JdbcTemplate设计理念,来构建一个自定义的ORM(对象关系映射)框架。ORM框架的主要目的是简化Java应用程序与数据库之间的...
这里定义了一个名为`DynamicDataSource`的`Bean`,它能够根据传入的键值动态地选择数据源。 #### 5. jdbcTemplate配置 最后,还需要配置`jdbcTemplate`以供业务层调用。 ```xml <!-- jdbcTemplate配置 --> ...
在构建一个音乐网站平台系统的过程中,技术和工具的选择至关重要。在这个项目中,主要涉及了两个核心部分:数据爬取和后端服务的搭建。下面将详细阐述这两个方面。 首先,我们来看数据爬取部分,这里使用了`Jsoup`...
Java通过Druid连接MySQL是一种常见的数据库操作方式,Druid是一个强大的数据库连接池组件,由阿里巴巴开源,它提供了优秀的性能、全面的监控以及强大的扩展性。在这个场景中,我们将探讨如何在Java环境中使用Druid来...
Spatialite是一个开源的扩展,它为SQLite数据库添加了对地理空间数据的支持,使其能够处理复杂的地理空间操作。 首先,你需要确保在系统`system32`目录下已经安装并配置了Spatialite的相关库。通常,这包括`...
多对一关系是指多个实体对象与另一个实体对象之间存在关联关系。例如,一个订单可能属于一个客户,但一个客户可以拥有多个订单。在Hibernate中,可以通过`@ManyToOne`注解来定义这种关系。 **示例代码**: ```java...