tomcat連接數據庫,MyBatis3源碼解析(2)數據庫連接

 2023-10-12 阅读 31 评论 0

摘要:簡介 基于上篇的示例感受,下面我們探索下MyBatis連接數據庫的細節是如果實現的,在日常使用中是如何能和Druid數據庫連接池等配合起來的 源碼解析 基于上篇的示例代碼: public class MybatisTest {@Testpublic void test() {try(SqlSession session &

簡介

基于上篇的示例感受,下面我們探索下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等數據庫連接的配置使用的背后原理

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/135536.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息