Mybatis 核心配置文件 - 数据源 JNDI 集成第三方数据库连接池

建议阅读:

在 Tomcat 中使用 JNDI 可以对数据源进行配置,配置如下:

1
2
3
4
5
6
7
8
9
10
11
<Resource 
name="jdbc/mysql"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/task"
username="root"
password="123456"
maxActive="10"
maxIdle="5"
maxWait="-1"/>

上述配置中,只是指定了数据源接口 javax.sql.DataSource,并没有指定具体实现,但该配置依然可以生效。因此怀疑 Tomcat 是否有默认的数据库连接池实现。

查阅了一些资料发现,Tomcat 确实有自己默认的数据库连接池。

以前默认用的是 DBCP,现在默认用似乎是 DBCP2,另外还有一个 Tomcat 也自己实现了一个 Tomcat JDBC Pool,不过似乎该连接池并不是默认使用的,需要通过 factory 属性明确指定。Tomcat JDBC Pool 是基于 DBCP 实现的,不过不确定是 DBCP1 还是 DBCP2,但与 DBCP 似乎是完全兼容的。

打开 Tomcat 的安装目录下的 lib 目录,会发现其中存在 tomcat-dbcp.jar,打开查看里面有包名 org.apache.tomcat.dbcp.dbcp2org.apache.tomcat.dbcp.pool2,这个 jar 包应该就提供了默认的 DBCP2 的数据库连接池实现。

另外还有一个 tomcat-jdbc.jar,该包应该就是 Tomcat 自己基于 DBCP 实现的 Tomcat JDBC Pool,要使用该连接池,需要额外指定 factory=org.apache.tomcat.jdbc.pool.DataSourceFactory


如果希望使用 Druid 数据库连接池,那么 Tomcat 中 JNDI 的数据源配置应改为如下:

1
2
3
4
5
6
7
8
9
10
11
12
<Resource 
name="jdbc/mysql"
factory="com.alibaba.druid.pool.DruidDataSourceFactory"
auth="Container"
type="javax.sql.DataSource"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/task"
username="root"
password="123456"
maxActive="10"
maxIdle="5"
maxWait="-1"/>

关键在于多了一个 factory="com.alibaba.druid.pool.DruidDataSourceFactory" 的配置。

在 Tomcat 中通过 JNDI 配置好 Druid 数据源以后,在 Java 代码中可以这样进行查找:

1
2
3
4
5
6
7
8
// 一次查到
Context initContext = new InitialContext();
DataSource ds = (DataSource) initContext.lookup("java:comp/env/jdbc/mysql");

// 分两次查找
Context initContext = new InitialContext();
Context envContext = (Context) initContext.lookup("java:/comp/env");
DataSource ds = (DataSource) envContext.lookup("jdbc/mysql");

回到 Mybatis 核心配置文件中,希望 Mybatis 集成 Druid 数据库连接池,相应的 dataSource 标签的配置如下:

没有提供 initial_context 时,是直接在 InitialContext 中查找,因此需要提供完整路径 java:comp/env/jdbc/mysql

1
2
3
<dataSource type="JNDI">
<property name="data_source" value="java:comp/env/jdbc/mysql"/>
</dataSource>

提供 initial_context 时,是先在 InitialContext 中查找该属性值 java:/comp/env 对应的 Context,然后再基于该 Context 再查找其下的 jdbc/mysql 对应的数据源。

1
2
3
4
<dataSource type="JNDI">
<property name="initial_context" value="java:/comp/env"/>
<property name="data_source" value="jdbc/mysql"/>
</dataSource>