- 浏览: 840651 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
renzhengzhi:
请教一下楼主,公有云和私有云的开发,具体要做哪些工作呢?我拿到 ...
4,云的4 种模式 -
SangBillLee:
我用了solr5.5,用SolrQuery查询,没法高亮,不知 ...
solr5.x快速入门 -
lw900925:
这翻译读起来真是别扭。
solr in action翻译-第一章1.1 -
springjpa_springmvc:
spring mvc demo教程源代码下载,地址:http: ...
Spring MVC性能提升 -
h416373073:
正遇到了此问题不知如何解决, 多谢分享
solr错误
用语句创建器更新数据库
第一个回调接口是PerparedStatementCreator,实现这个接口来覆盖整个更新过程的语句创建任务。我们先看下源代码中的PerparedStatementCreator接口,然后实现我们自己的接
口。
public interface PreparedStatementCreator { /** * Create a statement in this connection. Allows implementations to use * PreparedStatements. The JdbcTemplate will close the created statement. * @param con Connection to use to create statement * @return a prepared statement * @throws SQLException there is no need to catch SQLExceptions * that may be thrown in the implementation of this method. * The JdbcTemplate class will handle them. */ PreparedStatement createPreparedStatement(Connection con) throws SQLException; }
源代码中只定义了一个方法createPreparedStatement,在connection连接的基础上创建statement,使我们可以使用PreparedStatements实例,创建完,jdbcTemplate会自动关闭
Connection连接,下面我们实现这个接口。
public class InsertPreparedStatementCreator implements PreparedStatementCreator{ private User user; public InsertPreparedStatementCreator(User user){ this.user = user; } public PreparedStatement createPreparedStatement(Connection conn)throws Exception{ String sql = "insert into user value(?,?); PreparedStatement ps = conn.prepareStatement(sql); ps.setString(user.getUsername()); ps.setString(user.getPassword()); return ps; } }
我们实现后,只需要创建PreparedStatement ,并且把参数绑定上去,然后返回,在处理过程中不需要进行异常处理,因为方法签名中已经给我们抛出了异常,也不用关闭数据库
连接或者打开数据库连接,这些spring都给我们做好了,然后调用jdbcTemplate中的update方法即可。
jdbcTemplate.update(new InsertPreparedStatementCreator(user));
当然也可以用另一种方式。
jdbcTemplate.update(new PreparedStatementCreator(){ String sql = "insert into user value(?,?); PreparedStatement ps = conn.prepareStatement(sql); ps.setString(user.getUsername()); ps.setString(user.getPassword()); return ps; });
这里其实是个回调函数,在设计模式中是模板方法模式。
模板方法使用继承机制实现。在父类中定义不变的,然后把变化的定义成一个抽象方法,供子类实现。因此模板方法的 父类一般也是一个抽象类。
在jdbcTemplate中的执行:
我们的update方法调用了jdbcTemplate方法中的
public int update(PreparedStatementCreator psc) throws DataAccessException { return update(psc, (PreparedStatementSetter) null); }
接着调用
protected int update(final PreparedStatementCreator psc, final PreparedStatementSetter pss) throws DataAccessException { if (logger.isDebugEnabled()) { String sql = getSql(psc); logger.debug("Executing SQL update" + (sql != null ? " [" + sql + "]" : "")); } Integer result = (Integer) execute(psc, new PreparedStatementCallback() { public Object doInPreparedStatement(PreparedStatement ps) throws SQLException { try { if (pss != null) { pss.setValues(ps); } int rows = ps.executeUpdate(); if (logger.isDebugEnabled()) { logger.debug("SQL update affected " + rows + " rows"); } return new Integer(rows); } finally { if (pss instanceof ParameterDisposer) { ((ParameterDisposer) pss).cleanupParameters(); } } } }); return result.intValue(); }
方法的关键:
int rows = ps.executeUpdate();
return new Integer(rows);
执行了preparedStatement.executeUpdate().然后返回执行后的值,和我们自己写是一样。在这里还是没有看到spring是如何打开数据库连接的。继续看,注意到一个方法的调用
Integer result = (Integer) execute(psc, new PreparedStatementCallback() 。。。。。。
我们找到这个方法
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"); Connection con = DataSourceUtils.getConnection(getDataSource()); PreparedStatement ps = null; try { Connection conToUse = con; if (this.nativeJdbcExtractor != null && this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativePreparedStatements()) { conToUse = this.nativeJdbcExtractor.getNativeConnection(con); } ps = psc.createPreparedStatement(conToUse); applyStatementSettings(ps); PreparedStatement psToUse = ps; if (this.nativeJdbcExtractor != null) { psToUse = this.nativeJdbcExtractor.getNativePreparedStatement(ps); } Object result = action.doInPreparedStatement(psToUse); SQLWarning warning = ps.getWarnings(); throwExceptionOnWarningIfNotIgnoringWarnings(warning); return result; } catch (SQLException ex) { // Release Connection early, to avoid potential connection pool deadlock // in the case when the exception translator hasn't been initialized yet. if (psc instanceof ParameterDisposer) { ((ParameterDisposer) psc).cleanupParameters(); } String sql = getSql(psc); psc = null; JdbcUtils.closeStatement(ps); ps = null; DataSourceUtils.releaseConnection(con, getDataSource()); con = null; throw getExceptionTranslator().translate("PreparedStatementCallback", sql, ex); } finally { if (psc instanceof ParameterDisposer) { ((ParameterDisposer) psc).cleanupParameters(); } JdbcUtils.closeStatement(ps); DataSourceUtils.releaseConnection(con, getDataSource()); } }
里面有这么一句Connection con = DataSourceUtils.getConnection(getDataSource());
这里获取数据库数据库连接。我们看看他是怎么获取的数据库连接。
进入DataSourceUtils这个类中
public static Connection getConnection(DataSource dataSource) throws CannotGetJdbcConnectionException { try { return doGetConnection(dataSource); } catch (SQLException ex) { throw new CannotGetJdbcConnectionException("Could not get JDBC Connection", ex); } } public static Connection doGetConnection(DataSource dataSource) throws SQLException { Assert.notNull(dataSource, "No DataSource specified"); ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource); if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) { conHolder.requested(); if (!conHolder.hasConnection()) { logger.debug("Fetching resumed JDBC Connection from DataSource"); conHolder.setConnection(dataSource.getConnection()); } return conHolder.getConnection(); } // Else we either got no holder or an empty thread-bound holder here. logger.debug("Fetching JDBC Connection from DataSource"); Connection con = dataSource.getConnection(); if (TransactionSynchronizationManager.isSynchronizationActive()) { logger.debug("Registering transaction synchronization for JDBC Connection"); // Use same Connection for further JDBC actions within the transaction. // Thread-bound object will get removed by synchronization at transaction completion. ConnectionHolder holderToUse = conHolder; if (holderToUse == null) { holderToUse = new ConnectionHolder(con); } else { holderToUse.setConnection(con); } holderToUse.requested(); TransactionSynchronizationManager.registerSynchronization( new ConnectionSynchronization(holderToUse, dataSource)); holderToUse.setSynchronizedWithTransaction(true); if (holderToUse != conHolder) { TransactionSynchronizationManager.bindResource(dataSource, holderToUse); } } return con; }
spring会先去ConnectionHolder 中获取Connection,如果有直接从ConnectionHolder 获取conennction. conHolder.getConnection();如果没有则conHolder.setConnection
(dataSource.getConnection());,然后继续conennction. conHolder.getConnection(),说白了Connection是从ConnectionHolder 中获取的。
我们继续往深处看看,ConnectionHolder 是怎么把Connection给我们的。我们进入ConnectionHolder这个类中
public class ConnectionHolder extends ResourceHolderSupport,ConnectionHolder继承自抽象类 ResourceHolderSupport,我们暂时先不讨论这个类,主要看
ConnectionHolder.
public Connection getConnection() { Assert.notNull(this.connectionHandle, "Active Connection is required"); if (this.currentConnection == null) { this.currentConnection = this.connectionHandle.getConnection(); } return this.currentConnection; }
原来ConnectionHolder也不是现实取得Connection真正的类,它是从connectionHandle中获取的,
我们在进入ConnectionHandle这个处理类中,
public interface ConnectionHandle { /** * Fetch the JDBC Connection that this handle refers to. */ Connection getConnection(); /** * Release the JDBC Connection that this handle refers to. * @param con the JDBC Connection to release */ void releaseConnection(Connection con); }
发现什么也没有,只是一个接口,定义了一个标准。既然是一个接口,就一定有实现类,我们继续往下找。
public class SimpleConnectionHandle implements ConnectionHandle 仅有一个实现类,还是一个simple的,晕吧,spring文档竟然说是一个简单的实现。那复杂的实现在哪呢
?找了半天就找到这个一个简单的实现,有点郁闷。看看在说。
public class SimpleConnectionHandle implements ConnectionHandle { private final Connection connection; /** * Create a new SimpleConnectionHandle for the given Connection. * @param connection the JDBC Connection */ public SimpleConnectionHandle(Connection connection) { Assert.notNull(connection, "Connection must not be null"); this.connection = connection; } /** * Return the specified Connection as-is. */ public Connection getConnection() { return connection; } /** * This implementation is empty, as we're using a standard * Connection handle that does not have to be released. */ public void releaseConnection(Connection con) { } public String toString() { return "SimpleConnectionHandle: " + this.connection; } }
这里也没有我们想要的connection连接,只是一个保存connnection的地方,我们要的是DriverManager.getConnection()的地方,在哪呢?继续找吧!返回到抽象类
DataSourceUtils中,继续看。Connection con = dataSource.getConnection();看到了吧,其实spring也没有提供如何获取,是在sun的包中实现了DriverManager.getConnection
spring给我们提供了多种获取connnection的途径,还有
ConnectionHolder holderToUse = conHolder; if (holderToUse == null) { holderToUse = new ConnectionHolder(con); } public ConnectionHolder(Connection connection) { this.connectionHandle = new SimpleConnectionHandle(connection); }
在我们第一次连接后,以后就吧connnection保存了,下次用的时候就直接存spring中拿就OK了。返回到我们的jdbcTemplate继续看我们刚才的代码,注意如下代码。
Connection conToUse = con; if (this.nativeJdbcExtractor != null && this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativePreparedStatements()) { conToUse = this.nativeJdbcExtractor.getNativeConnection(con); } ps = psc.createPreparedStatement(conToUse);
psc.createPreparedStatement(conToUse);使用的是conToUse的Connection,而这个Connection是通过this.nativeJdbcExtractor.getNativeConnection获取的,我们看
看.nativeJdbcExtractor这个东东。
public interface NativeJdbcExtractor { boolean isNativeConnectionNecessaryForNativeStatements(); boolean isNativeConnectionNecessaryForNativePreparedStatements(); boolean isNativeConnectionNecessaryForNativeCallableStatements(); Connection getNativeConnection(Connection con) throws SQLException; Connection getNativeConnectionFromStatement(Statement stmt) throws SQLException; Statement getNativeStatement(Statement stmt) throws SQLException; PreparedStatement getNativePreparedStatement(PreparedStatement ps) throws SQLException; CallableStatement getNativeCallableStatement(CallableStatement cs) throws SQLException; ResultSet getNativeResultSet(ResultSet rs) throws SQLException; }
NativeJdbcExtractor 是一个接口。有getNativeConnection获取Connection的方法。我们继续看看NativeJdbcExtractor 接口的实现类。就恍然大悟了。
C3P0NativeJdbcExtractor, CommonsDbcpNativeJdbcExtractor, JBossNativeJdbcExtractor, NativeJdbcExtractorAdapter, SimpleNativeJdbcExtractor,
WebLogicNativeJdbcExtractor, WebSphereNativeJdbcExtractor, XAPoolNativeJdbcExtractor有这么多类实现了NativeJdbcExtractor 这个接口,名名字不难看出胡,有通过
jboss获取的,有本地jdbc(NativeJdbcExtractorAdapter)获取的,有weblogic获取的,有websphere获取的,基本上我们常见的服务器都支持。在这里。
我们看一个实现类NativeJdbcExtractorAdapter,
public Connection getNativeConnection(Connection con) throws SQLException { if (con == null) { return null; } Connection targetCon = DataSourceUtils.getTargetConnection(con); Connection nativeCon = doGetNativeConnection(targetCon); if (nativeCon == targetCon) { // We haven't received a different Connection, so we'll assume that there's // some additional proxying going on. Let's check whether we get something // different back from the DatabaseMetaData.getConnection() call. DatabaseMetaData metaData = targetCon.getMetaData(); // The following check is only really there for mock Connections // which might not carry a DatabaseMetaData instance. if (metaData != null) { Connection metaCon = metaData.getConnection(); if (metaCon != targetCon) { // We've received a different Connection there: // Let's retry the native extraction process with it. nativeCon = doGetNativeConnection(metaCon); } } } return nativeCon; }
通过这里DatabaseMetaData metaData = targetCon.getMetaData();获取connection,就看到这里,关于更详细的介绍且听下回分解。
2010年9月7日22:02:47
发表评论
-
Spring的PropertyPlaceholderConfigurer应用
2014-01-02 14:43 8351. PropertyPlaceholderConfigur ... -
spring 发送MAILJavaMailSenderImpl
2014-01-02 14:32 893spring对mail的支持是org.springframe ... -
spring REST中的内容协商ContentNegotiatingViewResolver
2014-01-02 14:23 1690一.REST内容协商介绍 RESTfu ... -
Spring MVC异常处理
2014-01-02 14:13 475Spring3.0中对异常的处理方法一共提供了两种:一种是使 ... -
Spring AOP 的@Aspect (转)
2013-12-19 10:04 5697转自:http://blog.csdn.net/tangh ... -
spring @component的作用
2013-12-19 09:54 9981、@controller 控制器(注入服务) 2、@se ... -
Spring MVC性能提升
2013-12-18 18:06 7132这几天在做公司内部SpringMVC的培训,培训之余看了看大 ... -
Spring MVC简介
2013-08-27 20:09 983Spring MVC简介 1.Sp ... -
SpringMVC中HandlerInterceptorAdapter的使用
2013-08-27 20:04 1994一般情况下,对来自浏览器的请求的拦截,是利用Filte ... -
Spring注解_详解
2013-08-27 20:01 930spring注解 @Autowired 注释 将 ... -
SpringMVC方法返回值的学习(注解版)
2013-08-22 09:38 1433/** * 项目名称:Spring3mvc de ... -
spring中的Log4jConfigListener作用
2013-08-21 10:40 1377使用spring中的Log4jConfigListener ... -
srping 异常
2010-11-15 14:32 1225Spring数据访问的根异常是DataAccessExcep ... -
使用spring的jdbcTemplate-----将JDBC操作建模为细粒度的对象
2010-09-11 16:32 15201,更新操作对象 首先考虑如何将User插入操作建模为一个操 ... -
使用spring的jdbcTemplate-----使用具名参数
2010-09-11 15:01 3604在JDBC用法中,SQL参数是用占位符?表示,并且受到位置的限 ... -
使用spring的jdbcTemplate-----SimpleJdbcTemplate的使用
2010-09-11 12:39 59091,用简单的JDBC模板更新数据库 传统的Jdb ... -
使用spring的jdbcTemplate-----简化JdbcTemplate模板的创建
2010-09-10 20:41 2288每次使用的时候,都要创建一个JdbcTemplate新实例,这 ... -
使用spring的jdbcTemplate-----用JDBC模板查询数据库
2010-09-10 00:26 11782JdbcTemplate类声明了几个重载的query()模板方 ... -
使用spring的jdbcTemplate-----用jdbc模板跟新数据库
2010-09-09 23:21 45011,用语句创建器更新数据库第一个回调接口是PreparedSt ... -
spring中jdbcTemplate归纳1
2010-09-07 19:41 2904jdbcTemplate整理 为了实现基本的CRUD操作,s ...
相关推荐
在这个实例工程中,我们将深入探讨Spring JdbcTemplate的基本使用、优势以及常见操作。 一、Spring JdbcTemplate简介 Spring JdbcTemplate的出现是为了弥补原生JDBC在编码上的繁琐,它通过模板方法模式,将SQL执行...
使用Spring的JdbcTemplate调用Oracle的存储过程
使用Spring的JdbcTemplate实现分页功能
2. **创建JdbcTemplate Bean**:接下来,我们需要创建一个JdbcTemplate的实例,并将其注入到我们的应用中。这通常在Spring配置文件中完成,通过`@Bean`注解创建一个JdbcTemplate实例,并将DataSource注入其中。 ```...
在Spring中,JdbcTemplate就是一个典型的模板类,它实现了数据库操作的基本流程,如创建Connection、PreparedStatement、处理结果集等。用户可以通过扩展或自定义模板方法来实现特定的数据库操作逻辑。 **3. 回调...
SpringJdbcTemplate是Spring框架中用于简化Java数据库访问的工具,它是Spring JDBC模块的核心。这个封装工具类的出现是为了提供一种更简洁、易于使用的接口来执行SQL操作,减轻开发者处理数据库连接、事务管理以及...
Struts2、Spring和Spring JDBC Template是Java Web开发中常用的三个框架,它们分别负责不同的职责。Struts2作为MVC(Model-View-Controller)框架,主要处理前端请求和业务逻辑;Spring则是一个全面的后端框架,提供...
### Spring中的JdbcTemplate #### JdbcTemplate概述 JdbcTemplate是Spring框架提供的一种用于简化JDBC编程的对象。通过封装原生的JDBC API,JdbcTemplate不仅提高了代码的可读性和可维护性,还帮助开发者避免了...
spring 中对大数据的处理,包括clob,blob的数据。比之jdbc下简便很多。
Struts、Spring 和 JDBCTemplate 是三个在 Java Web 开发中常用的框架和技术,它们结合使用可以构建出高效且灵活的企业级应用程序。在这个“Struts+Spring+JdbcTemplate Demo”中,我们将探讨这三个组件如何协同工作...
在Spring配置文件中,我们需要定义一个`JdbcTemplate` bean,如下所示: ```xml <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> ``` 其中,`dataSource`是指向数据库连接池的...
`Spring-JdbcTemplate` 是 Spring 框架中的一个核心模块,主要用于简化数据库操作,提供了强大的数据访问功能。它通过模板方法设计模式封装了 SQL 的执行,使得开发者无需直接与 JDBC API 打交道,从而降低了数据库...
Spring的JdbcTemplate是Spring框架中用于简化数据库操作的工具类,它是基于JDBC但又抽象出了一层,避免了直接与数据库驱动API交互,从而提高了代码的可读性和可维护性。本文将深入探讨Spring JdbcTemplate的常用方法...
配制Spring事务和JdbcTemplate使用 配制Spring事务和JdbcTemplate使用
Spring的JdbcTemplate是Spring框架中的一个核心组件,用于简化数据库操作。它提供了一种模板方法模式,抽象出常见的JDBC代码,使得开发者可以避免编写大量的重复性代码,从而更加专注于业务逻辑。本项目是对Spring ...
Spring的JdbcTemplate是Spring框架中的一个核心组件,用于简化数据库操作。它提供了一种模板方法模式,抽象出了一些常见的数据库访问任务,使得开发者无需关注低级的JDBC细节,如打开和关闭连接、处理结果集等,从而...
Spring 框架 JdbcTemplate 类中查询方法介绍 JdbcTemplate 是 Spring 框架中 org.springframework.jdbc.core 包提供的 JDBC 模板类,它是核心类,其他模板类都是基于它封装完成的。JdbcTemplate 类主要提供四类方法...
使用Spring的JdbcTemplate和BeanPropertyRowMapper完成的JDBC我的实例 博文链接:https://zmx.iteye.com/blog/373454
在提供的压缩包中,`securitydb_2.sql`很可能包含了预设的数据库结构和初始数据,这些数据可能是为了设置Spring Security的安全配置,如用户角色、权限等。这通常涉及创建用户表、角色表以及它们之间的关联。执行这...