往期内容,如下
一、MyBatis简介
二、MyBatis环境搭建
三、MyBatis入门案例
四、MyBatis自定义
五、MyBatis CRUD操作
六、Mybatis中参数和返回值的深入了解
七、MyBatis 配置文件标签
我们在实际开发中都会使用连接池,因为它可以减少我们获取连接所消耗的时间,在这里就不在赘述了。
mybatis连接池配置的位置:主配置文件SqlMapConfig.xml
中的dataSource
标签,type
属性就是表示采用何种连接池方式
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 配置properties--><properties resource="jdbcConfig.properties"></properties><!--使用typeAliases配置别名,它只能配置domain中类的别名 --><typeAliases><package name="com.itheima.domain"></package></typeAliases><!--配置环境--><environments default="mysql"><!-- 配置mysql的环境--><environment id="mysql"><!-- 配置事务 --><transactionManager type="JDBC"></transactionManager><!--配置连接池--><dataSource type="POOLED"><!-- ============================================ --><property name="driver" value="${jdbc.driver}"></property><property name="url" value="${jdbc.url}"></property><property name="username" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property></dataSource></environment></environments><!-- 配置映射文件的位置 --><mappers><package name="com.itheima.dao"></package></mappers>
</configuration>
type属性的取值:
- POOLED:采用传统的
javax.sql.DataSource
规范中的连接池,mybatis中有针对规范的实现 - UNPOOLED:采用传统的获取连接的方式,虽然也实现
Javax.sql.DataSource
接口,但是并没有使用池的思想 - JNDI:采用服务器提供的
JNDI
技术实现,来获取DataSource
对象,不同的服务器所能拿到DataSource
是不一样(如果不是web
或者maven
的war工程,是不能使用的)
我们课程中使用的是tomcat服务器,采用连接池就是dbcp
连接池
IDEA 快捷键Ctrl+N,打开PooledDataSource.java
//找到getConnection方法public Connection getConnection() throws SQLException {return this.popConnection(this.dataSource.getUsername(), this.dataSource.getPassword()).getProxyConnection();}
//=========================================================================================
//Ctrl+左键进入popConnection方法,截取部分代码while(conn == null) {synchronized(this.state) {//他必须得是线程安全的,两个线程不能拿到同一个连接PoolState var10000;if (!this.state.idleConnections.isEmpty()) {//如果有一个空闲的连接,就接着往下走conn = (PooledConnection)this.state.idleConnections.remove(0);if (log.isDebugEnabled()) {log.debug("Checked out connection " + conn.getRealHashCode() + " from pool.");}//=========================================================================================//跟进去idleConnection方法//可以发现idleConnection是一个集合
protected final List<PooledConnection> idleConnections = new ArrayList();//=========================================================================================回到popConnection方法private PooledConnection popConnection(String username, String password) throws SQLException {boolean countedWait = false;PooledConnection conn = null;long t = System.currentTimeMillis();int localBadConnectionCount = 0;while(conn == null) {synchronized(this.state) {PoolState var10000;if (!this.state.idleConnections.isEmpty()) {//判断空闲连接是否还有conn = (PooledConnection)this.state.idleConnections.remove(0);//如果空闲连接还有,取一个出来用if (log.isDebugEnabled()) {log.debug("Checked out connection " + conn.getRealHashCode() + " from pool.");}} else if (this.state.activeConnections.size() < this.poolMaximumActiveConnections) {//如果空闲连接没有了,那么就会判断活动的连接池最大数量是否小于设定的最大值conn = new PooledConnection(this.dataSource.getConnection(), this);//如果小于,new一个空闲的connection,从dataSource哪一个连接出来if (log.isDebugEnabled()) {log.debug("Created connection " + conn.getRealHashCode() + ".");}} else {//没有空闲连接,活动连接池又没有空闲的地方PooledConnection oldestActiveConnection = (PooledConnection)this.state.activeConnections.get(0);//获取活动连接池中最老的一个连接出来long longestCheckoutTime = oldestActiveConnection.getCheckoutTime();if (longestCheckoutTime > (long)this.poolMaximumCheckoutTime) {++this.state.claimedOverdueConnectionCount;var10000 = this.state;var10000.accumulatedCheckoutTimeOfOverdueConnections += longestCheckoutTime;var10000 = this.state;var10000.accumulatedCheckoutTime += longestCheckoutTime;this.state.activeConnections.remove(oldestActiveConnection);
整个流程图如下