一、纯 MyBatis 项目无 Spring纯 MyBatis 有两种方式配置第三方连接池方式一自定义 DataSourceFactory原理MyBatis 内置只支持POOLED/UNPOOLED/JNDI没有 HikariCP/Druid 的内置支持。通过自定义工厂类让 MyBatis 能创建第三方连接池。1. 添加 Maven 依赖!-- MyBatis -- dependency groupIdorg.mybatis/groupId artifactIdmybatis/artifactId version3.5.13/version /dependency !-- 数据库驱动 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency !-- 连接池三选一 -- !-- HikariCP -- dependency groupIdcom.zaxxer/groupId artifactIdHikariCP/artifactId version5.0.1/version /dependency !-- 或 Druid -- dependency groupIdcom.alibaba/groupId artifactIddruid/artifactId version1.2.20/version /dependency2. 编写自定义工厂类HikariCP 版本package com.example.factory; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import org.apache.ibatis.datasource.DataSourceFactory; import javax.sql.DataSource; import java.util.Properties; public class HikariDataSourceFactory implements DataSourceFactory { private Properties props; // MyBatis 自动调用传入 xml 里的 property 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 javax.sql.DataSource; import java.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?xml version1.0 encodingUTF-8? !DOCTYPE configuration PUBLIC -//mybatis.org//DTD Config 3.0//EN http://mybatis.org/dtd/mybatis-3-config.dtd configuration environments defaultdev environment iddev transactionManager typeJDBC/ !-- type 填自定义工厂类的全限定名 -- dataSource typecom.example.factory.HikariDataSourceFactory !-- 这些属性会被收集成 Properties 传给 setProperties() -- property namedriverClassName valuecom.mysql.cj.jdbc.Driver/ property namejdbcUrl valuejdbc:mysql://localhost:3306/mydb/ property nameusername valueroot/ property namepassword value123456/ !-- HikariCP 参数 -- property namemaximumPoolSize value20/ property nameminimumIdle value5/ property nameconnectionTimeout value30000/ property nameidleTimeout value600000/ property namemaxLifetime value1800000/ /dataSource /environment /environments !-- Mapper 注册 -- mappers mapper resourcemapper/UserMapper.xml/ /mappers /configuration4. Java 代码中使用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容器整个过程和 Tomcat 没有任何关系就是一个普通的 Java 程序用main()方法就能直接跑。方式二JNDI 方式原理连接池不由 MyBatis 创建而是由 Tomcat 等 Web 容器提前配置好MyBatis 通过 JNDI 名称去查找获取。适用场景多应用共享同一个连接池数据库密码不写在应用代码里企业级 war 包部署到外部 TomcatJNDI 方式的本质┌─────────────────────────────────────┐ │ Tomcat 服务器 │ │ ┌─────────────────────────────┐ │ │ │ context.xml 里配置 │ │ │ │ - 数据库密码 │ │ │ │ - 连接池参数 │ │ │ │ - 连接池实现Druid等 │ │ │ │ │ │ │ │ 对外暴露namejdbc/MyDB │ │ │ └─────────────────────────────┘ │ └─────────────────────────────────────┘ ↑ JNDI 查找按名字 ↓ ┌─────────────────────────────────────┐ │ MyBatis 应用war包 │ │ │ │ mybatis-config.xml 里只有 │ │ dataSource typeJNDI │ │ property namedata_source │ │ valuejava:comp/env/ │ │ jdbc/MyDB/ │ │ /dataSource │ │ │ │ ❌ 没有数据库密码 │ │ ❌ 没有连接池参数 │ │ ❌ 不知道用的是 Druid 还是 Hikari │ └─────────────────────────────────────┘为什么企业级部署常用 JNDI场景一个 Tomcat 跑 3 个应用不用 JNDI每个应用自己配应用A配了 HikariCPmax10密码123456 应用B配了 Druidmax10密码123456 应用C配了 c3p0max10密码123456 → 总共 30 个连接密码改了要改 3 个地方用 JNDI统一配置Tomcat 配 1 个连接池max20密码123456 应用A、B、C 都引用 jdbc/MyDB → 总共 20 个连接密码改了只改 1 个地方一句话总结JNDI 方式 把数据库配置外包给 TomcatMyBatis 只负责说给我 jdbc/MyDB具体怎么连、用什么连、密码是什么全由 Tomcat 管。这和 Spring 无关是纯 MyBatis 项目在企业部署时的标准做法。1. 在 Tomcat 中配置连接池找到Tomcat/conf/context.xml添加Context !-- 给连接池起个名字jdbc/MyDB -- Resource namejdbc/MyDB authContainer typejavax.sql.DataSource !-- 连接池实现可换 Druid、DBCP、HikariCP 等 -- factorycom.alibaba.druid.pool.DruidDataSourceFactory !-- 数据库基本信息 -- driverClassNamecom.mysql.cj.jdbc.Driver urljdbc:mysql://localhost:3306/mydb usernameroot password123456 !-- 连接池参数 -- maxActive20 maxIdle10 maxWait10000 / /Context不同连接池只需改factory和参数名连接池factory 值参数特点Druidcom.alibaba.druid.pool.DruidDataSourceFactorymaxActive,maxWaitDBCPorg.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactorymaxTotal,maxWaitMillisHikariCPcom.zaxxer.hikari.HikariJNDIFactorymaximumPoolSize,connectionTimeout2. MyBatis 配置文件mybatis-config.xml?xml version1.0 encodingUTF-8? !DOCTYPE configuration PUBLIC -//mybatis.org//DTD Config 3.0//EN http://mybatis.org/dtd/mybatis-3-config.dtd configuration environments defaultdev environment iddev transactionManager typeJDBC/ !-- typeJNDI只需填名字 -- dataSource typeJNDI !-- java:comp/env/ 是 JNDI 标准前缀 -- property namedata_source valuejava:comp/env/jdbc/MyDB/ /dataSource /environment /environments mappers mapper resourcemapper/UserMapper.xml/ /mappers /configuration关键点typeJNDI告诉 MyBatis我不自己创建连接池去服务器上找java:comp/env/这是 JNDI 的标准前缀就像打电话要加区号jdbc/MyDB就是 Tomcat 里配置的那个名字3. 项目打包为 war 部署到 Tomcat!-- pom.xml -- packagingwar/packaging dependencies !-- Servlet APIprovidedTomcat 自带 -- dependency groupIdjavax.servlet/groupId artifactIdjavax.servlet-api/artifactId version4.0.1/version scopeprovided/scope /dependency !-- MyBatis -- dependency groupIdorg.mybatis/groupId artifactIdmybatis/artifactId version3.5.13/version /dependency /dependencies完整流程图┌─────────────────┐ │ Tomcat 服务器 │ │ ┌───────────┐ │ │ │ Druid连接池 │ ← 统一管理20个连接 │ │ name │ │ │ │ jdbc/MyDB │ │ │ └─────┬─────┘ │ └────────┼────────┘ │ JNDI 查找按名字要 │ ┌────────┼────────┐ │ MyBatis 应用 │ │ 给我 jdbc/MyDB │ │ 不知道真实密码 │ └─────────────────┘注意不同的连接池比如c3p0、dbcp就直接修改tomcat配置文件中的factorycom.alibaba.druid.pool.DruidDataSourceFactory其他的不用变就行了两种纯 MyBatis方式的对比自定义 DataSourceFactoryJNDI 方式连接池在哪创建MyBatis 应用内部Tomcat 服务器里谁管理连接池MyBatis 自己Tomcat 容器密码存在哪mybatis-config.xml里Tomcat 的context.xml里应用是否知道密码✅ 知道❌ 不知道只知道名字多个应用共享❌ 每个应用独立✅共享同一个适用场景单机部署多应用共享、企业级部署二、MyBatis Spring 项目推荐Spring 管理连接池MyBatis 直接引用最常用、最简洁。Spring MyBatis 配置第三方连接池非常灵活核心思路是Spring 创建连接池 Bean → MyBatis 引用这个 Bean。1. 添加 Maven 依赖dependencies !-- Spring 核心 -- dependency groupIdorg.springframework/groupId artifactIdspring-context/artifactId version5.3.29/version /dependency !-- Spring JDBC包含事务管理 -- dependency groupIdorg.springframework/groupId artifactIdspring-jdbc/artifactId version5.3.29/version /dependency !-- MyBatis -- dependency groupIdorg.mybatis/groupId artifactIdmybatis/artifactId version3.5.13/version /dependency !-- MyBatis-Spring 整合包 -- dependency groupIdorg.mybatis/groupId artifactIdmybatis-spring/artifactId version2.1.1/version /dependency !-- 数据库驱动 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency !-- 连接池三选一 -- !-- HikariCP推荐 -- dependency groupIdcom.zaxxer/groupId artifactIdHikariCP/artifactId version5.0.1/version /dependency !-- 或 Druid -- dependency groupIdcom.alibaba/groupId artifactIddruid/artifactId version1.2.20/version /dependency !-- 或 DBCPTomcat 自带无需额外依赖 -- !-- 使用 org.apache.commons:commons-dbcp2 -- /dependencies2. Spring 配置文件applicationContext.xml方案 AHikariCP?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beans xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:contexthttp://www.springframework.org/schema/context xmlns:txhttp://www.springframework.org/schema/tx xsi:schemaLocation http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd !-- 1. 连接池HikariCP -- bean iddataSource classcom.zaxxer.hikari.HikariDataSource !-- 基本配置 -- property namedriverClassName valuecom.mysql.cj.jdbc.Driver/ property namejdbcUrl valuejdbc:mysql://localhost:3306/mydb?useSSLfalseamp;serverTimezoneAsia/Shanghai/ property nameusername valueroot/ property namepassword value123456/ !-- 连接池参数 -- property namemaximumPoolSize value20/ !-- 最大连接数 -- property nameminimumIdle value5/ !-- 最小空闲连接 -- property nameconnectionTimeout value30000/ !-- 连接超时(毫秒) -- property nameidleTimeout value600000/ !-- 空闲超时(毫秒) -- property namemaxLifetime value1800000/ !-- 最大生命周期(毫秒) -- property namepoolName valueHikariPool/ !-- 连接池名称 -- /bean !-- 2. SqlSessionFactory -- bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBean !-- 引用 dataSource -- !-- 引用上面的 dataSource -- property namedataSource refdataSource/ !-- Mapper XML 文件位置 -- property namemapperLocations valueclasspath:mapper/*.xml/ !-- 可选MyBatis 全局配置文件 -- property nameconfigLocation valueclasspath:mybatis-config.xml/ !-- 可选实体类别名包 -- property nametypeAliasesPackage valuecom.example.entity/ /bean !-- 3. Mapper 接口扫描 -- bean classorg.mybatis.spring.mapper.MapperScannerConfigurer property namebasePackage valuecom.example.mapper/ property namesqlSessionFactoryBeanName valuesqlSessionFactory/ /bean !-- 4. 事务管理器 -- bean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManager property namedataSource refdataSource/ /bean !-- 5. 开启注解事务 -- tx:annotation-driven transaction-managertransactionManager/ /beans方案 BDruid带监控?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beans xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:txhttp://www.springframework.org/schema/tx xsi:schemaLocation http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd !-- 1. 连接池Druid -- bean iddataSource classcom.alibaba.druid.pool.DruidDataSource init-methodinit destroy-methodclose !-- 基本配置 -- property namedriverClassName valuecom.mysql.cj.jdbc.Driver/ property nameurl valuejdbc:mysql://localhost:3306/mydb?useSSLfalseamp;serverTimezoneAsia/Shanghai/ property nameusername valueroot/ property namepassword value123456/ !-- 连接池参数 -- property namemaxActive value20/ !-- 最大连接数 -- property nameminIdle value5/ !-- 最小空闲连接 -- property namemaxWait value60000/ !-- 获取连接最大等待时间(毫秒) -- property nameinitialSize value5/ !-- 初始连接数 -- !-- Druid 特有监控和防御 -- property namefilters valuestat,wall,slf4j/ !-- 监控防火墙日志 -- property namevalidationQuery valueSELECT 1/ property nametestWhileIdle valuetrue/ property nametestOnBorrow valuefalse/ property nametestOnReturn valuefalse/ !-- 连接池监控页面配置需要配置 Servlet -- property nameresetEnable valuefalse/ /bean !-- 2. SqlSessionFactory -- bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBean property namedataSource refdataSource/ property namemapperLocations valueclasspath:mapper/*.xml/ /bean !-- 3. Mapper 扫描 -- bean classorg.mybatis.spring.mapper.MapperScannerConfigurer property namebasePackage valuecom.example.mapper/ /bean !-- 4. 事务管理器 -- bean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManager property namedataSource refdataSource/ /bean tx:annotation-driven transaction-managertransactionManager/ /beans方案 CDBCPTomcat 自带简单!-- 无需额外 Maven 依赖 -- bean iddataSource classorg.apache.commons.dbcp2.BasicDataSource destroy-methodclose property namedriverClassName valuecom.mysql.cj.jdbc.Driver/ property nameurl valuejdbc:mysql://localhost:3306/mydb/ property nameusername valueroot/ property namepassword value123456/ property namemaxTotal value20/ !-- 最大连接数 -- property namemaxIdle value10/ !-- 最大空闲连接 -- property nameminIdle value5/ !-- 最小空闲连接 -- property namemaxWaitMillis value10000/ !-- 最大等待时间(毫秒) -- /bean3. 参数名速查表功能HikariCPDruidDBCP驱动类driverClassNamedriverClassNamedriverClassName数据库URLjdbcUrlurlurl用户名usernameusernameusername密码passwordpasswordpassword最大连接数maximumPoolSizemaxActivemaxTotal最小空闲连接minimumIdleminIdleminIdle初始连接数—initialSizeinitialSize连接超时/等待connectionTimeoutmaxWaitmaxWaitMillis空闲超时idleTimeout—minEvictableIdleTimeMillis最大生命周期maxLifetime——连接检测SQL—validationQueryvalidationQuery4. Java 代码中使用// 实体类 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六、Spring Boot Mybatis项目6-1、Spring boot项目换不同的web容器一、Spring Boot 怎么换 Web 容器Spring Boot 默认内嵌 Tomcat但换起来非常简单就是排除一个依赖、引入另一个依赖。1. 换成 Jetty!-- pom.xml -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId !-- 排除默认的 Tomcat -- exclusions exclusion groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-tomcat/artifactId /exclusion /exclusions /dependency !-- 引入 Jetty -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-jetty/artifactId /dependency2. 换成 Undertow性能极高!-- 同样排除 Tomcat -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId exclusions exclusion groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-tomcat/artifactId /exclusion /exclusions /dependency !-- 引入 Undertow -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-undertow/artifactId /dependency就改这几行 Maven 依赖代码完全不用动Spring Boot 自动适配。二、为什么要换—— 三种容器对比特性Tomcat默认JettyUndertow出身Apache 基金会Eclipse 基金会JBoss红帽体积中等最轻量轻量性能中等中等最高高并发场景优势明显内存占用中等较低最低启动速度中等最快快并发模型线程池阻塞IO线程池非阻塞IOXNIO热部署支持支持最好支持嵌入式友好好最好好企业级生态最成熟较少较少典型场景通用、企业级微服务、嵌入式设备高并发、云原生、低内存三、什么场景换什么容器场景 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.HikariDataSourceJNDI 更多用于传统 war 包部署到外部 Tomcat的场景。一句话总结问题答案怎么换改 Maven 依赖排除 Tomcat引入 Jetty/Undertow为什么要换Tomcat 求稳、Jetty 求轻、Undertow 求快JNDI 受影响吗内嵌模式一般不用 JNDI外部部署时各容器配置位置不同
Mybatis13-不同的数据库连接池的配置
一、纯 MyBatis 项目无 Spring纯 MyBatis 有两种方式配置第三方连接池方式一自定义 DataSourceFactory原理MyBatis 内置只支持POOLED/UNPOOLED/JNDI没有 HikariCP/Druid 的内置支持。通过自定义工厂类让 MyBatis 能创建第三方连接池。1. 添加 Maven 依赖!-- MyBatis -- dependency groupIdorg.mybatis/groupId artifactIdmybatis/artifactId version3.5.13/version /dependency !-- 数据库驱动 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency !-- 连接池三选一 -- !-- HikariCP -- dependency groupIdcom.zaxxer/groupId artifactIdHikariCP/artifactId version5.0.1/version /dependency !-- 或 Druid -- dependency groupIdcom.alibaba/groupId artifactIddruid/artifactId version1.2.20/version /dependency2. 编写自定义工厂类HikariCP 版本package com.example.factory; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import org.apache.ibatis.datasource.DataSourceFactory; import javax.sql.DataSource; import java.util.Properties; public class HikariDataSourceFactory implements DataSourceFactory { private Properties props; // MyBatis 自动调用传入 xml 里的 property 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 javax.sql.DataSource; import java.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?xml version1.0 encodingUTF-8? !DOCTYPE configuration PUBLIC -//mybatis.org//DTD Config 3.0//EN http://mybatis.org/dtd/mybatis-3-config.dtd configuration environments defaultdev environment iddev transactionManager typeJDBC/ !-- type 填自定义工厂类的全限定名 -- dataSource typecom.example.factory.HikariDataSourceFactory !-- 这些属性会被收集成 Properties 传给 setProperties() -- property namedriverClassName valuecom.mysql.cj.jdbc.Driver/ property namejdbcUrl valuejdbc:mysql://localhost:3306/mydb/ property nameusername valueroot/ property namepassword value123456/ !-- HikariCP 参数 -- property namemaximumPoolSize value20/ property nameminimumIdle value5/ property nameconnectionTimeout value30000/ property nameidleTimeout value600000/ property namemaxLifetime value1800000/ /dataSource /environment /environments !-- Mapper 注册 -- mappers mapper resourcemapper/UserMapper.xml/ /mappers /configuration4. Java 代码中使用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容器整个过程和 Tomcat 没有任何关系就是一个普通的 Java 程序用main()方法就能直接跑。方式二JNDI 方式原理连接池不由 MyBatis 创建而是由 Tomcat 等 Web 容器提前配置好MyBatis 通过 JNDI 名称去查找获取。适用场景多应用共享同一个连接池数据库密码不写在应用代码里企业级 war 包部署到外部 TomcatJNDI 方式的本质┌─────────────────────────────────────┐ │ Tomcat 服务器 │ │ ┌─────────────────────────────┐ │ │ │ context.xml 里配置 │ │ │ │ - 数据库密码 │ │ │ │ - 连接池参数 │ │ │ │ - 连接池实现Druid等 │ │ │ │ │ │ │ │ 对外暴露namejdbc/MyDB │ │ │ └─────────────────────────────┘ │ └─────────────────────────────────────┘ ↑ JNDI 查找按名字 ↓ ┌─────────────────────────────────────┐ │ MyBatis 应用war包 │ │ │ │ mybatis-config.xml 里只有 │ │ dataSource typeJNDI │ │ property namedata_source │ │ valuejava:comp/env/ │ │ jdbc/MyDB/ │ │ /dataSource │ │ │ │ ❌ 没有数据库密码 │ │ ❌ 没有连接池参数 │ │ ❌ 不知道用的是 Druid 还是 Hikari │ └─────────────────────────────────────┘为什么企业级部署常用 JNDI场景一个 Tomcat 跑 3 个应用不用 JNDI每个应用自己配应用A配了 HikariCPmax10密码123456 应用B配了 Druidmax10密码123456 应用C配了 c3p0max10密码123456 → 总共 30 个连接密码改了要改 3 个地方用 JNDI统一配置Tomcat 配 1 个连接池max20密码123456 应用A、B、C 都引用 jdbc/MyDB → 总共 20 个连接密码改了只改 1 个地方一句话总结JNDI 方式 把数据库配置外包给 TomcatMyBatis 只负责说给我 jdbc/MyDB具体怎么连、用什么连、密码是什么全由 Tomcat 管。这和 Spring 无关是纯 MyBatis 项目在企业部署时的标准做法。1. 在 Tomcat 中配置连接池找到Tomcat/conf/context.xml添加Context !-- 给连接池起个名字jdbc/MyDB -- Resource namejdbc/MyDB authContainer typejavax.sql.DataSource !-- 连接池实现可换 Druid、DBCP、HikariCP 等 -- factorycom.alibaba.druid.pool.DruidDataSourceFactory !-- 数据库基本信息 -- driverClassNamecom.mysql.cj.jdbc.Driver urljdbc:mysql://localhost:3306/mydb usernameroot password123456 !-- 连接池参数 -- maxActive20 maxIdle10 maxWait10000 / /Context不同连接池只需改factory和参数名连接池factory 值参数特点Druidcom.alibaba.druid.pool.DruidDataSourceFactorymaxActive,maxWaitDBCPorg.apache.tomcat.dbcp.dbcp2.BasicDataSourceFactorymaxTotal,maxWaitMillisHikariCPcom.zaxxer.hikari.HikariJNDIFactorymaximumPoolSize,connectionTimeout2. MyBatis 配置文件mybatis-config.xml?xml version1.0 encodingUTF-8? !DOCTYPE configuration PUBLIC -//mybatis.org//DTD Config 3.0//EN http://mybatis.org/dtd/mybatis-3-config.dtd configuration environments defaultdev environment iddev transactionManager typeJDBC/ !-- typeJNDI只需填名字 -- dataSource typeJNDI !-- java:comp/env/ 是 JNDI 标准前缀 -- property namedata_source valuejava:comp/env/jdbc/MyDB/ /dataSource /environment /environments mappers mapper resourcemapper/UserMapper.xml/ /mappers /configuration关键点typeJNDI告诉 MyBatis我不自己创建连接池去服务器上找java:comp/env/这是 JNDI 的标准前缀就像打电话要加区号jdbc/MyDB就是 Tomcat 里配置的那个名字3. 项目打包为 war 部署到 Tomcat!-- pom.xml -- packagingwar/packaging dependencies !-- Servlet APIprovidedTomcat 自带 -- dependency groupIdjavax.servlet/groupId artifactIdjavax.servlet-api/artifactId version4.0.1/version scopeprovided/scope /dependency !-- MyBatis -- dependency groupIdorg.mybatis/groupId artifactIdmybatis/artifactId version3.5.13/version /dependency /dependencies完整流程图┌─────────────────┐ │ Tomcat 服务器 │ │ ┌───────────┐ │ │ │ Druid连接池 │ ← 统一管理20个连接 │ │ name │ │ │ │ jdbc/MyDB │ │ │ └─────┬─────┘ │ └────────┼────────┘ │ JNDI 查找按名字要 │ ┌────────┼────────┐ │ MyBatis 应用 │ │ 给我 jdbc/MyDB │ │ 不知道真实密码 │ └─────────────────┘注意不同的连接池比如c3p0、dbcp就直接修改tomcat配置文件中的factorycom.alibaba.druid.pool.DruidDataSourceFactory其他的不用变就行了两种纯 MyBatis方式的对比自定义 DataSourceFactoryJNDI 方式连接池在哪创建MyBatis 应用内部Tomcat 服务器里谁管理连接池MyBatis 自己Tomcat 容器密码存在哪mybatis-config.xml里Tomcat 的context.xml里应用是否知道密码✅ 知道❌ 不知道只知道名字多个应用共享❌ 每个应用独立✅共享同一个适用场景单机部署多应用共享、企业级部署二、MyBatis Spring 项目推荐Spring 管理连接池MyBatis 直接引用最常用、最简洁。Spring MyBatis 配置第三方连接池非常灵活核心思路是Spring 创建连接池 Bean → MyBatis 引用这个 Bean。1. 添加 Maven 依赖dependencies !-- Spring 核心 -- dependency groupIdorg.springframework/groupId artifactIdspring-context/artifactId version5.3.29/version /dependency !-- Spring JDBC包含事务管理 -- dependency groupIdorg.springframework/groupId artifactIdspring-jdbc/artifactId version5.3.29/version /dependency !-- MyBatis -- dependency groupIdorg.mybatis/groupId artifactIdmybatis/artifactId version3.5.13/version /dependency !-- MyBatis-Spring 整合包 -- dependency groupIdorg.mybatis/groupId artifactIdmybatis-spring/artifactId version2.1.1/version /dependency !-- 数据库驱动 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId version8.0.33/version /dependency !-- 连接池三选一 -- !-- HikariCP推荐 -- dependency groupIdcom.zaxxer/groupId artifactIdHikariCP/artifactId version5.0.1/version /dependency !-- 或 Druid -- dependency groupIdcom.alibaba/groupId artifactIddruid/artifactId version1.2.20/version /dependency !-- 或 DBCPTomcat 自带无需额外依赖 -- !-- 使用 org.apache.commons:commons-dbcp2 -- /dependencies2. Spring 配置文件applicationContext.xml方案 AHikariCP?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beans xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:contexthttp://www.springframework.org/schema/context xmlns:txhttp://www.springframework.org/schema/tx xsi:schemaLocation http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd !-- 1. 连接池HikariCP -- bean iddataSource classcom.zaxxer.hikari.HikariDataSource !-- 基本配置 -- property namedriverClassName valuecom.mysql.cj.jdbc.Driver/ property namejdbcUrl valuejdbc:mysql://localhost:3306/mydb?useSSLfalseamp;serverTimezoneAsia/Shanghai/ property nameusername valueroot/ property namepassword value123456/ !-- 连接池参数 -- property namemaximumPoolSize value20/ !-- 最大连接数 -- property nameminimumIdle value5/ !-- 最小空闲连接 -- property nameconnectionTimeout value30000/ !-- 连接超时(毫秒) -- property nameidleTimeout value600000/ !-- 空闲超时(毫秒) -- property namemaxLifetime value1800000/ !-- 最大生命周期(毫秒) -- property namepoolName valueHikariPool/ !-- 连接池名称 -- /bean !-- 2. SqlSessionFactory -- bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBean !-- 引用 dataSource -- !-- 引用上面的 dataSource -- property namedataSource refdataSource/ !-- Mapper XML 文件位置 -- property namemapperLocations valueclasspath:mapper/*.xml/ !-- 可选MyBatis 全局配置文件 -- property nameconfigLocation valueclasspath:mybatis-config.xml/ !-- 可选实体类别名包 -- property nametypeAliasesPackage valuecom.example.entity/ /bean !-- 3. Mapper 接口扫描 -- bean classorg.mybatis.spring.mapper.MapperScannerConfigurer property namebasePackage valuecom.example.mapper/ property namesqlSessionFactoryBeanName valuesqlSessionFactory/ /bean !-- 4. 事务管理器 -- bean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManager property namedataSource refdataSource/ /bean !-- 5. 开启注解事务 -- tx:annotation-driven transaction-managertransactionManager/ /beans方案 BDruid带监控?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beans xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:txhttp://www.springframework.org/schema/tx xsi:schemaLocation http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd !-- 1. 连接池Druid -- bean iddataSource classcom.alibaba.druid.pool.DruidDataSource init-methodinit destroy-methodclose !-- 基本配置 -- property namedriverClassName valuecom.mysql.cj.jdbc.Driver/ property nameurl valuejdbc:mysql://localhost:3306/mydb?useSSLfalseamp;serverTimezoneAsia/Shanghai/ property nameusername valueroot/ property namepassword value123456/ !-- 连接池参数 -- property namemaxActive value20/ !-- 最大连接数 -- property nameminIdle value5/ !-- 最小空闲连接 -- property namemaxWait value60000/ !-- 获取连接最大等待时间(毫秒) -- property nameinitialSize value5/ !-- 初始连接数 -- !-- Druid 特有监控和防御 -- property namefilters valuestat,wall,slf4j/ !-- 监控防火墙日志 -- property namevalidationQuery valueSELECT 1/ property nametestWhileIdle valuetrue/ property nametestOnBorrow valuefalse/ property nametestOnReturn valuefalse/ !-- 连接池监控页面配置需要配置 Servlet -- property nameresetEnable valuefalse/ /bean !-- 2. SqlSessionFactory -- bean idsqlSessionFactory classorg.mybatis.spring.SqlSessionFactoryBean property namedataSource refdataSource/ property namemapperLocations valueclasspath:mapper/*.xml/ /bean !-- 3. Mapper 扫描 -- bean classorg.mybatis.spring.mapper.MapperScannerConfigurer property namebasePackage valuecom.example.mapper/ /bean !-- 4. 事务管理器 -- bean idtransactionManager classorg.springframework.jdbc.datasource.DataSourceTransactionManager property namedataSource refdataSource/ /bean tx:annotation-driven transaction-managertransactionManager/ /beans方案 CDBCPTomcat 自带简单!-- 无需额外 Maven 依赖 -- bean iddataSource classorg.apache.commons.dbcp2.BasicDataSource destroy-methodclose property namedriverClassName valuecom.mysql.cj.jdbc.Driver/ property nameurl valuejdbc:mysql://localhost:3306/mydb/ property nameusername valueroot/ property namepassword value123456/ property namemaxTotal value20/ !-- 最大连接数 -- property namemaxIdle value10/ !-- 最大空闲连接 -- property nameminIdle value5/ !-- 最小空闲连接 -- property namemaxWaitMillis value10000/ !-- 最大等待时间(毫秒) -- /bean3. 参数名速查表功能HikariCPDruidDBCP驱动类driverClassNamedriverClassNamedriverClassName数据库URLjdbcUrlurlurl用户名usernameusernameusername密码passwordpasswordpassword最大连接数maximumPoolSizemaxActivemaxTotal最小空闲连接minimumIdleminIdleminIdle初始连接数—initialSizeinitialSize连接超时/等待connectionTimeoutmaxWaitmaxWaitMillis空闲超时idleTimeout—minEvictableIdleTimeMillis最大生命周期maxLifetime——连接检测SQL—validationQueryvalidationQuery4. Java 代码中使用// 实体类 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六、Spring Boot Mybatis项目6-1、Spring boot项目换不同的web容器一、Spring Boot 怎么换 Web 容器Spring Boot 默认内嵌 Tomcat但换起来非常简单就是排除一个依赖、引入另一个依赖。1. 换成 Jetty!-- pom.xml -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId !-- 排除默认的 Tomcat -- exclusions exclusion groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-tomcat/artifactId /exclusion /exclusions /dependency !-- 引入 Jetty -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-jetty/artifactId /dependency2. 换成 Undertow性能极高!-- 同样排除 Tomcat -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId exclusions exclusion groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-tomcat/artifactId /exclusion /exclusions /dependency !-- 引入 Undertow -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-undertow/artifactId /dependency就改这几行 Maven 依赖代码完全不用动Spring Boot 自动适配。二、为什么要换—— 三种容器对比特性Tomcat默认JettyUndertow出身Apache 基金会Eclipse 基金会JBoss红帽体积中等最轻量轻量性能中等中等最高高并发场景优势明显内存占用中等较低最低启动速度中等最快快并发模型线程池阻塞IO线程池非阻塞IOXNIO热部署支持支持最好支持嵌入式友好好最好好企业级生态最成熟较少较少典型场景通用、企业级微服务、嵌入式设备高并发、云原生、低内存三、什么场景换什么容器场景 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.HikariDataSourceJNDI 更多用于传统 war 包部署到外部 Tomcat的场景。一句话总结问题答案怎么换改 Maven 依赖排除 Tomcat引入 Jetty/Undertow为什么要换Tomcat 求稳、Jetty 求轻、Undertow 求快JNDI 受影响吗内嵌模式一般不用 JNDI外部部署时各容器配置位置不同