MyBatis POOLED连接池深入了解

本文详细介绍了MyBatis框架中连接池的配置方法,包括配置位置、type属性的三种取值及其含义,以及在SqlMapConfig.xml文件中dataSource标签的具体配置。深入解析了POOLED、UNPOOLED和JNDI三种连接池类型的特点,以及在Tomcat服务器下使用dbcp连接池的流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

往期内容,如下
一、MyBatis简介
二、MyBatis环境搭建
三、MyBatis入门案例
四、MyBatis自定义
五、MyBatis CRUD操作
六、Mybatis中参数和返回值的深入了解
七、MyBatis 配置文件标签

我们在实际开发中都会使用连接池,因为它可以减少我们获取连接所消耗的时间,在这里就不在赘述了。
mybatis连接池配置的位置:主配置文件SqlMapConfig.xml中的dataSource标签,type属性就是表示采用何种连接池方式

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//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);

整个流程图如下
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值