Java MyBatisPlus代码生成器配置与自定义模板

引言:代码生成器的魅力

在当今的软件开发世界中,效率和质量是两个至关重要的因素。我们不仅要写出功能强大的代码,还要确保这些代码易于维护、扩展和调试。为了实现这一目标,许多开发者选择使用代码生成器来加速开发过程。代码生成器可以帮助我们自动生成重复性高的代码,减少手动编写的时间,从而让我们能够将更多的精力集中在业务逻辑和架构设计上。

MyBatis Plus 是一个基于 MyBatis 的增强工具,它不仅简化了数据库操作,还提供了一个强大的代码生成器,能够根据数据库表结构自动生成实体类、Mapper接口、Service层代码等。这使得开发者可以快速搭建项目的基础框架,极大地提高了开发效率。

然而,标准的代码生成器生成的代码往往只能满足基本需求,无法完全符合项目的特定要求。因此,掌握如何配置和自定义代码生成器模板,成为了提高代码质量和开发效率的关键技能。通过自定义模板,我们可以根据项目的实际需求生成更加符合规范、更具可读性和可维护性的代码。

在这篇文章中,我们将以轻松诙谐的方式,深入探讨 MyBatis Plus 代码生成器的配置与自定义模板。我们会从基础配置开始,逐步深入到高级定制,帮助你在实际项目中灵活运用这一强大工具。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的技术干货和实用技巧。

MyBatis Plus 简介

在进入代码生成器的具体配置之前,我们先来了解一下 MyBatis Plus 到底是什么。MyBatis Plus 是一个基于 MyBatis 的增强工具,旨在简化 MyBatis 的使用,并提供一些额外的功能,使开发者能够更高效地进行数据库操作。MyBatis 本身是一个优秀的持久层框架,它允许你通过 XML 或注解的方式映射 Java 对象与数据库表之间的关系,从而实现数据的持久化操作。而 MyBatis Plus 在此基础上做了进一步的优化和扩展,提供了许多便捷的功能,如条件构造器、分页查询、乐观锁、自动填充等。

MyBatis Plus 的主要特点

  1. 简洁易用:MyBatis Plus 提供了丰富的默认实现,减少了开发者需要编写的代码量。例如,它内置了许多常用的 CRUD 操作方法,开发者只需继承 BaseMapper 接口即可直接使用这些方法,无需再手动编写 SQL 语句。

  2. 条件构造器:MyBatis Plus 提供了一个强大的条件构造器 Wrapper,允许开发者通过链式调用的方式构建复杂的查询条件。这不仅提高了代码的可读性,还避免了手动拼接 SQL 语句时可能出现的错误。

  3. 分页插件:MyBatis Plus 内置了分页插件,支持多种数据库的分页查询。开发者只需调用 Page<T> 方法并传入分页参数,即可轻松实现分页功能,而无需关心不同数据库的分页语法差异。

  4. 乐观锁:MyBatis Plus 支持乐观锁机制,通过在实体类中添加版本号字段,可以在更新数据时自动检查版本号是否一致,从而防止并发更新问题。

  5. 自动填充:MyBatis Plus 提供了自动填充功能,可以在插入或更新数据时自动设置某些字段的值,如创建时间、更新时间等。这不仅减少了代码量,还确保了数据的一致性。

  6. 全局配置:MyBatis Plus 提供了全局配置功能,允许开发者在应用启动时统一配置一些常用参数,如主键生成策略、SQL 日志输出等,从而避免了在每个 Mapper 中重复配置。

  7. 代码生成器:这是本文的重点。MyBatis Plus 内置了一个强大的代码生成器,可以根据数据库表结构自动生成实体类、Mapper接口、Service层代码等。通过配置和自定义模板,开发者可以根据项目的实际需求生成更加符合规范的代码。

为什么选择 MyBatis Plus?

相比于其他 ORM 框架,MyBatis Plus 有着明显的优势。首先,它保留了 MyBatis 的灵活性,允许开发者根据需要编写自定义的 SQL 语句,同时又提供了许多便捷的功能,减少了重复劳动。其次,MyBatis Plus 的学习曲线较低,熟悉 MyBatis 的开发者可以很容易上手。最后,MyBatis Plus 的社区非常活跃,文档和示例代码丰富,遇到问题时可以轻松找到解决方案。

总之,MyBatis Plus 是一个功能强大、易于使用的持久层框架,特别适合那些希望在保持灵活性的同时提高开发效率的开发者。接下来,我们将重点介绍 MyBatis Plus 的代码生成器,看看它是如何帮助我们快速搭建项目的基础框架的。

MyBatis Plus 代码生成器的基本配置

既然我们已经了解了 MyBatis Plus 的强大功能,那么现在让我们来探索一下它的代码生成器。代码生成器可以帮助我们自动生成实体类、Mapper接口、Service层代码等,极大地提高了开发效率。为了让生成的代码符合我们的项目需求,我们需要对代码生成器进行合理的配置。

1. 添加依赖

首先,我们需要在项目的 pom.xml 文件中添加 MyBatis Plus 代码生成器的依赖。如果你使用的是 Maven 项目,可以在 dependencies 节点下添加以下内容:

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.3</version>
</dependency>
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.3</version>
</dependency>

这里我们引入了 mybatis-plus-generatorvelocity-engine-core 两个依赖。mybatis-plus-generator 是 MyBatis Plus 的代码生成器模块,而 velocity-engine-core 是 Velocity 模板引擎,用于生成代码的模板文件。

2. 创建代码生成器类

接下来,我们需要创建一个类来配置和启动代码生成器。你可以将这个类放在项目的任意位置,通常建议放在 src/main/java 目录下的某个包中。下面是一个简单的代码生成器类示例:

import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

public class CodeGenerator {

    public static void main(String[] args) {
        FastAutoGenerator.create("jdbc:mysql://localhost:3306/your_database", "username", "password")
                .globalConfig(builder -> {
                    builder.author("Your Name") // 设置作者名
                            .outputDir(System.getProperty("user.dir") + "/src/main/java"); // 设置输出目录
                })
                .dataSourceConfig(dataSourceConfig -> {
                    dataSourceConfig.driverName("com.mysql.cj.jdbc.Driver") // 设置数据库驱动
                            .url("jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC") // 设置数据库连接URL
                            .username("username") // 设置数据库用户名
                            .password("password"); // 设置数据库密码
                })
                .packageConfig(packageConfig -> {
                    packageConfig.parent("com.example") // 设置父包名
                            .moduleName("demo") // 设置模块名
                            .entity("entity") // 设置实体类包名
                            .mapper("mapper") // 设置Mapper接口包名
                            .service("service") // 设置Service接口包名
                            .controller("controller"); // 设置Controller包名
                })
                .strategyConfig(strategyConfig -> {
                    strategyConfig.addInclude("user", "order") // 设置要生成的表名
                            .addTablePrefix("t_", "sys_") // 设置表前缀
                            .entityBuilder() // 配置实体类生成策略
                                .enableLombok() // 开启 Lombok 注解
                                .naming(NamingStrategy.underline_to_camel) // 表名转驼峰命名
                                .columnNaming(NamingStrategy.underline_to_camel) // 字段名转驼峰命名
                            .controllerBuilder() // 配置Controller生成策略
                                .enableRestStyle(); // 开启 REST 风格
                })
                .templateEngine(new VelocityTemplateEngine()) // 使用 Velocity 模板引擎
                .execute(); // 执行代码生成
    }
}

3. 配置说明

让我们逐一解释一下上述代码中的各个配置项:

  • FastAutoGenerator.create():这是代码生成器的入口方法,接受三个参数:数据库连接 URL、用户名和密码。你可以根据自己的数据库信息进行修改。

  • globalConfig():用于配置全局参数。这里我们设置了作者名和输出目录。outputDir 是生成代码的存放路径,默认为当前项目的根目录下的 src/main/java

  • dataSourceConfig():用于配置数据库连接信息。你需要根据自己的数据库类型和连接方式填写正确的驱动名称、URL、用户名和密码。

  • packageConfig():用于配置生成代码的包结构。parent 是父包名,moduleName 是模块名,entitymapperservicecontroller 分别是实体类、Mapper接口、Service接口和Controller的包名。你可以根据项目的实际情况进行调整。

  • strategyConfig():用于配置生成代码的策略。addInclude() 用于指定要生成的表名,addTablePrefix() 用于设置表前缀(生成代码时会自动去掉前缀)。entityBuilder()controllerBuilder() 分别用于配置实体类和Controller的生成策略。这里我们开启了 Lombok 注解、REST 风格以及驼峰命名规则。

  • templateEngine():用于指定模板引擎。MyBatis Plus 默认使用 FreeMarker 作为模板引擎,但在这里我们选择了 Velocity。你可以根据个人喜好选择不同的模板引擎。

4. 运行代码生成器

配置完成后,你可以直接运行 CodeGenerator 类的 main 方法。代码生成器会根据你配置的参数,自动生成相应的代码文件。生成的代码会存放在你指定的输出目录中,通常位于 src/main/java 下的相应包中。

自定义代码生成器模板

虽然 MyBatis Plus 提供了默认的代码生成模板,但这些模板可能并不完全符合你的项目需求。为了生成更加符合规范、更具可读性和可维护性的代码,我们可以对代码生成器的模板进行自定义。MyBatis Plus 支持多种模板引擎,如 FreeMarker、Velocity 和 Beetl,你可以根据自己的喜好选择合适的模板引擎。

1. 模板文件的结构

MyBatis Plus 的代码生成器会根据不同的文件类型生成不同的代码文件。常见的文件类型包括:

  • Entity.java:实体类,对应数据库表的结构。
  • Mapper.java:Mapper接口,用于定义数据库操作方法。
  • ServiceImpl.java:Service实现类,包含业务逻辑。
  • Controller.java:Controller类,用于处理 HTTP 请求。
  • Mapper.xml:Mapper的 XML 文件,包含 SQL 语句。

每种文件类型都有对应的模板文件,通常存放在 templates 目录下。你可以根据需要修改这些模板文件,以生成符合项目需求的代码。

2. 修改模板文件

假设你想修改实体类的生成模板,使其包含更多的注释或自定义方法。你可以找到 templates/entity.java.vm 文件(如果是使用 Velocity 模板引擎),然后根据需要进行修改。以下是一个简单的示例:

#parse("fileHeader.java.vm")

package ${package.Entity};

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

/**
 * ${table.comment} (自定义注释)
 */
@Data
@TableName("${table.name}")
public class ${className} {

    #foreach($column in $columns)
        /**
         * ${column.comment} (自定义字段注释)
         */
        @TableField("${column.name}")
        private ${column.javaType} ${column.name}; 
    #end

    /**
     * 自定义方法
     */
    public void customMethod() {
        // 自定义逻辑
    }
}

在这个模板中,我们添加了一些自定义的注释和方法。#parse("fileHeader.java.vm") 用于引入文件头模板,#foreach 用于遍历表中的列,生成对应的字段。customMethod 是我们自定义的方法,你可以根据项目的实际需求添加更多的逻辑。

3. 添加新的模板文件

除了修改现有的模板文件,你还可以根据需要添加新的模板文件。例如,如果你想为每个实体类生成一个 DTO(Data Transfer Object)类,可以在 templates 目录下创建一个新的模板文件 dto.java.vm,并在代码生成器中配置生成 DTO 类的逻辑。

#parse("fileHeader.java.vm")

package ${package.dto};

import lombok.Data;

/**
 * ${table.comment} DTO (自定义注释)
 */
@Data
public class ${className}DTO {

    #foreach($column in $columns)
        /**
         * ${column.comment} (自定义字段注释)
         */
        private ${column.javaType} ${column.name}; 
    #end
}

然后,在 CodeGenerator 类中添加生成 DTO 类的配置:

.templateConfig(templateConfig -> {
    templateConfig.setDto("/templates/dto.java.vm"); // 设置 DTO 模板路径
})

4. 使用模板引擎的高级特性

不同的模板引擎提供了不同的语法和特性。例如,Velocity 模板引擎支持宏定义、条件判断和循环等高级特性。你可以利用这些特性来生成更加复杂的代码。以下是一些常见的 Velocity 语法示例:

  • 宏定义#macro(name, param) 用于定义宏,#end 用于结束宏定义。#name($param) 用于调用宏。
  • 条件判断#if($condition) 用于条件判断,#else 用于定义 else 分支,#end 用于结束条件判断。
  • 循环#foreach($item in $list) 用于遍历列表,#end 用于结束循环。

通过合理使用这些高级特性,你可以生成更加灵活和复杂的代码。

实战案例:生成带有权限控制的 API

在实际项目中,我们经常需要为 API 添加权限控制。为了简化开发过程,我们可以通过自定义代码生成器模板,自动生成带有权限控制的 API。下面是一个实战案例,展示如何实现这一功能。

1. 修改 Controller 模板

首先,我们需要修改 templates/controller.java.vm 文件,添加权限控制相关的注解。假设我们使用 Spring Security 进行权限控制,可以在模板中添加 @PreAuthorize 注解。

#parse("fileHeader.java.vm")

package ${package.controller};

import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

@RestController
@RequestMapping("/api/${moduleName}/${className}")
public class ${className}Controller {

    @Autowired
    private ${className}Service ${serviceVarName};

    /**
     * 获取所有记录 (需要管理员权限)
     */
    @GetMapping
    @PreAuthorize("hasRole('ADMIN')")
    public Page<${className}> getAll() {
        return ${serviceVarName}.page(new Page<>());
    }

    /**
     * 根据 ID 获取记录 (需要查看权限)
     */
    @GetMapping("/{id}")
    @PreAuthorize("hasPermission(#id, '${className}', 'READ')")
    public ${className} getById(@PathVariable Long id) {
        return ${serviceVarName}.getById(id);
    }

    /**
     * 新增记录 (需要创建权限)
     */
    @PostMapping
    @PreAuthorize("hasPermission(null, '${className}', 'CREATE')")
    public ${className} create(@RequestBody ${className} entity) {
        return ${serviceVarName}.save(entity);
    }

    /**
     * 更新记录 (需要更新权限)
     */
    @PutMapping("/{id}")
    @PreAuthorize("hasPermission(#id, '${className}', 'UPDATE')")
    public ${className} update(@PathVariable Long id, @RequestBody ${className} entity) {
        entity.setId(id);
        return ${serviceVarName}.updateById(entity);
    }

    /**
     * 删除记录 (需要删除权限)
     */
    @DeleteMapping("/{id}")
    @PreAuthorize("hasPermission(#id, '${className}', 'DELETE')")
    public boolean delete(@PathVariable Long id) {
        return ${serviceVarName}.removeById(id);
    }
}

在这个模板中,我们为每个 API 方法添加了 @PreAuthorize 注解,指定了所需的权限。hasRole('ADMIN') 表示只有管理员角色才能访问该 API,而 hasPermission(#id, '${className}', 'READ') 表示只有拥有查看权限的用户才能访问该 API。你可以根据项目的实际需求调整权限控制逻辑。

2. 配置权限控制

为了让 @PreAuthorize 注解生效,我们需要在 Spring Security 配置类中启用权限控制。你可以在 SecurityConfig 类中添加以下配置:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/api/**").authenticated() // 所有 API 需要认证
                .and()
            .httpBasic(); // 使用 Basic 认证
    }
}

@EnableGlobalMethodSecurity(prePostEnabled = true) 启用了方法级别的权限控制,prePostEnabled = true 允许使用 @PreAuthorize 注解。HttpSecurity 配置了 API 的访问权限,所有 /api/** 路径都需要经过认证。

3. 测试生成的 API

完成配置后,你可以运行代码生成器,生成带有权限控制的 API。生成的 API 将自动包含权限控制注解,确保只有具有相应权限的用户才能访问。你可以使用 Postman 或其他工具测试生成的 API,验证权限控制是否生效。

总结与展望

通过本文的学习,我们深入了解了 MyBatis Plus 代码生成器的配置与自定义模板。从基础配置到高级定制,我们掌握了如何根据项目需求生成更加符合规范、更具可读性和可维护性的代码。无论是修改现有模板,还是添加新的模板文件,甚至是结合权限控制生成带有安全性的 API,MyBatis Plus 代码生成器都为我们提供了极大的灵活性和便利性。

在未来的工作中,随着项目的复杂度不断增加,代码生成器将成为我们提高开发效率的重要工具。通过不断优化代码生成器的配置和模板,我们可以更好地应对各种开发场景,确保代码的质量和一致性。希望本文的内容能够帮助你在实际项目中灵活运用 MyBatis Plus 代码生成器,提升开发效率,享受编程的乐趣。

如果你有任何疑问或建议,欢迎在评论区留言讨论。祝你在编程的道路上越走越远,代码越来越优雅!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注