Java MyBatis 代码生成与示例

发布时间: 更新时间: 总字数:3419 阅读时间:7m 作者: IP上海 分享 网址

在 Spring Boot 项目中,结合 MyBatis 进行数据库相关代码的自动生成,最常用的工具是 MyBatis Generator。此外,MyBatis-Plus 也提供了强大的代码生成器 AutoGenerator,功能更为丰富。

1. 使用 MyBatis Generator 自动生成代码

MyBatis Generator (MBG) 是 MyBatis 官方提供的一个代码生成器,它可以根据数据库表结构自动生成以下文件:

  • 实体类 (Model/Entity):对应数据库表中的字段。
  • Mapper 接口 (DAO/Mapper):包含 CRUD 操作的方法定义。
  • Mapper XML 文件 (SQL Mapping File):包含实际的 SQL 语句。
  • Example 类 (Optional):用于构建复杂的动态查询条件。

1.1 准备工作

  1. 创建 Spring Boot 项目: 可以使用 Spring Initializr (start.spring.io) 创建一个 Spring Boot 项目,并添加必要的依赖,如 spring-boot-starter-webspring-boot-starter-jdbcmysql-connector-java (或其他数据库驱动)、mybatis-spring-boot-starter

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.3</version> </dependency>
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.4.2</version> <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
  2. 配置数据库连接: 在 application.propertiesapplication.yml 中配置数据库连接信息。

    # application.properties
    spring.datasource.url=jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    spring.datasource.username=your_username
    spring.datasource.password=your_password
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    
  3. 创建数据库表: 假设你有一个 user 表:

    CREATE TABLE `user` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(50) NOT NULL,
      `email` varchar(100) DEFAULT NULL,
      `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    

1.2 配置 MyBatis Generator Maven 插件

pom.xml 中添加 MyBatis Generator Maven 插件:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <excludes>
                    <exclude>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                    </exclude>
                </excludes>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.4.2</version> <configuration>
                <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
                <overwrite>true</overwrite>
                <verbose>true</verbose>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>${mysql.version}</version> </dependency>
                </dependencies>
        </plugin>
    </plugins>
</build>

<properties>
    <java.version>17</java.version>
    <mysql.version>8.0.28</mysql.version> </properties>

1.3 编写 generatorConfig.xml

src/main/resources 目录下创建 generatorConfig.xml 文件,这是 MyBatis Generator 的核心配置文件。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <properties resource="application.properties"/>

    <context id="MySqlContext" targetRuntime="MyBatis3Simple" defaultModelType="flat">
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <property name="addRemarkComments" value="true"/>
        </commentGenerator>

        <jdbcConnection driverClass="${spring.datasource.driver-class-name}"
                        connectionURL="${spring.datasource.url}"
                        userId="${spring.datasource.username}"
                        password="${spring.datasource.password}">
        </jdbcConnection>

        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>

        <javaModelGenerator targetPackage="com.example.demo.model" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>

        <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>

        <javaClientGenerator type="XMLMAPPER" targetPackage="com.example.demo.mapper" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <table tableName="user" domainObjectName="User"
               enableCountByExample="false"
               enableUpdateByExample="false"
               enableDeleteByExample="false"
               enableSelectByExample="false"
               enableSelectByPrimaryKey="true"
               enableInsert="true"
               enableUpdateByPrimaryKey="true"
               selectAll="true">
            </table>

        </context>
</generatorConfiguration>

配置说明:

  • <properties resource="application.properties"/>: 引入 Spring Boot 的配置文件,这样可以直接使用 application.properties 中定义的数据库连接信息。
  • <context>: 定义一个生成上下文。
    • id: 上下文的唯一标识。
    • targetRuntime: 指定生成代码的目标运行时环境,MyBatis3Simple 生成的 Mapper 接口中方法会少一些,MyBatis3 会生成包含 Example 类的完整 CRUD 方法。
    • defaultModelType="flat": flat 模型不会生成独立的主键类和 BLOB 字段类,所有字段都在一个实体类中。
  • <commentGenerator>: 控制生成的代码中的注释。
  • <jdbcConnection>: 数据库连接配置。
  • <javaModelGenerator>: 实体类的生成配置,包括目标包和目标项目路径。
  • <sqlMapGenerator>: Mapper XML 文件的生成配置。
  • <javaClientGenerator>: Mapper 接口的生成配置。type="XMLMAPPER" 表示生成接口和对应的 XML 文件。
  • <table>: 最重要的配置,指定要生成代码的数据库表。你可以控制为每张表生成哪些类型的操作方法。

1.4 执行代码生成

在项目根目录打开命令行,执行 Maven 命令:

mvn mybatis-generator:generate

执行成功后,你会在 src/main/java 下看到生成的 modelmapper 包,以及 src/main/resources/mapper 下的 XML 文件。

1.5 集成到 Spring Boot 项目

  1. 在 Spring Boot 主类上添加 @MapperScan 注解: 扫描 Mapper 接口。

    package com.example.demo;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    @MapperScan("com.example.demo.mapper") // 扫描 Mapper 接口所在的包
    public class DemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    
    }
    
  2. 编写 Service 和 Controller 层: 调用生成的 Mapper 接口进行数据库操作。

    // com.example.demo.service.UserService.java
    package com.example.demo.service;
    
    import com.example.demo.mapper.UserMapper;
    import com.example.demo.model.User;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    @Service
    public class UserService {
    
        private final UserMapper userMapper;
    
        public UserService(UserMapper userMapper) {
            this.userMapper = userMapper;
        }
    
        public User getUserById(Integer id) {
            return userMapper.selectByPrimaryKey(id);
        }
    
        public List<User> getAllUsers() {
            // Mybatis Generator 默认生成的 selectAll 方法 (如果没有禁用Example查询)
            // 如果使用了 MyBatis3Simple 或禁用了 Example, 可能需要手动添加一个selectAll方法到Mapper接口和XML中
            // 这里假设你的 generatorConfig.xml 配置了 selectAll="true" 并且生成了相应的方法
             return userMapper.selectAll(); // 或者使用 selectByExample(new UserExample())
        }
    
        public int addUser(User user) {
            return userMapper.insert(user);
        }
    
        public int updateUser(User user) {
            return userMapper.updateByPrimaryKey(user);
        }
    
        public int deleteUser(Integer id) {
            return userMapper.deleteByPrimaryKey(id);
        }
    }
    
    // com.example.demo.controller.UserController.java
    package com.example.demo.controller;
    
    import com.example.demo.model.User;
    import com.example.demo.service.UserService;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.List;
    
    @RestController
    @RequestMapping("/users")
    public class UserController {
    
        private final UserService userService;
    
        public UserController(UserService userService) {
            this.userService = userService;
        }
    
        @GetMapping("/{id}")
        public ResponseEntity<User> getUserById(@PathVariable Integer id) {
            User user = userService.getUserById(id);
            return user != null ? ResponseEntity.ok(user) : ResponseEntity.notFound().build();
        }
    
        @GetMapping
        public List<User> getAllUsers() {
            return userService.getAllUsers();
        }
    
        @PostMapping
        public ResponseEntity<String> addUser(@RequestBody User user) {
            int result = userService.addUser(user);
            return result > 0 ? ResponseEntity.ok("User added successfully") : ResponseEntity.badRequest().body("Failed to add user");
        }
    
        @PutMapping("/{id}")
        public ResponseEntity<String> updateUser(@PathVariable Integer id, @RequestBody User user) {
            user.setId(id); // 确保ID设置正确
            int result = userService.updateUser(user);
            return result > 0 ? ResponseEntity.ok("User updated successfully") : ResponseEntity.badRequest().body("Failed to update user");
        }
    
        @DeleteMapping("/{id}")
        public ResponseEntity<String> deleteUser(@PathVariable Integer id) {
            int result = userService.deleteUser(id);
            return result > 0 ? ResponseEntity.ok("User deleted successfully") : ResponseEntity.badRequest().body("Failed to delete user");
        }
    }
    

2. 使用 MyBatis-Plus AutoGenerator (推荐)

MyBatis-Plus 是 MyBatis 的增强工具包,它在 MyBatis 的基础上做了很多增强,包括更简化的 CRUD 操作、分页插件、以及强大的代码生成器 AutoGenerator。它能生成 Controller、Service、Mapper、Entity、Mapper XML 等更多层级的代码。

2.1 准备工作

  1. 创建 Spring Boot 项目: 同上,但依赖需要改为 MyBatis-Plus。

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.6</version> </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.3.1</version> </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.32</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
  2. 配置数据库连接: 同 MyBatis Generator 配置。

2.2 编写代码生成器

MyBatis-Plus 的 AutoGenerator 是通过 Java 代码来配置和执行的。创建一个独立的类来运行生成器,例如 CodeGenerator.java

package com.example.demo; // 确保这个包名在你项目之外,或者是一个独立的工具类包

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.fill.Column;

import java.util.Collections;

public class CodeGenerator {

    public static void main(String[] args) {
        // 1. 代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 2. 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir"); // 获取项目根路径
        gc.setOutputDir(projectPath + "/src/main/java"); // 生成文件的输出目录
        gc.setAuthor("YourName"); // 作者
        gc.setOpen(false); // 是否打开输出目录
        gc.setSwagger2(true); // 实体属性 Swagger API 注解
        gc.setServiceName("%sService"); // Service 层接口名称,去掉 I 前缀
        gc.setDateType(DateType.TIME_PACK); // 日期类型用 java.util.Date 或 java.time 包

        // 自定义文件命名,注意 %s 会自动填充表名
        gc.setEntityName("%s"); // 实体类名
        gc.setMapperName("%sMapper"); // Mapper 接口名
        gc.setXmlName("%sMapper"); // Mapper XML 文件名
        gc.setControllerName("%sController"); // Controller 类名

        mpg.setGlobalConfig(gc);

        // 3. 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("your_username");
        dsc.setPassword("your_password");
        // 数据库类型,默认为 MySql
        dsc.setDbQuery(new MySqlQuery());
        dsc.setTypeConvert(new MySqlTypeConvert());

        mpg.setDataSource(dsc);

        // 4. 包配置
        PackageConfig pc = new PackageConfig();
        // pc.setModuleName("sys"); // 模块名,会在包路径下再加一层,例如 com.example.demo.sys.entity
        pc.setParent("com.example.demo"); // 父包名
        pc.setController("controller");
        pc.setService("service");
        pc.setMapper("mapper");
        pc.setEntity("entity");
        pc.setXml("mapper.xml"); // Mapper XML 文件所在的包名

        mpg.setPackageInfo(pc);

        // 5. 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel); // 数据库表名下划线转驼峰命名
        strategy.setColumnNaming(NamingStrategy.underline_to_camel); // 数据库字段名下划线转驼峰命名
        // strategy.setSuperEntityClass("com.example.demo.BaseEntity"); // 如果有公共父类,可以设置
        strategy.setEntityLombokModel(true); // 实体类使用 Lombok 注解
        strategy.setRestControllerStyle(true); // Controller 生成 @RestController
        // strategy.setSuperControllerClass("com.example.demo.BaseController"); // 如果有公共父类,可以设置

        strategy.setInclude("user"); // 需要生成代码的表名,可以传入多个表名
        // strategy.setExclude("表名1", "表名2"); // 排除表名
        // strategy.setTablePrefix("t_", "mp_"); // 表前缀,生成实体类时会去除
        strategy.setControllerMappingHyphenStyle(true); // url 中驼峰转连字符
        strategy.setTableFillList(Collections.singletonList(
                new Column("created_at", FieldFill.INSERT) // 自动填充字段,例如创建时间
                // new Column("updated_at", FieldFill.INSERT_UPDATE) // 更新时间
        ));
        // strategy.setLogicDeleteFieldName("deleted"); // 逻辑删除字段名 (MyBatis-Plus 特性)

        mpg.setStrategy(strategy);

        // 6. 模板引擎配置 (可选,默认为 Velocity,你也可以配置 Freemarker)
        // mpg.setTemplateEngine(new FreemarkerTemplateEngine()); // 如果使用 Freemarker

        // 执行生成
        mpg.execute();
    }
}

配置说明:

  • GlobalConfig: 全局配置,如作者、输出目录、是否开启 Swagger 注解、Service 名称格式等。
  • DataSourceConfig: 数据库连接配置。
  • PackageConfig: 包名配置,指定不同层级代码(Controller、Service、Mapper、Entity)的包路径。
  • StrategyConfig: 策略配置,最重要的部分,定义了表名、字段命名策略、是否使用 Lombok、是否生成 RESTful Controller 等。
    • setInclude("user"): 指定需要生成代码的表名,可以传入多个。
    • setTablePrefix("t_"): 如果表名有前缀,例如 t_user,设置后生成的实体类就是 User
    • setEntityLombokModel(true): 推荐使用 Lombok,可以大大简化实体类的代码。
    • setTableFillList: 配置自动填充字段,例如创建时间、更新时间。
  • TemplateEngine: 模板引擎配置,MyBatis-Plus 支持 Velocity (默认)、Freemarker、Beetl。

2.3 执行代码生成

直接运行 CodeGenerator 类中的 main 方法即可生成代码。

2.4 集成到 Spring Boot 项目

  1. 在 Spring Boot 主类上添加 @MapperScan 注解:

    package com.example.demo;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    @MapperScan("com.example.demo.mapper") // 扫描 Mapper 接口所在的包
    public class DemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    
    }
    
  2. 配置 MyBatis-Plus: 在 application.propertiesapplication.yml 中配置 MyBatis-Plus。

    # application.properties
    mybatis-plus.mapper-locations=classpath*:/mapper/**/*.xml
    mybatis-plus.type-aliases-package=com.example.demo.entity # 实体类包名
    # 配置驼峰命名转换
    mybatis-plus.configuration.map-underscore-to-camel-case=true
    
  3. 使用生成的代码: MyBatis-Plus 生成的 Mapper 接口会继承 BaseMapper<T>,拥有丰富的 CRUD 方法,Service 接口会继承 IService<T>,Service 实现类会继承 ServiceImpl<M, T>

    // com.example.demo.entity.User.java (Lombok 注解)
    package com.example.demo.entity;
    
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableField;
    import com.baomidou.mybatisplus.annotation.TableId;
    import com.baomidou.mybatisplus.annotation.TableName;
    import lombok.Data;
    
    import java.io.Serializable;
    import java.util.Date;
    
    @Data
    @TableName("user") // 对应数据库表名
    public class User implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @TableId(value = "id", type = IdType.AUTO) // 主键,自增
        private Integer id;
    
        private String username;
    
        private String email;
    
        @TableField("created_at")
        private Date createdAt;
    }
    
    // com.example.demo.mapper.UserMapper.java
    package com.example.demo.mapper;
    
    import com.baomidou.mybatisplus.core.mapper.BaseMapper;
    import com.example.demo.entity.User;
    import org.apache.ibatis.annotations.Mapper; // 也可以使用 @Mapper
    
    @Mapper
    public interface UserMapper extends BaseMapper<User> {
        // BaseMapper 提供了丰富的 CRUD 方法,例如 insert, selectById, selectList 等
        // 你也可以在此添加自定义的方法
    }
    
    // com.example.demo.service.UserService.java
    package com.example.demo.service;
    
    import com.baomidou.mybatisplus.extension.service.IService;
    import com.example.demo.entity.User;
    
    public interface UserService extends IService<User> {
        // IService 提供了更高级的业务方法
    }
    
    // com.example.demo.service.impl.UserServiceImpl.java
    package com.example.demo.service.impl;
    
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.example.demo.entity.User;
    import com.example.demo.mapper.UserMapper;
    import com.example.demo.service.UserService;
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
        // ServiceImpl 实现了 IService 的大部分方法
        // 如果需要,你可以在这里实现自定义的业务逻辑
    }
    
    // com.example.demo.controller.UserController.java
    package com.example.demo.controller;
    
    import com.example.demo.entity.User;
    import com.example.demo.service.UserService;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.beans.factory.annotation.Autowired;
    import java.util.List;
    
    @RestController
    @RequestMapping("/user") // 通常会根据实体类名自动生成
    public class UserController {
    
        @Autowired
        private UserService userService;
    
        @GetMapping("/{id}")
        public User getById(@PathVariable Integer id) {
            return userService.getById(id);
        }
    
        @GetMapping("/list")
        public List<User> list() {
            return userService.list(); // 获取所有用户
        }
    
        @PostMapping
        public boolean save(@RequestBody User user) {
            return userService.save(user);
        }
    
        @PutMapping
        public boolean update(@RequestBody User user) {
            return userService.updateById(user);
        }
    
        @DeleteMapping("/{id}")
        public boolean delete(@PathVariable Integer id) {
            return userService.removeById(id);
        }
    }
    

总结与建议

  • MyBatis Generator:适用于只生成基础的 Model、Mapper 接口和 XML 文件的场景,配置通过 XML 文件进行,相对传统。
  • MyBatis-Plus AutoGenerator:功能更强大,可以生成 Controller、Service 等多层代码,且通过 Java 代码配置,更灵活。推荐在新的 Spring Boot + MyBatis 项目中使用 MyBatis-Plus,它能大幅提高开发效率。

无论选择哪种方式,自动生成代码都能帮助你快速构建基础的 CRUD 功能,让你专注于业务逻辑的开发。记得在生成代码后,根据实际需求进行调整和扩展。

在实际项目中,你可能会将代码生成器作为单独的 Maven 模块或者一个独立的 Java 应用来运行,以避免将其生成的文件混入到主项目的版本控制中。生成后,再将所需文件复制到主项目中。

希望这个详细的指南对你有所帮助!

Home Archives Categories Tags Statistics
本文总阅读量 次 本站总访问量 次 本站总访客数