xml配置:<?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><environments default="mysql_development"><!-- 连接环境信息 --><environment id="mysql_development"><!-- mysql使用什么事物管理方式 --><transactionManager type="JDBC"><property name="" value="" /></transactionManager><!-- mybatis使用连接池方式来获取连接对象 --><dataSource type="POOLED"><!-- 配置数据库连接信息 --><property name="driver" value="com.mysql.jdbc.Driver" /><property name="url" value="jdbc:mysql://your_mysql_url:3306/your_db_name?useUnicode=true&characterEncoding=utf-8" /><property name="username" value="root" /><property name="password" value="your_password" /><property name="poolMaximumIdleConnections" value="0"/><property name="poolMaximumActiveConnections" value="1000"/><property name="poolPingQuery" value="SELECT 1 FROM DUAL" /> <property name="poolPingEnabled" value="true" /></dataSource></environment></environments><mappers><package name="bean.map"/></mappers>
</configuration>
说明:上面都是很显然的,有几个地方注意
url中useUnicode=true&characterEncoding=utf-8 注意里面的转义字符&也就是&,否则会出错的
后面两个参数poolMaximumIdleConnections,和poolMaximumActiveConnections,需要并发控制的时候必须调整这俩参数
poolMaximumActiveConnections是最大的活动连接数,活动连接,就是正在与数据库交互的连接,默认是10
poolMaximumIdleConnections是空闲连接数,就是没有处理请求的连接,默认是5
具体可以参考mybatis的源码org.apache.ibatis.datasource.pooled.PooledDataSource.
注意:
PooledDataSource就是连接池的实现类。可以看到里面定义了几个参数,其中就包括
poolMaximumActiveConnections和poolMaximumIdleConnections,找到pushConnection方法,这个方法里会判断当前空闲连接数和poolMaximumIdleConnections的大小,如果小于poolMaximumIdleConnections,会new PooledConnection并放进队列中,这就导致一个问题,当所有的连接被占满后,Mybatis为了保持一定的空闲连接,会不断获取新的连接,然后这些新连接被占用后,就会再去new PooledConnection,如果一直这样new下去,结果就会超过了mysql设置的最大连接数max_connections,然后数据库返回错误:too many connections。
1. 先看是否有空闲(idle)状态下的PooledConnection对象,如果有,就直接返回一个可用的PooledConnection对象;否则进行第2步。
3. 查看活动状态的PooledConnection池activeConnections是否已满;如果没有满,则创建一个新的PooledConnection对象,然后放到activeConnections池中,然后返回此PooledConnection对象;否则进行第三步;
4. 看最先进入activeConnections池中的PooledConnection对象是否已经过期:如果已经过期,从activeConnections池中移除此对象,然后创建一个新的PooledConnection对象,添加到activeConnections中,然后将此对象返回;否则进行第4步;
5. 线程等待,循环2步