在 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 准备工作
创建 Spring Boot 项目: 可以使用 Spring Initializr (start.spring.io) 创建一个 Spring Boot 项目,并添加必要的依赖,如 spring-boot-starter-web
、spring-boot-starter-jdbc
、mysql-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>
配置数据库连接: 在 application.properties
或 application.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
创建数据库表: 假设你有一个 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
下看到生成的 model
和 mapper
包,以及 src/main/resources/mapper
下的 XML 文件。
1.5 集成到 Spring Boot 项目
在 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);
}
}
编写 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 准备工作
创建 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>
配置数据库连接: 同 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 项目
在 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);
}
}
配置 MyBatis-Plus: 在 application.properties
或 application.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
使用生成的代码: 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 应用来运行,以避免将其生成的文件混入到主项目的版本控制中。生成后,再将所需文件复制到主项目中。
希望这个详细的指南对你有所帮助!