问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

谁有Spring技术内幕:深入解析Spring架构与设计原理(第2版)电子版?

发布网友 发布时间:2022-04-10 00:16

我来回答

3个回答

懂视网 时间:2022-04-10 04:38


在使用数据库的时候,有一个很重要的地方就是对数据库连接的管理,在这里,是由DataSourceUtils来完成的。Spring通过这个辅助类来对数据的Connection进行管理。比如通过它来完成打开和关闭Connection等操作。DataSourceUtils对这些数据库Connection管理的实现, 如以下代码所示。


//这是取得数据库连接的调用,实现是通过调用doGetConnection完成的,这里执行了异常的转换操作  
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");  
    //把对数据库的Connection放到事务管理中进行管理,这里使用TransactionSynchronizationManager中定义的ThreadLocal变量来和线程绑定数据库连接  
    //如果在TransactionSynchronizationManager中已经有与当前线程绑定数据库连接,那就直接取出来使用  
    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.  
    // 这里得到需要的数据库Connection,在Bean配置文件中定义好的,  
    // 同时最后把新打开的数据库Connection通过TransactionSynchronizationManager和当前线程绑定起来。  
    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;  
}  


关于数据库操作类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是这样完成的,如以下代码所示:


protected final void compileInternal() {  
    //这里是对参数的compile过程,所有的参数都在getDeclaredParameters里面,生成了一个PreparedStatementCreatorFactory  
    this.preparedStatementFactory = new PreparedStatementCreatorFactory(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数据对象的转换,如以下代码所示:


public List<T> executeByNamedParam(Map<String, ?> paramMap, Map context) throws DataAccessException {  
    validateNamedParameters(paramMap);  
    //得到需要执行的SQL语句  
    ParsedSql parsedSql = getParsedSql();  
    MapSqlParameterSource paramSource = new MapSqlParameterSource(paramMap);  
    String sqlToUse = NamedParameterUtils.substituteNamedParameters(parsedSql, paramSource);  
    //配置好SQL语句需要的Parameters及rowMapper,这个rowMapper完成数据记录到对象的转换  
    Object[] params = NamedParameterUtils.buildValueArray(parsedSql, paramSource, getDeclaredParameters());  
    RowMapper<T> rowMapper = newRowMapper(params, context);  
    //我们又看到了JdbcTemplate,这里使用JdbcTemplate来完成对数据库的查询操作,所以我们说JdbcTemplate是非常基本的操作类  
        return getJdbcTemplate().query(newPreparedStatementCreator(sqlToUse, params), rowMapper);  
}  


在Spring对JDBC的操作中,基本上是对JDBC/Hibernate基础上API的封装。这些封装可以直接使用,也可以在IoC容器中配置好了再使用,当结合IoC容器的基础上进行使用的时候,可以看到许多和事务管理相关的处理部分,都是非常值得学习的,在那里,可以看到对数据源的管理 - Hibernate中session的管理,与线程的结合等等。

更多内容请关注微信公众号:IT哈哈(it_haha)

技术分享


本文出自 “doujh” 博客,请务必保留此出处http://doujh.blog.51cto.com/10177066/1933904

深入解析Spring架构与设计原理-数据库的操作实现

标签:spring 数据库

热心网友 时间:2022-04-10 01:46

没听过搞不懂

热心网友 时间:2022-04-10 03:04

才出来多久啊 怎么可能那么快。做技术的,还是支持下正版吧。自己买吧
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
吃生大蒜好吗 吃生大蒜有什么好处呢 保字词语接龙两个字 建筑设计资质有哪些 iphone视频格式 男人说纠结是什么意思纠结是什么意思 古天乐的资料!!! 胆结石可以喝柠檬蜂蜜水吗 柠檬对结石有什么作用 胆结石可以吃柠檬吗 江西有哪些风景 织梦后台不能上传图片 MCreator配置时出错! 服务器里织梦后台上传不了图片? 期货加仓技巧请教 Cocos Creator怎么使用安卓手机相册中的图片,最好有示例源码 织梦5.7文章发布不能上传图片是怎么回事??我用另一个网站上传又正常。点击上传到服务器后就出现下图示 如何让C++中的代码规范一点 织梦后台无法上传图片是要怎么解决?上传的时候路径是错误的 股票盈利后如何加仓?有哪些操作方法? 求助大神!织梦后台无法上传和插入图片 弱弱的问一下Qt Creator多线程怎么调试 当期货交易有盈利后,怎么让盈利幅度扩大? 【Linux Live USB Creator】什么事live mode?和永久系统模式? 织梦系统后台上传不了图片 织梦后台发表文章添加图片失败,怎么解决? story creator mode《奥德赛》为什么开不开? 我去英国剑桥游学,有两个问题,希望大家帮助我! 1、手机卡买哪个?我想要经常给国内打电话,平常经常 DNF缔造者技能效果的npk文件是哪个? 织梦网站后台怎么上传不了图片了呢? 豌豆种可以放冰箱里冷冻吗? QT Creator 运行出错 Cocos Creator的WebView没有JsCallback接口吗 天使爱美丽的插曲是什么风格或者调式的歌? 美国初等教育是从儿童几岁开始的? 美国学前儿童食谱,美国3到6岁学前儿童早餐午餐和晚餐一般以哪些食物为主 到底《天使爱美丽》值不值得我们欣赏呢? 美国儿童几周岁上小学一年级? 分析一下《天使爱美丽》中比较典型的蒙太奇手法 美国学生上学的年龄 求电影《天使爱美丽》详尽赏析 美国小学生入学年龄?会不会因为差几个月就要等一年的情况发生? 电影音乐中有刻画人物形象的么? 美国对儿童玩具产品是如何分儿童年龄组的? 天使爱美丽 主题音乐叫什么名字? 一部电影的拍摄特点可以从哪几个点切入分析?电影《天使爱美丽》。希望大家给点关键词 请问美国儿童福利有什么制度?是怎样的? 要分析一部电影的音乐哪部电影比较适合 天使爱美丽视听分析 美国法律不允许把小于几岁的孩子独自留在家里 求影视鉴赏选修课作业。 1.罗拉快跑的结构特点 2.天使爱美丽的主题分析 要求:2选1 , 800~1000字、