生产级 Spring Boot + MyBatis 核心配置模板

适配Spring Boot 2.7.x/3.x + MyBatis 3.5.x ,包含数据源优化、MyBatis 核心配置、插件注册(分页 / 脱敏)、性能调优、日志配置,可直接复制复用,根据项目需求微调即可。

一、核心配置文件(application.yml)

整合HikariCP 最优连接池MySQL 批量优化MyBatis 基础配置日志配置,生产级参数直接适配高并发场景。

yaml

复制代码
# 服务端口
server:
  port: 8080
  tomcat:
    threads:
      max: 200 # Tomcat最大线程数,适配高并发
    connection-timeout: 30000 # 连接超时时间

# 数据源配置(HikariCP,Spring Boot默认最优连接池)
spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/your_db?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&allowMultiQueries=true
    username: root
    password: root123
    # HikariCP连接池优化参数(核心)
    hikari:
      minimum-idle: 5 # 最小空闲连接数,建议=CPU核心数
      maximum-pool-size: 20 # 最大连接数,建议=CPU核心数*2+1,不超过30
      idle-timeout: 300000 # 空闲连接超时时间(5分钟),超时回收
      connection-timeout: 20000 # 获取连接超时时间(20秒)
      max-lifetime: 1800000 # 连接最大生命周期(30分钟),避免无效连接
      connection-test-query: SELECT 1 # 连接有效性检测语句
  # MyBatis基础配置
  mybatis:
    mapper-locations: classpath:mapper/**/*.xml # Mapper XML扫描路径
    type-aliases-package: com.example.entity # 实体类别名包,简化XML中的resultType
    configuration:
      map-underscore-to-camel-case: true # 开启驼峰命名自动映射(db_column → dbColumn)
      cache-enabled: true # 全局开启二级缓存(默认true,可显式开启)
      local-cache-scope: SESSION # 一级缓存作用域:SESSION/STATEMENT(读写分离建议设为STATEMENT)
      lazy-loading-enabled: false # 关闭懒加载(避免N+1查询问题)
      aggressive-lazy-loading: false # 关闭积极懒加载
      multiple-result-sets-enabled: true # 支持多结果集
      use-generated-keys: true # 支持自动生成主键(如MySQL自增ID)
      default-statement-timeout: 30 # SQL执行超时时间(30秒)
      log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl # 日志实现,适配SLF4J/Logback

# 日志配置(MyBatis SQL日志打印,生产可调整级别)
logging:
  level:
    root: INFO
    com.example.mapper: DEBUG # 打印Mapper层SQL(开发/测试开启,生产可设为INFO)
    org.apache.ibatis: WARN
    com.zaxxer.hikari: WARN
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"
    file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"
  file:
    name: logs/app.log # 日志文件路径

二、MyBatis 自定义配置类(MyBatisConfig.java)

包含分页插件、脱敏插件注册自定义 TypeHandler 扫描二级缓存配置,可根据项目需求增删插件,直接注入 Spring 容器即可。

java

运行

复制代码
package com.example.config;

import com.example.plugin.PageInterceptor;
import com.example.plugin.SensitiveInterceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Properties;

/**
 * 生产级MyBatis核心配置类
 * 包含:Mapper扫描、插件注册、事务管理、SqlSessionFactory配置
 */
@Configuration
@MapperScan(basePackages = "com.example.mapper") // Mapper接口扫描路径,替代@Mapper注解
@EnableTransactionManagement(proxyTargetClass = true) // 开启事务管理,CGLIB代理
public class MyBatisConfig {

    @Resource
    private DataSource dataSource; // 注入Spring管理的Hikari数据源

    /**
     * 配置SqlSessionFactory,注册插件、XML路径
     */
    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        // 配置Mapper XML扫描路径(与yml中一致,双重保障)
        factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath:mapper/**/*.xml"));
        // 配置实体类别名包(与yml中一致)
        factoryBean.setTypeAliasesPackage("com.example.entity");
        // 自定义TypeHandler扫描(如有自定义类型转换器,添加此配置)
        // factoryBean.setTypeHandlersPackage("com.example.handler");

        // 注册MyBatis插件(核心:分页+脱敏,可按需增删)
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        // 手动注册插件,优先级高于XML配置
        configuration.addInterceptor(pageInterceptor()); // 分页插件
        configuration.addInterceptor(sensitiveInterceptor()); // 数据脱敏插件
        factoryBean.setConfiguration(configuration);

        return factoryBean.getObject();
    }

    /**
     * 注册分页插件,配置自定义参数
     */
    @Bean
    public PageInterceptor pageInterceptor() {
        PageInterceptor interceptor = new PageInterceptor();
        Properties props = new Properties();
        props.setProperty("dbType", "mysql"); // 数据库类型:mysql/oracle/postgres
        props.setProperty("pageSizeLimit", "100"); // 最大每页条数,防止恶意分页
        interceptor.setProperties(props);
        return interceptor;
    }

    /**
     * 注册数据脱敏插件
     */
    @Bean
    public SensitiveInterceptor sensitiveInterceptor() {
        return new SensitiveInterceptor(); // 无配置参数,直接注册
    }

    /**
     * 配置事务管理器,适配Spring声明式事务(@Transactional)
     */
    @Bean
    public PlatformTransactionManager transactionManager() {
        // 单数据源事务管理器,多数据源需用AbstractRoutingDataSource
        return new DataSourceTransactionManager(dataSource);
    }
}

三、配套必备组件(直接复用 / 微调)

1. 分页插件核心类(PageInterceptor.java)

已在之前文章中提供,需保证包路径与配置类中一致 ,核心实现自动拼接LIMIT,适配 MySQL,可扩展支持 Oracle(ROWNUM)。

2. 脱敏插件核心类(SensitiveInterceptor.java + 注解)

包含@Sensitive注解、SensitiveType枚举、脱敏拦截器,需保证包路径与配置类中一致,直接标记实体类字段即可实现自动脱敏。

3. 分页参数类(PageParam.java)

通用分页参数,适配分页插件,支持页码、每页条数,可扩展排序字段 / 方向。

java

运行

复制代码
package com.example.param;

import lombok.Data;

/**
 * 通用分页参数类
 * 分页插件自动识别此类,拼接分页SQL
 */
@Data
public class PageParam {
    private int pageNum = 1; // 页码,默认1
    private int pageSize = 10; // 每页条数,默认10
    private String sortBy; // 排序字段(可选)
    private String sortDir = "desc"; // 排序方向:asc/desc,默认desc
}

四、Mapper/XML 开发规范(生产级)

基于模板的开发规范,保证代码一致性与性能,直接复用即可。

1. Mapper 接口规范

java

运行

复制代码
package com.example.mapper;

import com.example.entity.OrderDO;
import com.example.param.PageParam;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * Mapper接口规范:
 * 1. 无需加@Mapper(配置类中@MapperScan已扫描);
 * 2. 批量操作参数用List,单参数用@Param明确名称;
 * 3. 分页查询直接传入PageParam,XML无需写LIMIT;
 * 4. 返回值尽量用实体类,避免使用Map(提升性能)。
 */
public interface OrderMapper {
    // 分页查询(插件自动拼接LIMIT)
    List<OrderDO> selectByPage(PageParam pageParam);

    // 单条件查询,@Param明确参数名称
    OrderDO selectById(@Param("id") Long id);

    // 批量插入(适配yml中rewriteBatchedStatements=true)
    int batchInsert(@Param("list") List<OrderDO> orderList);

    // 批量更新(CASE WHEN方式)
    int batchUpdate(@Param("list") List<OrderDO> orderList);
}

2. Mapper XML 规范

xml

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 命名空间必须与Mapper接口全类名一致 -->
<mapper namespace="com.example.mapper.OrderMapper">
    <!-- 自定义ResultMap,明确字段映射,避免自动映射开销(生产必备) -->
    <resultMap id="BaseResultMap" type="com.example.entity.OrderDO">
        <id column="id" property="id" jdbcType="BIGINT"/>
        <result column="user_id" property="userId" jdbcType="BIGINT"/>
        <result column="product_id" property="productId" jdbcType="BIGINT"/>
        <result column="count" property="count" jdbcType="INTEGER"/>
        <result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
        <result column="update_time" property="updateTime" jdbcType="TIMESTAMP"/>
    </resultMap>

    <!-- 分页查询,无需写LIMIT,插件自动拼接 -->
    <select id="selectByPage" parameterType="com.example.param.PageParam" resultMap="BaseResultMap">
        SELECT id, user_id, product_id, count, create_time, update_time
        FROM t_order
        <where>
            <!-- 动态条件,<where>自动处理AND/OR -->
            <if test="sortBy != null and sortBy != ''">
                ORDER BY ${sortBy} ${sortDir}
            </if>
            <if test="sortBy == null or sortBy == ''">
                ORDER BY create_time DESC
            </if>
        </where>
    </select>

    <!-- 单条查询,复用ResultMap -->
    <select id="selectById" parameterType="java.lang.Long" resultMap="BaseResultMap">
        SELECT id, user_id, product_id, count, create_time, update_time
        FROM t_order
        WHERE id = #{id}
    </select>

    <!-- 批量插入,高性能(适配MySQL批量优化) -->
    <insert id="batchInsert" parameterType="java.util.List">
        INSERT INTO t_order (user_id, product_id, count, create_time, update_time)
        VALUES
        <foreach collection="list" item="item" separator="," index="index">
            (#{item.userId}, #{item.productId}, #{item.count}, NOW(), NOW())
        </foreach>
    </insert>

    <!-- 批量更新,CASE WHEN方式,单条SQL完成 -->
    <update id="batchUpdate" parameterType="java.util.List">
        UPDATE t_order
        SET count = CASE
        <foreach collection="list" item="item" separator=" ">
            WHEN id = #{item.id} THEN #{item.count}
        </foreach>
        END,
        update_time = NOW()
        WHERE id IN
        <foreach collection="list" item="item" open="(" close=")" separator=",">
            #{item.id}
        </foreach>
    </update>
</mapper>

五、生产级调优备注(关键)

  1. 数据源调优hikari.maximum-pool-size根据服务器CPU 核心数 调整(建议CPU核心数*2+1),不超过 30,避免连接过多导致数据库压力过大;
  2. SQL 日志 :生产环境将com.example.mapper的日志级别从DEBUG改为INFO,减少日志 IO 开销;
  3. 批量操作 :批量插入 / 更新建议每 500 条分一批 ,避免 SQL 过长触发 MySQLmax_allowed_packet限制;
  4. 缓存配置 :高频查询、低频更新的表(如商品基础信息)可在 XML 中开启二级缓存(添加<cache/>标签),复杂多表联查表禁止开启二级缓存
  5. 读写分离 :若项目使用读写分离,需将mybatis.configuration.local-cache-scope设为STATEMENT,关闭一级缓存,避免脏读;
  6. 插件扩展 :可在配置类中新增自定义插件(如数据权限、SQL 日志增强),遵循 MyBatis 插件开发规范(@Intercepts+@Signature);
  7. 事务管理 :核心业务(如订单、支付)添加@Transactional注解,指定事务传播行为与隔离级别(默认REQUIRED+READ_COMMITTED,生产足够)。

六、目录结构规范(配套模板)

保证项目结构清晰,便于维护,适配 Spring Boot 标准结构:

plaintext

复制代码
src/main/
├── java/com/example/
│   ├── config/        # 配置类(MyBatisConfig、RedisConfig等)
│   ├── entity/        # 实体类(DO/DTO/VO)
│   ├── mapper/        # Mapper接口
│   ├── param/         # 参数类(PageParam、CreateOrderParam等)
│   ├── plugin/        # MyBatis插件(PageInterceptor、SensitiveInterceptor)
│   ├── service/       # 服务层(Impl实现类)
│   ├── controller/    # 控制层
│   └── Application.java # 项目启动类
└── resources/
    ├── mapper/        # Mapper XML文件(按业务模块分包,如order/、user/)
    ├── application.yml # 核心配置文件
    └── logback-spring.xml # 日志详细配置(可选)
相关推荐
nbsaas-boot5 小时前
为什么 ScopedValue 是 SaaS 的分水岭
java
卓怡学长5 小时前
m119在线购书商城系统
java·数据库·spring boot·spring·汽车
yuankunliu5 小时前
【redis】4、Redis的过期策略和淘汰策略
数据库·redis·缓存
haokan_Jia5 小时前
【java使用LinkedHashMap进行list数据分组写入,顺序并没有按照原始顺序,原因分析】
java·开发语言·list
C雨后彩虹5 小时前
中文分词模拟器
java·数据结构·算法·华为·面试
a努力。5 小时前
蚂蚁Java面试被问:流批一体架构的实现和状态管理
java·后端·websocket·spring·面试·职场和发展·架构
虹科网络安全5 小时前
艾体宝洞察 | 缓存策略深度解析:从内存缓存到 Redis 分布式缓存
redis·分布式·缓存
计算机学姐5 小时前
基于SpringBoot的在线骑行网站系统
java·vue.js·spring boot·后端·mysql·spring·tomcat
weixin_440730505 小时前
04python编程笔记-01基础知识+02三种结构
java·笔记·python