位置:首页 > Java > Mybatis数据库连接池配置方法与区别详解

Mybatis数据库连接池配置方法与区别详解

时间:2026-08-18  |  作者:半糖攻略君  |  阅读:0

一、纯 MyBatis 项目(无 Spring)

纯 MyBatis 项目要接入第三方连接池,其实有两条路可以走。一条是自己动手写工厂类,另一条是让 Tomcat 这样的容器帮你管。下面分别展开。

Mybatis不同的数据库连接池的配置

方式一:自定义 DataSourceFactory

原理:MyBatis 内置只支持 POOLED/UNPOOLED/JNDI 三种数据源,并没有直接集成 HikariCP 或 Druid。想用第三方连接池,就得自己写一个工厂类,让 MyBatis 能通过这个工厂创建出你想要的连接池。

1. 添加 Ma ven 依赖



    org.mybatis
    mybatis
    3.5.13




    mysql
    mysql-connector-ja va
    8.0.33





    com.zaxxer
    HikariCP
    5.0.1




    com.alibaba
    druid
    1.2.20

2. 编写自定义工厂类

HikariCP 版本:

package com.example.factory;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.ibatis.datasource.DataSourceFactory;

import ja vax.sql.DataSource;
import ja va.util.Properties;

public class HikariDataSourceFactory implements DataSourceFactory {
    
    private Properties props;
    
    // MyBatis 自动调用,传入 xml 里的 
    @Override
    public void setProperties(Properties props) {
        this.props = props;
    }
    
    // MyBatis 调用此方法获取 DataSource
    @Override
    public DataSource getDataSource() {
        // 用 Properties 创建 HikariCP 配置
        HikariConfig config = new HikariConfig(props);

        // 返回连接池实例
        return new HikariDataSource(config);
    }
}

Druid 版本:

package com.example.factory;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.apache.ibatis.datasource.DataSourceFactory;

import ja vax.sql.DataSource;
import ja va.util.Properties;

public class DruidDataSourceFactory implements DataSourceFactory {
    
    private Properties props;
    
    @Override
    public void setProperties(Properties props) {
        this.props = props;
    }
    
    @Override
    public DataSource getDataSource() {
        try {
            return DruidDataSourceFactory.createDataSource(props);
        } catch (Exception e) {
            throw new RuntimeException("创建 DruidDataSource 失败", e);
        }
    }
}

3. MyBatis 配置文件mybatis-config.xml





    
    
        
            
            
            
            
                
                
                
                
                
                
                
                
                
                
                
                
            
            
        
    
    
    
    
        
    
    

4. Ja va 代码中使用

public class Main {
    public static void main(String[] args) throws IOException {
        // 读取配置文件
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        
        // 构建 SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        
        // 获取 SqlSession
        try (SqlSession session = sqlSessionFactory.openSession()) {
            UserMapper mapper = session.getMapper(UserMapper.class);
            User user = mapper.selectById(1);
            System.out.println(user);
        }
    }
}

注意: 这种方式完全不需要 Tomcat 容器。整个过程就是一个普通的 Ja va 程序,用 main() 方法就能直接跑起来。

方式二:JNDI 方式

原理:连接池不由 MyBatis 创建,而是由 Tomcat 等 Web 容器提前配置好,MyBatis 通过 JNDI 名称去“查找”获取。

适用场景

  • 多应用共享同一个连接池
  • 数据库密码不写在应用代码里
  • 企业级 war 包部署到外部 Tomcat

JNDI 方式的本质

┌─────────────────────────────────────┐
│           Tomcat 服务器              │
│  ┌─────────────────────────────┐   │
│  │  context.xml 里配置:         │   │
│  │  - 数据库密码                 │   │
│  │  - 连接池参数                 │   │
│  │  - 连接池实现(Druid等)      │   │
│  │                             │   │
│  │  对外暴露:name="jdbc/MyDB"  │   │
│  └─────────────────────────────┘   │
└─────────────────────────────────────┘
                    ↑
              JNDI 查找(按名字)
                    ↓
┌─────────────────────────────────────┐
│         MyBatis 应用(war包)        │
│                                     │
│  mybatis-config.xml 里只有:          │
│              │
│         │
│                        │
│                                     │
│   没有数据库密码                    │
│   没有连接池参数                    │
│   不知道用的是 Druid 还是 Hikari   │
└─────────────────────────────────────┘

为什么企业级部署常用 JNDI?

场景:一个 Tomcat 跑 3 个应用

不用 JNDI(每个应用自己配)

应用A:配了 HikariCP,max=10,密码=123456
应用B:配了 Druid,max=10,密码=123456
应用C:配了 c3p0,max=10,密码=123456
→ 总共 30 个连接,密码改了要改 3 个地方

用 JNDI(统一配置)

Tomcat 配 1 个连接池:max=20,密码=123456
应用A、B、C 都引用 jdbc/MyDB
→ 总共 20 个连接,密码改了只改 1 个地方

一句话总结

JNDI 方式 = 把数据库配置“外包”给 Tomcat

MyBatis 只负责说“给我 jdbc/MyDB”,具体怎么连、用什么连、密码是什么,全由 Tomcat 管。

这和 Spring 无关,是 纯 MyBatis 项目在企业部署时的标准做法

1. 在 Tomcat 中配置连接池

找到 Tomcat/conf/context.xml,添加:


    
    
        factory="com.alibaba.druid.pool.DruidDataSourceFactory"
        
        driverClassName="com.mysql.cj.jdbc.Driver"
        url="jdbc:mysql://localhost:3306/mydb"
        username="root"
        password="123456"
        
        maxActive="20"
        maxIdle="10"
        maxWait="10000"
    />

不同连接池只需改 factory 和参数名:

连接池factory 值参数特点
Druidcom.alibaba.druid.pool.DruidDataSourceFactorymaxActive, maxWait
DBCPorg.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactorymaxTotal, maxWaitMillis
HikariCPcom.zaxxer.hikari.HikariJNDIFactorymaximumPoolSize, connectionTimeout

2. MyBatis 配置文件mybatis-config.xml





    
    
        
            
            
            
            
                
                
            
            
        
    
    
    
        
    
    

关键点:

  • type="JNDI":告诉 MyBatis,“我不自己创建连接池,去服务器上找”
  • ja va:comp/env/:这是 JNDI 的标准前缀(就像打电话要加区号)
  • jdbc/MyDB:就是 Tomcat 里配置的那个名字

3. 项目打包为 war 部署到 Tomcat


war


    
    
        ja vax.servlet
        ja vax.servlet-api
        4.0.1
        provided
    
    
    
    
        org.mybatis
        mybatis
        3.5.13
    

完整流程图

┌─────────────────┐
│    Tomcat 服务器  │
│  ┌───────────┐  │
│  │  Druid连接池 │  ← 统一管理:20个连接
│  │  name=    │  │
│  │ jdbc/MyDB │  │
│  └─────┬─────┘  │
└────────┼────────┘
         │
    JNDI 查找(按名字要)
         │
┌────────┼────────┐
│   MyBatis 应用   │
│  "给我 jdbc/MyDB" │
│  (不知道真实密码) │
└─────────────────┘

注意:如果换用不同的连接池(比如 c3p0、DBCP),只需修改 Tomcat 配置文件中的 factory 属性值,其他部分保持不变。

两种“纯 MyBatis”方式的对比

自定义 DataSourceFactoryJNDI 方式
连接池在哪创建MyBatis 应用内部Tomcat 服务器里
谁管理连接池MyBatis 自己Tomcat 容器
密码存在哪mybatis-config.xml 里Tomcat 的 context.xml 里
应用是否知道密码 知道 不知道(只知道名字)
多个应用共享 每个应用独立 共享同一个
适用场景单机部署多应用共享、企业级部署

二、MyBatis + Spring 项目(推荐)

Spring 管理连接池,MyBatis 直接引用,这是现代项目中最常用、最简洁的方式。核心思路很简单:Spring 创建连接池 Bean → MyBatis 引用这个 Bean

1. 添加 Ma ven 依赖


    
    
        org.springframework
        spring-context
        5.3.29
    
    
    
        org.springframework
        spring-jdbc
        5.3.29
    
    
    
        org.mybatis
        mybatis
        3.5.13
    
    
    
        org.mybatis
        mybatis-spring
        2.1.1
    
    
    
        mysql
        mysql-connector-ja va
        8.0.33
    
    
    
    
        com.zaxxer
        HikariCP
        5.0.1
    
    
    
        com.alibaba
        druid
        1.2.20
    
    
    

2. Spring 配置文件applicationContext.xml

方案 A:HikariCP




    
    
        
        
        
        
        
        
        
               
                  
          
             
            
            
    

    
    
        
        
        
        
        
        
        
        
        
        
        
        
    

    
    
        
        
    

    
    
        
    

    
    

方案 B:Druid(带监控)



    
    
        
        
        
        
        
        
                   
                      
                  
                  
        
         
        
        
        
        
        
        
    
    
    
        
        
    
    
    
        
    
    
    
        
    
    

方案 C:DBCP(Tomcat 自带,简单)

    
    
        
        
        
        
                    
                     
                      
            
    

3. 参数名速查表

功能HikariCPDruidDBCP
驱动类driverClassNamedriverClassNamedriverClassName
数据库URLjdbcUrlurlurl
用户名usernameusernameusername
密码passwordpasswordpassword
最大连接数maximumPoolSizemaxActivemaxTotal
最小空闲连接minimumIdleminIdleminIdle
初始连接数initialSizeinitialSize
连接超时/等待connectionTimeoutmaxWaitmaxWaitMillis
空闲超时idleTimeoutminEvictableIdleTimeMillis
最大生命周期maxLifetime
连接检测SQLvalidationQueryvalidationQuery

4. Ja va 代码中使用

// 实体类
package com.example.entity;

public class User {
    private Integer id;
    private String name;
    // getter/setter...
}

// Mapper 接口
package com.example.mapper;

import com.example.entity.User;
import org.apache.ibatis.annotations.Select;

public interface UserMapper {
    
    @Select("SELECT * FROM user WHERE id = #{id}")
    User selectById(Integer id);
}
// Service 层
package com.example.service;

import com.example.entity.User;
import com.example.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    public User getUserById(Integer id) {
        return userMapper.selectById(id);
    }
    
    @Transactional
    public void updateUser(User user) {
        // 事务自动管理
        userMapper.update(user);
    }
}
// 启动类
package com.example;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        // 加载 Spring 配置
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        
        // 获取 Service
        UserService userService = context.getBean(UserService.class);
        
        // 使用
        User user = userService.getUserById(1);
        System.out.println(user);
    }
}

换连接池 = 换 class + 调参数名,MyBatis 端完全无感知。

三、三种方式对比总结

对比项纯 MyBatis 自定义 Factory纯 MyBatis JNDIMyBatis + Spring
复杂度中(需写工厂类)高(需配 Tomcat)低(Spring 管理)
灵活性一般低(依赖容器)
连接池管理应用内Tomcat 容器Spring 容器
密码位置mybatis-config.xmlcontext.xml(安全)applicationContext.xml
多应用共享(每个 Spring 容器独立)
事务管理手动手动注解自动
推荐度
适用场景简单纯 MyBatis 项目企业 war 部署现代项目首选

四、快速选择指南

┌─────────────────────────────────────────┐
│  项目类型判断                            │
└─────────────────────────────────────────┘
           │
           ▼
┌─────────────────────────┐
│  有 Spring 吗?          │
└─────────────────────────┘
     │            │
    是           否
     │            │
     ▼            ▼
┌──────────┐  ┌─────────────────────────┐
│ 直接用    │  │ 需要 war 部署到外部     │
│ Spring   │  │ Tomcat 且多应用共享?    │
│ 方式     │  └─────────────────────────┘
└──────────┘        │            │
                 是           否
                  │            │
                  ▼            ▼
            ┌──────────┐  ┌─────────────────┐
            │ JNDI 方式 │  │ 自定义 DataSource│
            │          │  │ Factory 方式    │
            └──────────┘  └─────────────────┘

五、生产环境推荐

场景推荐方案
新项目/微服务Spring + MyBatis + HikariCP
需要 SQL 监控Spring + MyBatis + Druid
传统 war 部署JNDI + Tomcat 统一管理
老项目维护保持原有方案,逐步迁移到 Spring

6-1、Spring boot项目换不同的web容器

一、Spring Boot 怎么换 Web 容器

Spring Boot 默认内嵌 Tomcat,但换起来非常简单,就是排除一个依赖、引入另一个依赖

1. 换成 Jetty



    org.springframework.boot
    spring-boot-starter-web
    
    
        
            org.springframework.boot
            spring-boot-starter-tomcat
        
    



    org.springframework.boot
    spring-boot-starter-jetty

2. 换成 Undertow(性能极高)



    org.springframework.boot
    spring-boot-starter-web
    
        
            org.springframework.boot
            spring-boot-starter-tomcat
        
    



    org.springframework.boot
    spring-boot-starter-undertow

就改这几行 Ma ven 依赖,代码完全不用动,Spring Boot 自动适配。

二、为什么要换?—— 三种容器对比

特性Tomcat(默认)JettyUndertow
出身Apache 基金会Eclipse 基金会JBoss(红帽)
体积中等最轻量轻量
性能中等中等最高(高并发场景优势明显)
内存占用中等较低最低
启动速度中等最快
并发模型线程池(阻塞IO)线程池非阻塞IO(XNIO)
热部署支持支持最好支持
嵌入式友好最好
企业级生态最成熟较少较少
典型场景通用、企业级微服务、嵌入式设备高并发、云原生、低内存

三、什么场景换什么容器?

场景 1:用 Tomcat(默认,不动就行)

企业级应用,求稳

需要丰富的监控和管理工具

团队熟悉,文档多

兼容性好,第三方插件多

场景 2:换成 Jetty

微服务架构,追求启动快

嵌入式设备 / 物联网(内存受限)

需要频繁热部署开发

和 Eclipse 生态集成

场景 3:换成 Undertow(趋势)

高并发、高吞吐(如网关、API服务)

云原生 / K8s 部署(内存省=省钱)

长连接、WebSocket 场景

追求极致性能

四、回到 JNDI —— 换容器后配置会变吗?

会变一点,但核心逻辑不变。

容器JNDI 配置位置说明
Tomcatconf/context.xml最常用,资料最多
JettyWEB-INF/jetty-env.xml语法类似
Undertow通常用 Spring 配置代替内嵌模式很少用 JNDI

注意:Spring Boot 内嵌容器模式下,一般不用 JNDI,而是直接用 application.yml 配置数据源:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: root
    password: 123456
    type: com.zaxxer.hikari.HikariDataSource

JNDI 更多用于 传统 war 包部署到外部 Tomcat 的场景。

一句话总结

问题答案
怎么换?改 Ma ven 依赖,排除 Tomcat,引入 Jetty/Undertow
为什么要换?Tomcat 求稳、Jetty 求轻、Undertow 求快
JNDI 受影响吗?内嵌模式一般不用 JNDI,外部部署时各容器配置位置不同

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多