MyBatis-Plus(简称 MP)是一个基于 MyBatis 的增强工具,在 MyBatis 的基础上实现了自动化 CRUD 操作,极大地简化了开发工作量。以下将从其核心功能、特性及使用场景等方面进行详细介绍:
一、核心功能与特性
1. 代码生成器(Code Generator)
- 功能:自动生成 Entity、Mapper、Service、Controller 等基础代码,减少重复开发。
- 优势:可通过配置数据库表结构,一键生成符合项目规范的代码,支持自定义模板(如注释格式、包路径等)。
- 示例配置:
@SpringBootApplication
public class MyBatisPlusApplication {
public static void main(String[] args) {
SpringApplication.run(MyBatisPlusApplication.class, args);
}
// 代码生成器配置(通常在配置类中)
@Bean
public CodeGenerator codeGenerator() {
CodeGenerator generator = new CodeGenerator();
generator.setDataSource(new DataSourceConfig()
.setUrl("jdbc:mysql://localhost:3306/test")
.setDriverName("com.mysql.cj.jdbc.Driver")
.setUsername("name")//自己的
.setPassword("pwd"));
generator.setStrategy(new StrategyConfig()
.setInclude("user", "order")); // 生成指定表的代码
return generator;
}
}
public class FastAutoGeneratorTest {
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://localhost:3306/mp?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8&useSSL=false", "name", "pwd")//自己的
.globalConfig(builder -> {
builder.author("xxx") // 设置作者
//.enableSwagger() // 开启 swagger 模式
.fileOverride() // 覆盖已生成文件
.outputDir("D://mp"); // 指定输出目录
})
.packageConfig(builder -> {
builder.parent("com.xxx") // 设置父包名,即公司名
.moduleName("mp") // 设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, "D://mp")); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.addInclude() // 设置需要生成的表名,不写参数代表数据库下的所有表,写参数如"user"代表user表
.addTablePrefix("tb_", "cb_") // 设置过滤表前缀
.controllerBuilder().enableRestStyle()
.serviceBuilder().formatServiceFileName("%sService").formatServiceImplFileName("%sServiceImpl");
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}
}
扩展
代码对比分析
1. 版本差异
- 第一段代码:使用的是MyBatis-Plus 3.4.3 及以下版本的
CodeGenerator
(旧版 API)。 - 第二段代码:使用的是MyBatis-Plus 3.5.0 及以上版本的
FastAutoGenerator
(新版 API)。
2. 核心功能对比
功能点 | CodeGenerator(旧版) | FastAutoGenerator(新版) |
---|---|---|
数据源配置 | 需显式创建DataSourceConfig 对象 | 链式调用直接配置 URL、用户名、密码 |
表选择策略 | setInclude("user", "order") 指定表名 | addInclude() 支持可变参数或无参(生成所有表) |
包路径配置 | 无明确模块化配置 | packageConfig 支持父包名、模块名、自定义路径映射 |
文件输出控制 | 无明确覆盖选项 | fileOverride() 支持覆盖已生成文件 |
模板引擎 | 默认使用 Velocity | 默认使用 Velocity,可切换为 Freemarker(.templateEngine() ) |
代码风格 | 需手动配置 | 内置enableRestStyle() 生成 RestController 风格代码 |
命名策略 | 无明确支持 | formatServiceFileName 等方法自定义文件命名 |
3. 代码结构与易用性
-
旧版(CodeGenerator) :
- 结构较分散,需创建多个配置对象(如
DataSourceConfig
、StrategyConfig
)。 - 配置项较少,灵活性较低,但适合快速上手。
- 结构较分散,需创建多个配置对象(如
-
新版(FastAutoGenerator) :
- 采用链式调用,代码更简洁流畅。
- 功能更丰富,支持更多自定义选项(如 Swagger 注解、Rest 风格、自定义命名)。
- 推荐使用,尤其是 MyBatis-Plus 3.5.x 及以上版本。
4. 示例差异点
-
表选择:
- 旧版:
setInclude("user", "order")
- 新版:
addInclude()
(无参时生成所有表,或传入表名)
- 旧版:
-
输出路径:
- 旧版:未显式配置,默认输出到项目路径。
- 新版:
outputDir("D://mp")
和pathInfo()
可精确控制各文件输出位置。
-
命名策略:
- 旧版:使用默认命名(如
UserServiceImpl
)。 - 新版:可通过
formatServiceFileName("%sService")
自定义。
- 旧版:使用默认命名(如
5. 最佳实践建议
-
优先使用新版 API:
FastAutoGenerator
提供了更现代的 API 设计和更丰富的功能。 -
升级注意事项:
- 若项目已使用旧版
CodeGenerator
,升级后需迁移至FastAutoGenerator
。 - 注意依赖版本兼容(MyBatis-Plus 3.5.x 需匹配对应版本的模板引擎)。
- 若项目已使用旧版
2. 通用 Mapper(BaseMapper)
-
核心接口:
BaseMapper<T>
提供通用 CRUD 方法,无需手动编写 SQL。 -
支持方法:
insert(T entity)
:插入单条记录deleteById(Serializable id)
:根据 ID 删除updateById(T entity)
:根据 ID 更新selectById(Serializable id)
:根据 ID 查询selectList(Wrapper<T> queryWrapper)
:条件查询列表
-
示例:
// UserMapper接口继承BaseMapper
public interface UserMapper extends BaseMapper<User> {
// 自定义方法可在此扩展,无需实现通用CRUD
}
3. 条件构造器(Wrapper)
-
作用:以面向对象的方式构建 SQL 查询条件,避免手写 SQL 字符串。
-
核心类:
QueryWrapper<T>
:查询条件构造器UpdateWrapper<T>
:更新条件构造器LambdaQueryWrapper<T>
:Lambda 表达式风格构造器(推荐使用,避免字符串硬编码)
-
示例:
// 查询年龄>18且姓名包含"张"的用户,按年龄降序排列
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
.gt(User::getAge, 18)
.like(User::getName, "张")
.orderByDesc(User::getAge);
List<User> userList = userMapper.selectList(wrapper);
4. 分页插件(Pagination)
-
功能:支持物理分页,自动生成分页 SQL,兼容多种数据库(MySQL、Oracle 等)。
-
使用方式:
- 配置分页插件(如
MybatisPlusInterceptor
) - 调用
selectPage(Page<T> page, Wrapper<T> queryWrapper)
方法
- 配置分页插件(如
-
示例:
// 配置分页插件(通常在MyBatis配置类中)
@Configuration
public class MyBatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
// 业务代码中使用分页
Page<User> page = new Page<>(1, 10); // 第1页,每页10条
userMapper.selectPage(page, null);
long total = page.getTotal(); // 总记录数
List<User> records = page.getRecords(); // 当前页数据
5. 自动填充(MetaObjectHandler)
-
场景:自动填充创建时间、更新时间、创建人、更新人等公共字段。
-
实现方式:
- 实现
MetaObjectHandler
接口 - 在 Entity 中使用
@TableField(fill = FieldFill.INSERT)
等注解标记字段
- 实现
-
示例:
// 实体类字段标记
public class User {
private Long id;
private String name;
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
// getter/setter省略
}
// 自动填充处理器
@Component
public class MetaObjectHandlerImpl implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
setFieldValByName("createTime", new Date(), metaObject);
setFieldValByName("updateTime", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
setFieldValByName("updateTime", new Date(), metaObject);
}
}
6. 乐观锁(OptimisticLocker)
-
作用:解决并发更新时的数据竞争问题,通过版本号(version)实现。
-
使用步骤:
- 表中添加
version
字段 - 实体类中使用
@Version
注解标记 - 配置乐观锁插件
- 表中添加
-
示例:
// 实体类字段标记
public class User {
private Long id;
private String name;
@Version
private Integer version;
// 其他字段省略
}
// 配置乐观锁插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
二、核心扩展功能
1. 逻辑删除(LogicDelete)
-
原理:通过标记字段(如
deleted
)实现数据软删除,查询时自动过滤已删除记录。 -
使用方式:
- 表中添加
deleted
字段(类型通常为int
或boolean
) - 实体类中使用
@TableLogic
注解标记 - 配置逻辑删除插件
- 表中添加
-
示例:
// 实体类字段标记
public class User {
private Long id;
private String name;
@TableLogic
private Integer deleted; // 0未删除,1已删除
// 其他字段省略
}
// 配置逻辑删除插件(全局配置中)
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new LogicSqlInjector());
return interceptor;
}
}
2. 主键生成策略(IdGenerator)
-
支持策略:
AUTO
:数据库自增(如 MySQL 的AUTO_INCREMENT
)INPUT
:手动输入ASSIGN_ID
:MP 提供的雪花算法(默认,生成 19 位长整型 ID,全局唯一)ASSIGN_UUID
:生成 32 位 UUID
-
示例:
public class User {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
// 其他字段省略
}
3. 自定义 SQL 注入器(SqlInjector)
- 场景:扩展
BaseMapper
的通用方法,或自定义全局 SQL 逻辑。 - 示例:添加自定义通用方法
selectByStatus
:
public class CustomSqlInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
List<AbstractMethod> methodList = super.getMethodList(mapperClass);
methodList.add(new SelectByStatus()); // 添加自定义方法
return methodList;
}
}
// 自定义方法实现
public class SelectByStatus extends AbstractMethod {
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
String sql = "SELECT * FROM " + tableInfo.getTableName() + " WHERE status = #{status}";
SqlSource sqlSource = new RawSqlSource(configuration, sql, modelClass);
return this.addSelectMappedStatementForOther(mapperClass, "selectByStatus", sqlSource, modelClass);
}
}
三、核心架构与原理
1. 插件机制(Interceptor)
- 核心类:
MybatisPlusInterceptor
,通过责任链模式加载各类插件(分页、乐观锁、逻辑删除等)。 - 原理:基于 MyBatis 的拦截器(Interceptor)机制,在 SQL 执行前对 SQL 进行改写或增强。
2. SQL 解析与生成
-
核心组件:
SqlBuilder
:构建基础 SQL 片段(如SELECT
、WHERE
)Wrapper
:将条件转换为 SQL 参数MetaObjectHandler
:处理字段填充逻辑
-
优势:避免手写 SQL,减少 SQL 注入风险,同时保持 MyBatis 的灵活性。
四、应用场景与优势
1. 适用场景
- 中小型项目:快速开发,减少 CRUD 代码量。
- 大型项目:统一数据访问层规范,便于团队协作。
- 复杂查询场景:结合 MyBatis 原生 SQL,灵活扩展功能。
2. 核心优势
- 效率提升:自动生成代码,通用 CRUD 无需手写 SQL。
- 代码简洁:减少 XML 配置或注解,提升代码可读性。
- 兼容性强:完全兼容 MyBatis,可无缝集成现有 MyBatis 项目。
- 生态丰富:支持 Spring Boot、Spring Cloud 等主流框架,社区活跃。
五、快速入门示例
1. 添加依赖
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version> <!-- 最新版本可查询MP官网 -->
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
</dependencies>
2. 配置文件(application.yml)
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8
username: root
password: 123456
mybatis-plus:
mapper-locations: classpath:mapper/*.xml # Mapper.xml路径
type-aliases-package: com.example.entity # 实体类包路径
configuration:
map-underscore-to-camel-case: true # 驼峰命名转换
3. 实体类与 Mapper
// 实体类
@Data
@TableName("user")
public class User {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
private String name;
private Integer age;
private String email;
}
// Mapper接口
public interface UserMapper extends BaseMapper<User> {
// 可扩展自定义方法
}
4. 服务层与控制器
// Service接口(继承IService)
public interface UserService extends IService<User> {
// 扩展业务方法
}
// Service实现类(继承ServiceImpl)
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
// 实现业务方法
}
// 控制器
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/list")
public List<User> list() {
return userService.list();
}
@PostMapping("/save")
public boolean save(@RequestBody User user) {
return userService.save(user);
}
}
总结
MyBatis-Plus 通过自动化 CRUD、条件构造器、代码生成器等核心功能,大幅提升了开发效率,同时保持了 MyBatis 的灵活性。其核心设计思想是 “约定大于配置”,适合各类 Java 项目中简化数据访问层的开发。如果需要更复杂的 SQL 操作,仍可结合 MyBatis 原生 XML 或注解实现,真正做到 “零侵入性” 扩展。