mybatis-plus-config.java.ftl 模板文件参考示例

以下是添加了详细中文注释说明mybatis-plus-config.java.ftl 模板文件,涵盖每一行代码的设计意图、配置原理和企业级最佳实践:

package ${package.Config};

<#-- 导入 MyBatis-Plus 核心插件和拦截器 -->
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
<#-- 导入 MyBatis 原生 MetaObject,用于自动填充 -->
import org.apache.ibatis.reflection.MetaObject;
<#-- Spring 注解 -->
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.LocalDateTime;

/**
 * <p>
 * MyBatis-Plus 全局配置类
 * </p>
 *
 * <p>
 * 【核心作用】
 * 1. 注册 MyBatis-Plus 插件(如分页插件)
 * 2. 配置自动填充处理器(Auto Fill Handler)
 * 3. 统一数据库方言、逻辑删除等全局行为
 * </p>
 *
 * <p>
 * 【设计原则】
 * - 通过 Spring {@code @Configuration} 和 {@code @Bean} 声明式配置
 * - 插件链式注册,便于扩展(如添加多租户、性能分析插件)
 * - 自动填充逻辑集中管理,避免在每个 Entity 中重复
 * - 与 application.yml 配置互补,代码配置优先级更高
 * </p>
 *
 * <p>
 * 【注意事项】
 * - 此配置类会被 Spring 自动扫描并加载(需在 ComponentScan 范围内)
 * - 若同时存在 application.yml 中的 MP 配置,代码配置会覆盖 YAML 配置
 * - 分页插件必须在第一个位置(MyBatis-Plus 要求)
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
@Configuration
public class MybatisPlusConfig {

    /**
     * 注册 MyBatis-Plus 拦截器链
     *
     * <p>
     * 【拦截器链说明】
     * MyBatis-Plus 通过 {@link MybatisPlusInterceptor} 管理多个插件,
     * 插件按添加顺序执行(注意:分页插件必须放在第一位!)。
     * </p>
     *
     * <p>
     * 【当前注册的插件】
     * - {@link PaginationInnerInterceptor}:分页插件
     *   - 自动拦截 {@code selectPage} 等方法
     *   - 改写 SQL 添加 LIMIT/OFFSET
     *   - 支持多种数据库方言(MySQL、Oracle、PostgreSQL 等)
     * </p>
     *
     * <p>
     * 【扩展建议】
     * 可在此添加更多插件,例如:
     * - {@code BlockAttackInnerInterceptor}:防止全表更新/删除
     * - {@code TenantLineInnerInterceptor}:多租户插件
     * - {@code OptimisticLockerInnerInterceptor}:乐观锁插件
     * </p>
     *
     * @return 配置好的 MyBatis-Plus 拦截器
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        // 创建拦截器实例
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        
        // 添加分页插件(必须放在第一位!)
        // DbType.MYSQL 表示使用 MySQL 方言(自动处理 LIMIT 语法)
        // 其他常用值:DbType.ORACLE, DbType.POSTGRE_SQL, DbType.SQL_SERVER
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        
        // 【扩展点】在此添加其他插件
        // interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
        
        return interceptor;
    }

    /**
     * 注册自动填充处理器
     *
     * <p>
     * 【自动填充原理】
     * 当执行 INSERT/UPDATE 操作时,MyBatis-Plus 会回调此处理器,
     * 根据字段上的 {@code @TableField(fill = ...)} 注解自动填充值。
     * </p>
     *
     * <p>
     * 【填充策略说明】
     * - {@code FieldFill.INSERT}:仅插入时填充
     * - {@code FieldFill.UPDATE}:仅更新时填充
     * - {@code FieldFill.INSERT_UPDATE}:插入和更新时都填充
     * </p>
     *
     * <p>
     * 【当前填充逻辑】
     * 1. 插入时:
     *    - createTime = 当前时间
     *    - updateTime = 当前时间
     *    - deleted = 0(未删除)
     * 2. 更新时:
     *    - updateTime = 当前时间
     * </p>
     *
     * <p>
     * 【关键方法说明】
     * - {@code strictInsertFill}:严格插入填充(字段必须存在)
     * - {@code strictUpdateFill}:严格更新填充(字段必须存在)
     * - 使用 Lambda 表达式提供值(如 {@code LocalDateTime::now})
     * </p>
     *
     * <p>
     * 【与 Entity 的配合】
     * Entity 字段需添加注解,例如:
     * {@code @TableField(fill = FieldFill.INSERT)}
     * private LocalDateTime createTime;
     * </p>
     *
     * @return 自动填充处理器实例
     */
    @Bean
    public MetaObjectHandler metaObjectHandler() {
        return new MetaObjectHandler() {
            /**
             * 插入操作自动填充
             *
             * <p>
             * 【执行时机】
             * 在执行 {@code insert} 或 {@code insertBatch} 前触发
             * </p>
             *
             * <p>
             * 【填充字段】
             * - createTime:创建时间(仅插入时设置)
             * - updateTime:更新时间(插入时也设置为当前时间)
             * - deleted:逻辑删除标识(默认 0 表示未删除)
             * </p>
             *
             * @param metaObject MyBatis 元对象,包含实体信息
             */
            @Override
            public void insertFill(MetaObject metaObject) {
                // 填充 createTime 字段(仅当字段存在且未手动设置时)
                // LocalDateTime::now 是 Supplier<LocalDateTime>,提供当前时间
                this.strictInsertFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class);
                // this.strictInsertFill(metaObject, BaseEntity::getCreateTime, LocalDateTime::now, LocalDateTime.class);
                
                // 填充 updateTime 字段(插入时也设为当前时间)
                this.strictInsertFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
                // this.strictInsertFill(metaObject, BaseEntity::getUpdateTime, LocalDateTime::now, LocalDateTime.class);
                
                // 填充 deleted 字段(默认 0 表示未删除)
                // 使用 Lambda 表达式提供默认值:() -> 0
                this.strictInsertFill(metaObject, "deleted", () -> 0, Integer.class);
                // this.strictInsertFill(metaObject, BaseEntity::getDeleted, () -> 0, Integer.class);
            }

            /**
             * 更新操作自动填充
             *
             * <p>
             * 【执行时机】
             * 在执行 {@code updateById} 或 {@code update} 前触发
             * </p>
             *
             * <p>
             * 【填充字段】
             * - updateTime:每次更新时刷新为当前时间
             * </p>
             *
             * @param metaObject MyBatis 元对象,包含实体信息
             */
            @Override
            public void updateFill(MetaObject metaObject) {
                // 仅填充 updateTime 字段
                this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
                // this.strictInsertFill(metaObject, BaseEntity::getUpdateTime, LocalDateTime::now, LocalDateTime.class);
            }
        };
    }
}

🔍 关键设计说明补充

1. 为什么分页插件必须放在第一位?
  • MyBatis-Plus 内部对插件执行顺序有严格要求
  • 分页插件需要最先解析 SQL,才能正确提取原始查询并改写
  • 若放在后面,可能被其他插件(如多租户)干扰,导致分页失效
2. strictInsertFill vs fillStrategy
  • strictInsertFill严格模式,仅当字段未设置值时才填充
  • 避免覆盖用户手动设置的值(如创建时指定特殊时间)
  • 推荐始终使用 strict* 方法,而非已废弃的 fillStrategy
3. 数据库方言(DbType)选择
数据库DbType 常量说明
MySQLDbType.MYSQL默认使用
PostgreSQLDbType.POSTGRE_SQL注意拼写
OracleDbType.ORACLE需额外配置
SQL ServerDbType.SQL_SERVER-
达梦DbType.DM国产数据库
4. 自动填充的替代方案
  • 方案A(推荐):代码配置(本模板方式)— 灵活、类型安全

  • 方案B:YAML 配置 — 简单但不够灵活

    mybatis-plus:
      global-config:
        db-config:
          insert-strategy: not_null
          update-strategy: not_null
    
5. 生产环境增强建议
// 防止全表更新/删除(安全防护)
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());

// 乐观锁插件(需 Entity 添加 @Version 注解)
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());

✅ 此模板文件是 MyBatis-Plus 应用的核心配置,正确配置后可:

  • 实现无侵入式分页
  • 自动管理创建/更新时间
  • 统一逻辑删除行为
  • 为后续扩展(多租户、审计等)奠定基础

可直接用于企业级项目,确保数据访问层的健壮性和可维护性。

<think>我们讨论的是MyBatis-Plus的代码生成器,需要给出其Maven依赖。 MyBatis-Plus代码生成器是一个独立的模块,通常需要以下依赖: 1. mybatis-plus-generator: 代码生成器的核心依赖。 2. 模板引擎依赖:比如Velocity、Freemarker或Beetl,用于生成代码的模板。官方默认使用Velocity。 3. 数据库驱动:比如MySQL、Oracle等,根据你使用的数据库选择。 另外,通常我们也会将mybatis-plus-boot-starter(如果是Spring Boot项目)和lombok(用于简化实体类)作为依赖。 但是,这里只要求代码生成器的依赖,所以主要给出生成器模块和模板引擎。 注意:由于代码生成器通常在开发时使用,所以作用域(scope)可以设置为test或provided,但一般我们不会将其打包到生产环境,所以可以放在一个单独的profile或者直接使用而不指定scope(因为生成代码是一次性的,运行完即可)。 下面给出一个典型的依赖配置(以MySQL和Velocity为例): </think>### MyBatis-Plus 代码生成器的 Maven 依赖 以下是 **MyBatis-Plus 代码生成器**的核心 Maven 依赖配置(基于最新稳定版本 3.5.6): ```xml <dependencies> <!-- MyBatis-Plus 代码生成器核心依赖 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.5.6</version> </dependency> <!-- 模板引擎依赖(默认使用 Velocity,二选一即可) --> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.3</version> </dependency> <!-- 或使用 Freemarker 模板引擎(二选一) --> <!-- <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.32</version> </dependency> --> <!-- 数据库驱动(以 MySQL 为例) --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> </dependencies> ``` --- ### 依赖说明 1. **`mybatis-plus-generator`** - **作用**:提供代码生成的核心功能(如生成 Entity、Mapper、Service、Controller 等)。 - **版本要求**:建议使用最新稳定版(3.5.3+),旧版本配置方式不同。 2. **模板引擎依赖** - **必需性**:代码生成器需要模板引擎渲染代码文件- **选项**: - **Velocity**(默认):轻量级,无需额外配置。 - **Freemarker**:需在代码生成配置中指定 `TemplateEngine.ftl()`。 3. **数据库驱动** - **作用**:连接数据库并读取表元数据(如字段名、类型、注释)。 - **按需替换**:根据实际数据库更换驱动(如 Oracle 用 `ojdbc8`,PostgreSQL 用 `postgresql`)。 --- ### 完整代码生成器示例 配置依赖后,可通过以下 Java 代码生成基础 CRUD 模块: ```java import com.baomidou.mybatisplus.generator.FastAutoGenerator; import com.baomidou.mybatisplus.generator.config.DataSourceConfig; public class CodeGenerator { public static void main(String[] args) { FastAutoGenerator.create( new DataSourceConfig .Builder("jdbc:mysql://localhost:3306/your_db", "username", "password") .build() ) .globalConfig(builder -> builder.outputDir("src/main/java") // 输出目录 .author("YourName") // 作者 .fileOverride() // 覆盖已生成文件 ) .packageConfig(builder -> builder.parent("com.example") // 包名 .moduleName("system") // 模块名 ) .strategyConfig(builder -> builder.addInclude("user", "role") // 需生成的表名 ) .execute(); } } ``` --- ### 常见问题原因 1. **生成代码为空/失败** - 数据库连接信息错误(如 IP、端口、用户名密码)。 - 未添加数据库驱动依赖或版本不兼容。 2. **模板语法报错** - 未正确引入模板引擎依赖(如缺少 `velocity-engine-core`)。 3. **过时 API 警告** - 使用旧版 `AutoGenerator`(新版推荐 `FastAutoGenerator`)。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙茶清欢

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值