简介

基于上篇的示例感受,下面我们探索下MyBatis连接数据库的细节是如果实现的,在日常使用中是如何能和Druid数据库连接池等配合起来的

源码解析

基于上篇的示例代码:

public class MybatisTest {@Testpublic void test() {try(SqlSession session = buildSqlSessionFactory().openSession()) {PersonMapper personMapper = session.getMapper(PersonMapper.class);personMapper.createTable();personMapper.save(Person.builder().id(1L).name("1").build());Person person = personMapper.getPersonById(1);System.out.println(person);}}public static SqlSessionFactory buildSqlSessionFactory() {String JDBC_DRIVER = "org.h2.Driver";String DB_URL = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1";String USER = "sa";String PASS = "";DataSource dataSource = new PooledDataSource(JDBC_DRIVER, DB_URL, USER, PASS);Environment environment = new Environment("Development", new JdbcTransactionFactory(), dataSource);Configuration configuration = new Configuration(environment);configuration.addMapper(PersonMapper.class);SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();return builder.build(configuration);}
}

当前我们想找的是与数据库建立连接的部分

通过阅读书籍:《MyBatis3源码深度解析》,我们大概知道执行是在Executor中,我们跟踪相关的代码

经过不懈的努力跟踪,得到下面的关键代码:

找到了在执行语句中,在Executor中获取连接的关键代码

public class SimpleExecutor extends BaseExecutor {private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {// 获取数据库连接Connection connection = this.getConnection(statementLog);Statement stmt = handler.prepare(connection, this.transaction.getTimeout());handler.parameterize(stmt);return stmt;}
}

继续跟踪,来到我们示例中定义的事务管理器:JdbcTransactionFactory

public class JdbcTransaction implements Transaction {public Connection getConnection() throws SQLException {if (this.connection == null) {this.openConnection();}return this.connection;}protected void openConnection() throws SQLException {if (log.isDebugEnabled()) {log.debug("Opening JDBC Connection");}// 从DataSource中获取this.connection = this.dataSource.getConnection();if (this.level != null) {this.connection.setTransactionIsolation(this.level.getLevel());}this.setDesiredAutoCommit(this.autoCommit);}
}

上面可以看到是从DataSource中获取的,来到我们定义的:PooledDataSource

public class PooledDataSource implements DataSource {public Connection getConnection() throws SQLException {return this.popConnection(this.dataSource.getUsername(), this.dataSource.getPassword()).getProxyConnection();}private PooledConnection popConnection(String username, String password) throws SQLException {while(conn == null) {synchronized(this.state) {PoolState var10000;if (!this.state.idleConnections.isEmpty()) {......} else if (this.state.activeConnections.size() < this.poolMaximumActiveConnections) {// 获取数据库连接池连接conn = new PooledConnection(this.dataSource.getConnection(), this);if (log.isDebugEnabled()) {log.debug("Created connection " + conn.getRealHashCode() + ".");}} else {......}if (conn != null) {......}}}......}
}

我们继续跟下去:

public class UnpooledDataSource implements DataSource {public Connection getConnection() throws SQLException {return this.doGetConnection(this.username, this.password);}private Connection doGetConnection(String username, String password) throws SQLException {Properties props = new Properties();if (this.driverProperties != null) {props.putAll(this.driverProperties);}if (username != null) {props.setProperty("user", username);}if (password != null) {props.setProperty("password", password);}return this.doGetConnection(props);}private Connection doGetConnection(Properties properties) throws SQLException {this.initializeDriver();// 看到了熟悉的原生的获取数据库连接的方式Connection connection = DriverManager.getConnection(this.url, properties);this.configureConnection(connection);return connection;}
}

到这里我们找到了源码中如何获取数据库连接的关键代码

其实就是对于原生数据库操作的封装

调用栈回顾

我们回过头来看看整个过程中的类调用栈:

  • MybatisTest:我们的测试代码
  • MapperProxy:MyBatis的Mapper的代理类
  • MapperMethod:SQL执行相关
  • DefaultSqlSession
  • CachingExecutor
  • BaseExecutor
  • SimpleExecutor
  • JdbcTransation
  • PooledDataSource
  • UnpooledDataSource

可以看到数据库连接是从DataSource中获取的,而PooledDataSource是MyBatis自己的一个数据库连接池,其中使用非池化的UnpooledDataSource

在我们的日常开发中,经常使用MyBatis+Druid等数据库连接池一起使用,从这里就可以看到,我们简单替换一下MyBatis初始化时候的DataSource即可

总结

本篇中,我们跟踪了数据库如何进行连接获取,看到日常开发中MyBatis+Druid等数据库连接的配置使用的背后原理

MyBatis3源码解析(2)数据库连接相关推荐

  1. Mybatis3 源码解析系列

    简介 Mybatis作为一个优秀的Java持久化框架,在我们的日常工作中相信都会用到,本次源码解析系列,就开始探索下Mybatis 总结 在MyBatis的学习中,首先通读了<MyBatis3源 ...

  2. MyBatis3源码解析(3)查询语句执行

    简介 上篇探索了MyBatis中如何获取数据库连接,本篇继续探索,来看看MyBatis中如何执行一条查询语句 测试代码 本篇文中用于调试的测试代码请参考:MyBatis3源码解析(1)探索准备 完整的 ...

  3. MyBatis3源码解析(6)TypeHandler使用

    简介 在上几篇中,介绍了MyBatis3对参数和结果的解析转换,对于常规数据类型,默认的处理已经足够应付了,但日常开发中会有一些特殊的类型,就可以通过TypeHandler来进行处理 示例准备 本篇文 ...

  4. MyBatis3源码解析(5)查询结果处理

    简介 上篇中解析了MyBatis3中参数是如何传递处理的,本篇接着看看在获取到查询结果后,MyBatis3是如何将SQL查询结果与我们接口函数定义的返回结果对应的 源码 获取结果后处理的入口 在:My ...

  5. MyBatis3源码解析(1)探索准备

    简介 本篇文章将使用原生的JDBC方式操作数据库,然后在使用Mybatis提供的方式操作数据库,通过对比两部分的操作,大致得到Mybatis所做的主要工作,为接下来的源码解析做准备 示例代码 完整的工 ...

  6. MyBatis3源码解析(8)MyBatis与Spring的结合

    简介 在上几篇文章中,解析了MyBatis的核心原理部分,我们大致对其有了一定的了解,接下来我们看看在日常的开发中MyBatis是如何与Spring框架结合的 源码解析 在我们的日常开发中,使用Spr ...

  7. MyBatis3源码解析(7)TypeHandler注册与获取

    简介 在上篇文章中,我们介绍了TypeHandler的简单使用和解析了TypeHandler的处理核心,这篇文章中我们接着看到TypeHandler是如注册和获取使用的 源码解析 TypeHandle ...

  8. MyBatis3源码解析(4)参数解析

    简介 上篇文章中探索了查询语句的执行过程,下面我们接着来看看其中的查询参数的解析细节,是如何工作的 参数的解析 在日常的开发中,常见的参数有如下几种: 1.直接传入: func(Object para ...

  9. SpringBoot入门-源码解析(雷神)

    一.Spring Boot入门 视频学习资料(雷神): https://www.bilibili.com/video/BV19K4y1L7MT?p=1 github: https://github.c ...

最新文章

  1. python和c语言相通吗_python和C语言互相调用的几种方式
  2. 可汉学院python_可汗学院离线版本
  3. windows下RocketMQ下载、安装、部署、控制台
  4. 众所周知的局域网聊天软件
  5. 5个常用的htaccess技巧
  6. css3特效-传送带示例
  7. WCF中使用自定义behavior提示错误的解决方法
  8. 【报告分享】神策数据:2020银行数字营销现状洞察.pdf(附下载链接)
  9. 2020年最好用的手机是哪一款_2020年旗舰手机盘点,这七款优点明显,你最喜欢哪一款?...
  10. php做抖音在微信中播放,微信小程序实现抖音播放效果的实例代码
  11. jpa方言的yml格式
  12. 【车联网原型系统|三】树莓派设计+模拟基站程序
  13. 全流程东方时尚C1考试经历
  14. RFI射频干扰、谐波、基波
  15. 论文笔记(二十二):Soft Tracking Using Contacts for Cluttered Objects to Perform Blind Object Retrieval
  16. osgearth]样式表style中参数总结(OE官方文档翻译)
  17. EF core和数据库, Database First
  18. 用SQL语句查询一个特定老师学生中男生女生各多少人
  19. 3个5相乘列乘法算式_15个类型的速算巧算题目,打印出来给孩子练习一下
  20. openssl 漏洞 修复 教程

热门文章

  1. HDU——1272小希的迷宫(并查集+拓扑排序)
  2. 为bootstrap+angularJs打造的表格代码生成器
  3. ADO+MFC数据库编程常用语句
  4. 新年了,我也来kuso一下.......(yy帖~~)
  5. Invalid byte 2 of 2-byte UTF-8 sequence解决方案
  6. 【实践】SimSvr在微信推荐系统中的应用实践
  7. 【报告分享】中国数据智能应用趋势报告:解码数据中台最佳实践,企业数字化转型新引擎.pdf(附下载链接)...
  8. 梯度下降优化算法总结
  9. 宁波大学计算机网络实验五,宁波大学计算机网络实验四.doc
  10. java win 窗体开发简单订餐系统_Java实现简单订餐系统