本文将从以下几个方面介绍Mybatis的数据源和连接池:
- MyBatis数据源DataSource分类
- 数据源DataSource的创建过程
- DataSource什么时候创建Connection对象
MyBatis数据源DataSource分类
MyBatis数据源实现是在以下四个包中:
MyBatis把数据源DataSource分为三种:
1、UNPOOLED:不使用连接池的数据源
2、POOLED: 使用连接池的数据源
3、JNDI:使用JNDI实现的数据源(JNDI是 Java 命名与目录接口(Java Naming and Directory Interface),在J2EE规范中是重要的规范之一。JNDI由j2ee容器提供,避免了程序与数据库之间的紧耦合,使应用更加易于配置、易于部署)
DataSource的创建过程
通过上一篇文章 应用框架之Mybatis初始化机制解析 可以知道,在Mybatis初始化过程中,会将DataSource实例放到Configuration对象内的Environment对象中。在解析xml配置时:
通过DataSourceFactory.getDataSource()方法来创建数据源DataSource。
DataSource什么时候创建Connection对象
当我们需要创建SqlSession对象并需要执行SQL语句时,这时候MyBatis才会去调用dataSource对象来创建java.sql.Connection对象。也就是说,java.sql.Connection对象的创建一直延迟到执行SQL语句的时候。例如:
String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();sqlSession.selectList("SELECT * FROM STUDENTS");
前4句都不会导致java.sql.Connection对象的创建,只有当第5句sqlSession.selectList("SELECT * FROM STUDENTS"),才会触发MyBatis在底层执行下面这个方法来创建java.sql.Connection对象:
//Transaction的实现类中创建,最终调用到DataSource的实现类protected void openConnection() throws SQLException { if (log.isDebugEnabled()) { log.debug("Opening JDBC Connection"); } connection = dataSource.getConnection(); if (level != null) { connection.setTransactionIsolation(level.getLevel()); } setDesiredAutoCommit(autoCommmit); }
UnpooledDataSource.getConnection()
使用UnpooledDataSource的getConnection(),每调用一次就会产生一个新的Connection实例对象。
public Connection getConnection() throws SQLException{ return doGetConnection(username, password);} private Connection doGetConnection(String username, String password) throws SQLException{ //封装username和password成properties Properties props = new Properties(); if (driverProperties != null) { props.putAll(driverProperties); } if (username != null) { props.setProperty("user