Spring的JdbcTemplate使用,是否还需要手工或者aop指定关闭conn连接( 使用JdbcTemplate是否需要关闭连接)
2011-11-25 15:02
519 查看
JdbcTemplate类使用DataSource得到一个数据库连接。然后,他调用StatementCreator实例创建要执行的语句。下一步,他调用StatementCallBack完成。
一旦StatementCallBack返回结果,JdbcTemplate类完成所有必要清理工作关闭连接。如果StatementCreator或StatementCallBack抛出异常,JdbcTemplate类会捕获他们,并转换为Spring数据访问异常。
![](http://hi.csdn.net/attachment/201111/25/3042582_1322204819li3E.jpg)
看一个JdbcTemplate里面的比较核心的一个方法:
view
plaincopy
to clipboardprint?
//-------------------------------------------------------------------------
//
Methods dealing with prepared statements
//-------------------------------------------------------------------------
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 = 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);
handleWarnings(ps);
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());
}
}
显然,我们在finally里面看到了关闭调用,在看看这个关闭调用方法内部:
view
plaincopy
to clipboardprint?
/**
*
Close the given Connection, obtained from the given DataSource,
*
if it is not managed externally (that is, not bound to the thread).
*
@param con the Connection to close if necessary
*
(if this is <code>null</code>, the call will be ignored)
*
@param dataSource the DataSource that the Connection was obtained from
*
(may be <code>null</code>)
*
@see #getConnection
*/
public static void releaseConnection(Connection
con, DataSource dataSource) {
try {
doReleaseConnection(con,
dataSource);
}
catch (SQLException
ex) {
logger.debug("Could
not close JDBC Connection",
ex);
}
catch (Throwable
ex) {
logger.debug("Unexpected
exception on closing JDBC Connection",
ex);
}
}
/**
*
Actually close the given Connection, obtained from the given DataSource.
*
Same as {@link #releaseConnection}, but throwing the original SQLException.
*
<p>Directly accessed by {@link TransactionAwareDataSourceProxy}.
*
@param con the Connection to close if necessary
*
(if this is <code>null</code>, the call will be ignored)
*
@param dataSource the DataSource that the Connection was obtained from
*
(may be <code>null</code>)
*
@throws SQLException if thrown by JDBC methods
*
@see #doGetConnection
*/
public static void doReleaseConnection(Connection
con, DataSource dataSource) throws SQLException
{
if (con
== null)
{
return;
}
if (dataSource
!= null)
{
ConnectionHolder
conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
if (conHolder
!= null &&
connectionEquals(conHolder, con)) {
//
It's the transactional Connection: Don't close it.
conHolder.released();
return;
}
}
//
Leave the Connection open only if the DataSource is our
//
special SmartDataSoruce and it wants the Connection left open.
if (!(dataSource instanceof SmartDataSource)
|| ((SmartDataSource) dataSource).shouldClose(con)) {
logger.debug("Returning
JDBC Connection to DataSource");
con.close();
}
}
主要下面这几行代码:
view
plaincopy
to clipboardprint?
//
Leave the Connection open only if the DataSource is our
//
special SmartDataSoruce and it wants the Connection left open.
if (!(dataSource instanceof SmartDataSource)
|| ((SmartDataSource) dataSource).shouldClose(con)) {
logger.debug("Returning
JDBC Connection to DataSource");
con.close();
}
哦,可以看到大部分情况下是自动关闭,除非你使用的SmartDataSource,且SmartDataSource指定了允许关闭。
有些时候,你引入了JdbcTemplate或者DaoSupport,但是有时还需要自己额外的拿到conn进行操作,如下:
jdbcTemplate.getDataSource().getConnection()
那么,你应该就需要关闭连接了
一旦StatementCallBack返回结果,JdbcTemplate类完成所有必要清理工作关闭连接。如果StatementCreator或StatementCallBack抛出异常,JdbcTemplate类会捕获他们,并转换为Spring数据访问异常。
![](http://hi.csdn.net/attachment/201111/25/3042582_1322204819li3E.jpg)
看一个JdbcTemplate里面的比较核心的一个方法:
view
plaincopy
to clipboardprint?
//-------------------------------------------------------------------------
//
Methods dealing with prepared statements
//-------------------------------------------------------------------------
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 = 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);
handleWarnings(ps);
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());
}
}
显然,我们在finally里面看到了关闭调用,在看看这个关闭调用方法内部:
view
plaincopy
to clipboardprint?
/**
*
Close the given Connection, obtained from the given DataSource,
*
if it is not managed externally (that is, not bound to the thread).
*
@param con the Connection to close if necessary
*
(if this is <code>null</code>, the call will be ignored)
*
@param dataSource the DataSource that the Connection was obtained from
*
(may be <code>null</code>)
*
@see #getConnection
*/
public static void releaseConnection(Connection
con, DataSource dataSource) {
try {
doReleaseConnection(con,
dataSource);
}
catch (SQLException
ex) {
logger.debug("Could
not close JDBC Connection",
ex);
}
catch (Throwable
ex) {
logger.debug("Unexpected
exception on closing JDBC Connection",
ex);
}
}
/**
*
Actually close the given Connection, obtained from the given DataSource.
*
Same as {@link #releaseConnection}, but throwing the original SQLException.
*
<p>Directly accessed by {@link TransactionAwareDataSourceProxy}.
*
@param con the Connection to close if necessary
*
(if this is <code>null</code>, the call will be ignored)
*
@param dataSource the DataSource that the Connection was obtained from
*
(may be <code>null</code>)
*
@throws SQLException if thrown by JDBC methods
*
@see #doGetConnection
*/
public static void doReleaseConnection(Connection
con, DataSource dataSource) throws SQLException
{
if (con
== null)
{
return;
}
if (dataSource
!= null)
{
ConnectionHolder
conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
if (conHolder
!= null &&
connectionEquals(conHolder, con)) {
//
It's the transactional Connection: Don't close it.
conHolder.released();
return;
}
}
//
Leave the Connection open only if the DataSource is our
//
special SmartDataSoruce and it wants the Connection left open.
if (!(dataSource instanceof SmartDataSource)
|| ((SmartDataSource) dataSource).shouldClose(con)) {
logger.debug("Returning
JDBC Connection to DataSource");
con.close();
}
}
主要下面这几行代码:
view
plaincopy
to clipboardprint?
//
Leave the Connection open only if the DataSource is our
//
special SmartDataSoruce and it wants the Connection left open.
if (!(dataSource instanceof SmartDataSource)
|| ((SmartDataSource) dataSource).shouldClose(con)) {
logger.debug("Returning
JDBC Connection to DataSource");
con.close();
}
哦,可以看到大部分情况下是自动关闭,除非你使用的SmartDataSource,且SmartDataSource指定了允许关闭。
有些时候,你引入了JdbcTemplate或者DaoSupport,但是有时还需要自己额外的拿到conn进行操作,如下:
jdbcTemplate.getDataSource().getConnection()
那么,你应该就需要关闭连接了
相关文章推荐
- 关于python语言使用redis时,连接是否需要关闭的问题
- 8 -- 深入使用Spring -- 4...1 为什么需要AOP
- nginx 下使用laravel 需要配置.conf文件,否则无法访问指定路由(不知道说路由是否合适,刚学的小白,tp中对应的应该方法)
- spring使用aop时需要设置proxy-target-class="true" 否则无法依赖注入
- Spring jdbcTemplate操作完数据库后是否需要手动关闭数据库连接 ,如何关闭
- spring使用aop时需要设置proxy-target-class="true" 否则无法依赖注入
- 关于spring3使用AOP编程时需要引入哪些jar包的问题
- c# 使用UdpClient并指定了本地端口,用完之后需要关闭
- Spring Boot 与 Kotlin 使用JdbcTemplate连接MySQL
- Spring Boot 与 Kotlin 使用JdbcTemplate连接MySQL数据库的方法
- redis连接是否需要关闭
- "无法连接到打印机。 您或者输入打印机名不正确, 或指定打印机是否不再连接到服务器。"错误提示的解决
- 使用Spring Aop验证方法参数是否合法
- 当获取相似数据时,使用不同方法调用不同sp,但是使用同一个方法去用IIDataReader或者SqlDataReader读取数据时需要判断column name是否存在。
- Spring中使用aop操作需要用到的aspectjweaver-1.8.7.jar包
- 使用spring声明式事务,spring使用AOP来支持声明式事务,会根据事务属性,自动在方法调用之前决定是否开启一个事务,并在方法执行之后决定事务提交或回滚事务。
- 使用Spring3的AOP功能需要的jar包
- 使用SpringAop 验证方法参数是否合法
- 使用SpringAop 验证方法参数是否合法
- 使用SpringAop 验证方法参数是否合法