最近事情实在是比较多,没有及时更新帖子,还望大家见谅啊。今天,一起讨论讨论Spring JDBC的实现吧。
关于Spring JDBC
还是从Spring JDBC说起吧,虽然现在应用很多都是直接使用Hibernate或者其他的ORM工具。但JDBC毕竟还是很基本的,其中的JdbcTemplate就是我们经常使用的,比如JDBCTemplate的execute方法,就是一个基本的方法,在这个方法的实现中,可以看到对数据库操作的基本过程。
-
-
publicvoidexecute(finalStringsql)throwsDataAccessException{
-
if(logger.isDebugEnabled()){
-
logger.debug("ExecutingSQLstatement["+sql+"]");
-
}
-
classExecuteStatementCallbackimplementsStatementCallback<Object>,SqlProvider{
-
publicObjectdoInStatement(Statementstmt)throwsSQLException{
-
stmt.execute(sql);
-
returnnull;
-
}
-
publicStringgetSql(){
-
returnsql;
-
}
-
}
-
execute(newExecuteStatementCallback());
-
}
-
-
public<T>Texecute(StatementCallback<T>action)throwsDataAccessException{
-
Assert.notNull(action,"Callbackobjectmustnotbenull");
-
-
Connectioncon=DataSourceUtils.getConnection(getDataSource());
-
Statementstmt=null;
-
try{
-
ConnectionconToUse=con;
-
if(this.nativeJdbcExtractor!=null&&
-
this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()){
-
conToUse=this.nativeJdbcExtractor.getNativeConnection(con);
-
}
-
-
stmt=conToUse.createStatement();
-
applyStatementSettings(stmt);
-
StatementstmtToUse=stmt;
-
if(this.nativeJdbcExtractor!=null){
-
stmtToUse=this.nativeJdbcExtractor.getNativeStatement(stmt);
-
}
-
-
Tresult=action.doInStatement(stmtToUse);
-
handleWarnings(stmt);
-
returnresult;
-
}
-
catch(SQLExceptionex){
-
-
-
-
-
JdbcUtils.closeStatement(stmt);
-
stmt=null;
-
DataSourceUtils.releaseConnection(con,getDataSource());
-
con=null;
-
throwgetExceptionTranslator().translate("StatementCallback",getSql(action),ex);
-
}
-
finally{
-
JdbcUtils.closeStatement(stmt);
-
-
DataSourceUtils.releaseConnection(con,getDataSource());
-
}
-
}
在使用数据库的时候,有一个很重要的地方就是对数据库连接的管理,在这里,是由DataSourceUtils来完成的。Spring通过这个辅助类来对数据的Connection进行管理。比如通过它来完成打开和关闭Connection等操作。DataSourceUtils对这些数据库Connection管理的实现, 如以下代码所示。
-
-
publicstaticConnectiongetConnection(DataSourcedataSource)throwsCannotGetJdbcConnectionException{
-
try{
-
returndoGetConnection(dataSource);
-
}
-
catch(SQLExceptionex){
-
thrownewCannotGetJdbcConnectionException("CouldnotgetJDBCConnection",ex);
-
}
-
}
-
publicstaticConnectiondoGetConnection(DataSourcedataSource)throwsSQLException{
-
Assert.notNull(dataSource,"NoDataSourcespecified");
-
-
-
ConnectionHolderconHolder=(ConnectionHolder)TransactionSynchronizationManager.getResource(dataSource);
-
if(conHolder!=null&&(conHolder.hasConnection()||conHolder.isSynchronizedWithTransaction())){
-
conHolder.requested();
-
if(!conHolder.hasConnection()){
-
logger.debug("FetchingresumedJDBCConnectionfromDataSource");
-
conHolder.setConnection(dataSource.getConnection());
-
}
-
returnconHolder.getConnection();
-
}
-
-
-
-
logger.debug("FetchingJDBCConnectionfromDataSource");
-
Connectioncon=dataSource.getConnection();
-
-
if(TransactionSynchronizationManager.isSynchronizationActive()){
-
logger.debug("RegisteringtransactionsynchronizationforJDBCConnection");
-
-
-
ConnectionHolderholderToUse=conHolder;
-
if(holderToUse==null){
-
holderToUse=newConnectionHolder(con);
-
}
-
else{
-
holderToUse.setConnection(con);
-
}
-
holderToUse.requested();
-
TransactionSynchronizationManager.registerSynchronization(
-
newConnectionSynchronization(holderToUse,dataSource));
-
holderToUse.setSynchronizedWithTransaction(true);
-
if(holderToUse!=conHolder){
-
TransactionSynchronizationManager.bindResource(dataSource,holderToUse);
-
}
-
}
-
returncon;
-
}
关于数据库操作类RDBMS
从JdbcTemplate中,我们看到,他提供了许多简单查询和更新的功能。但是,如果需要更高层次的抽象,以及更面向对象的方法来访问数据库,Spring为我们提供了org.springframework.jdbc.object包,里面包含了SqlQuery、SqlMappingQuery、SqlUpdate和StoredProcedure等类,这些类都是Spring JDBC应用程序可以使用的。但要注意,在使用这些类时需要为它们配置好JdbcTemplate作为其基本的操作实现,因为在它们的功能实现中,对数据库操作的那部分实现基本上还是依赖于JdbcTemplate来完成的。
比如,对MappingSqlQuery使用的过程,是非常简洁的;在设计好数据的映射代码之后,查询得到的记录已经按照前面的设计转换为对象List了,一条查询记录对应于一个数据对象,可以把数据库的数据记录直接映射成Java对象在程序中使用,同时又可避免使用第三方ORM工具的配置,对于简单的数据映射场合是非常方便的;在mapRow方法的实现中提供的数据转换规则,和我们使用Hibernate时,Hibernate的hbm文件起到的作用是非常类似的。这个MappingSqlQuery需要的对设置进行compile,这些compile是这样完成的,如以下代码所示:
-
protectedfinalvoidcompileInternal(){
-
-
this.preparedStatementFactory=newPreparedStatementCreatorFactory(getSql(),getDeclaredParameters());
-
this.preparedStatementFactory.setResultSetType(getResultSetType());
-
this.preparedStatementFactory.setUpdatableResults(isUpdatableResults());
-
this.preparedStatementFactory.setReturnGeneratedKeys(isReturnGeneratedKeys());
-
if(getGeneratedKeysColumnNames()!=null){
-
this.preparedStatementFactory.setGeneratedKeysColumnNames(getGeneratedKeysColumnNames());
-
}
-
his.preparedStatementFactory.setNativeJdbcExtractor(getJdbcTemplate().getNativeJdbcExtractor());
-
onCompileInternal();
-
}
在执行查询时,执行的实际上是SqlQuery的executeByNamedParam方法,这个方法需要完成的工作包括配置SQL语句,配置数据记录到数据对象的转换的RowMapper,然后使用JdbcTemplate来完成数据的查询,并启动数据记录到Java数据对象的转换,如以下代码所示:
-
publicList<T>executeByNamedParam(Map<String,?>paramMap,Mapcontext)throwsDataAccessException{
-
validateNamedParameters(paramMap);
-
-
ParsedSqlparsedSql=getParsedSql();
-
MapSqlParameterSourceparamSource=newMapSqlParameterSource(paramMap);
-
StringsqlToUse=NamedParameterUtils.substituteNamedParameters(parsedSql,paramSource);
-
-
Object[]params=NamedParameterUtils.buildValueArray(parsedSql,paramSource,getDeclaredParameters());
-
RowMapper<T>rowMapper=newRowMapper(params,context);
-
-
returngetJdbcTemplate().query(newPreparedStatementCreator(sqlToUse,params),rowMapper);
-
}
在Spring对JDBC的操作中,基本上是对JDBC/Hibernate基础上API的封装。这些封装可以直接使用,也可以在IoC容器中配置好了再使用,当结合IoC容器的基础上进行使用的时候,可以看到许多和事务管理相关的处理部分,都是非常值得学习的,在那里,可以看到对数据源的管理 - Hibernate中session的管理,与线程的结合等等。
分享到:
相关推荐
Spring技术内幕:深入解析Spring架构与设计原理 Spring技术内幕 Spring是一个基于Java的开源框架,旨在简化Java企业应用的开发。Spring的目标是提供一个简洁、灵活、可扩展的框架,以帮助开发者快速构建企业级...
《Spring技术内幕:深入解析Spring架构与设计原理(第2版)》从源代码的角度对Spring的内核和各个主要功能模块的架构、设计和实现原理进行了深入剖析。你不仅能从本书中参透Spring框架的出色架构和设计思想,还能从...
本书《Struts2技术内幕——深入解析Struts2架构设计与实现原理》结合提供的《struts2基础.chm》资料,为我们提供了深入理解Struts2内部机制的机会。 首先,Struts2的核心在于它的拦截器(Interceptor)机制。拦截器...
SPRING技术内幕:深入解析SPRING架构与设计原理
《Spring技术内幕:深入解析Spring架构与设计原理(第2版)》这本书主要聚焦于Spring框架的核心架构和技术细节,帮助读者全面理解Spring的工作机制、设计理念以及实现方式。下面将根据书名及其描述来展开相关知识点。 ...
Spring技术内幕:深入解析Spring架构与设计原理 Spring是Java企业应用开发的主要框架之一,其架构和设计原理对Java开发者具有重要影响。本文将深入解析Spring架构和设计原理,对Spring的核心概念、架构设计和关键...
Spring技术内幕 深入解析Spring架构与设计原理1(完整清晰版),一共两部分,这是第一部分 《Spring技术内幕:深入解析Spring架构与设计原理》是Spring领域的问鼎之作,由业界拥有10余年开发经验的资深Java专家亲自...
本书从源代码的角度对Spring的内核和各个主要功能模块的架构、设计和实现原理进行了深入剖析。你不仅能从本书中参透Spring框架的优秀架构和设计思想,还能从Spring优雅的实现源码中一窥Java语言的精髓。本书在开篇...
Spring技术内幕 深入解析Spring架构与设计原理3(完整清晰版),你懂的。下载后请您回复支持一下。
Spring技术内幕——深入解析Spring架构与设计 (揭秘系列丛书) - 计文柯.mobi
在深入解析Spring技术内幕第2版中,会详细探讨Spring框架的核心架构与设计原理,Spring作为一个轻量级的Java平台,提供了全面的编程和配置模型,是企业级Java应用程序开发中广泛使用的技术之一。 Spring的核心特性...
Spring技术内幕-深入解析Spring架构与设计原理.pdf
Spring技术内幕:深入解析Spring架构与设计原理(第2部分) 《Spring技术内幕:深入解析Spring架构与设计原理》是Spring领域的问鼎之作,由业界拥有10余年开发经验的资深Java专家亲自执笔!Java开发者社区和Spring...
SPRING技术内幕:深入解析SPRING架构与设计原理.pdf(带书签)
Spring技术内幕:深入解析Spring架构与设计原理(第2版)》是国内唯一一本系统分析Spring源代码的著作,也是Spring领域的问鼎之作,由业界拥有10余年开发经验的资深Java专家亲自执笔,Java开发者社区和Spring开发者...
这本书《Struts2技术内幕——深入解析Struts2架构设计与实现原理》深入探讨了Struts2的核心机制和设计理念,旨在帮助开发者更好地理解和运用这个框架。 首先,Struts2的出现是为了解决Struts1在MVC模式中的局限性,...