前言
作为一名开发者,数据库操作是我们日常工作中不可或缺的部分。传统的MyBatis虽然强大,但需要编写大量XML映射文件,这在快速开发的今天显得效率不足。MyBatis-Plus(简称MP)作为MyBatis的增强工具,在保留MyBatis所有特性的基础上,极大地简化了开发流程。本文将带你全面了解如何在SpringBoot项目中整合MyBatis-Plus,实现零XML配置的高效CRUD操作。
一、MyBatis-Plus简介:JPA vs MyBatis vs MyBatis-Plus
在开始整合之前,我们先了解下这三种持久层框架的特点和差异:
特性 | JPA | MyBatis | MyBatis-Plus |
---|---|---|---|
ORM支持 | 全自动ORM | 半自动ORM | MyBatis增强 |
SQL控制 | 自动生成,可控性低 | 完全手动控制 | 自动生成+手动控制 |
XML配置 | 无 | 需要大量XML | 零XML |
CRUD操作 | 方法命名自动生成 | 需手动编写 | 内置通用Mapper |
学习曲线 | 中等 | 较高 | 低(MyBatis基础上) |
适用场景 | 简单标准业务 | 复杂SQL业务 | 各种业务场景 |
MyBatis-Plus的核心优势:
-
无侵入:只做增强不做改变,引入它不会对现有工程产生影响
-
损耗小:启动即会自动注入基本CRUD,性能基本无损耗
-
强大CRUD:内置通用Mapper、通用Service,少量配置即可实现单表大部分CRUD操作
-
多种插件:支持分页、性能分析、乐观锁、逻辑删除等
二、SpringBoot整合MyBatis-Plus
1. 添加依赖
首先在pom.xml
中添加必要依赖:
XML
<!-- SpringBoot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis-Plus Starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<!-- 数据库驱动(以MySQL为例) -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Lombok简化实体类开发 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
2. 配置数据库连接
在application.yml
中配置数据源和MyBatis-Plus相关配置:
XML
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mp_demo?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: 123456
mybatis-plus:
configuration:
# 下划线转驼峰
map-underscore-to-camel-case: true
# 日志实现
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
# 主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID", ID_WORKER:"全局唯一ID", UUID:"全局唯一UUID"
id-type: auto
# 逻辑删除字段名
logic-delete-field: deleted
# 逻辑删除值
logic-delete-value: 1
# 逻辑未删除值
logic-not-delete-value: 0
三、实体类注解详解
MyBatis-Plus通过注解简化了实体类与数据库表的映射关系:
java
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.util.Date;
@Data
@TableName("t_user") // 指定表名,省略时默认使用类名作为表名
public class User {
@TableId(type = IdType.AUTO) // 主键自增
private Long id;
private String username;
private String password;
@TableField("real_name") // 指定数据库字段名
private String realName;
private Integer age;
private String email;
@TableField(fill = FieldFill.INSERT) // 插入时自动填充
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE) // 插入和更新时自动填充
private Date updateTime;
@Version // 乐观锁版本字段
private Integer version;
@TableLogic // 逻辑删除字段
private Integer deleted;
}
常用注解说明:
-
@TableName
:指定实体类对应的表名 -
@TableId
:指定主键字段,可配置主键生成策略 -
@TableField
:指定非主键字段与数据库列的映射关系 -
@Version
:乐观锁注解 -
@TableLogic
:逻辑删除注解
四、Mapper接口与Service层开发
1. 创建Mapper接口
java
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.User;
public interface UserMapper extends BaseMapper<User> {
// 继承BaseMapper后已包含基本CRUD方法
// 可在此添加自定义SQL方法
}
2. Service层实现
MyBatis-Plus提供了通用的Service接口:
java
public interface UserService extends IService<User> {
// 可扩展自定义方法
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
// 实现类只需继承ServiceImpl即可
}
3. 基础CRUD示例
java
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
// 新增
@PostMapping
public boolean save(@RequestBody User user) {
return userService.save(user);
}
// 删除
@DeleteMapping("/{id}")
public boolean remove(@PathVariable Long id) {
return userService.removeById(id);
}
// 修改
@PutMapping
public boolean update(@RequestBody User user) {
return userService.updateById(user);
}
// 查询单个
@GetMapping("/{id}")
public User getById(@PathVariable Long id) {
return userService.getById(id);
}
// 分页查询
@GetMapping("/page")
public IPage<User> page(@RequestParam(defaultValue = "1") Integer current,
@RequestParam(defaultValue = "10") Integer size) {
return userService.page(new Page<>(current, size));
}
}
五、高级功能实战
1. 分页插件配置
MyBatis-Plus的分页功能需要先配置分页插件:
java
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
使用示例:
java
// 基本分页
Page<User> page = new Page<>(1, 10); // 当前页,每页大小
userMapper.selectPage(page, null);
// 自定义SQL分页
@Select("SELECT * FROM t_user WHERE age > #{age}")
IPage<User> selectPageByAge(IPage<User> page, @Param("age") Integer age);
2. 自动填充功能
实现MetaObjectHandler
接口来处理自动填充字段:
java
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
}
}
3. 条件构造器Wrapper
MyBatis-Plus提供了强大的条件构造器,可以构建复杂查询条件:
java
// 查询年龄大于18且名字包含"张"的用户
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.gt(User::getAge, 18)
.like(User::getUsername, "张");
List<User> users = userMapper.selectList(wrapper);
// 更新操作
LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(User::getUsername, "张三")
.set(User::getAge, 25);
userMapper.update(null, updateWrapper);
4. 逻辑删除配置
在application.yml
中已经配置了逻辑删除,实体类字段添加@TableLogic
注解后,删除操作将自动变为更新操作:
java
// 实际执行的是UPDATE t_user SET deleted=1 WHERE id=? AND deleted=0
userMapper.deleteById(1L);
// 查询时会自动加上WHERE deleted=0条件
userMapper.selectList(null);
5. 乐观锁实现
乐观锁通过版本号机制实现:
-
实体类添加
@Version
注解 -
配置乐观锁插件:
java
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
使用示例:
java
// 先查询获取version
User user = userMapper.selectById(1L);
// 修改数据
user.setUsername("new name");
// 执行更新,会带上version条件
userMapper.updateById(user);
六、性能优化建议
-
批量操作 :使用
saveBatch
、updateBatchById
等方法提高批量操作效率 -
SQL打印:开发环境可开启SQL打印方便调试,生产环境应关闭
-
索引优化:为常用查询条件添加数据库索引
-
查询字段控制 :避免使用
select *
,明确指定查询字段 -
逻辑删除:对于大表,逻辑删除可能影响性能,需考虑归档策略
七、常见问题解决方案
-
表名/字段名不一致:
-
使用
@TableName
和@TableField
注解明确指定 -
配置全局的下划线转驼峰命名
-
-
主键策略问题:
-
IdType.AUTO
:数据库自增 -
IdType.ASSIGN_ID
:雪花算法生成ID(默认) -
IdType.ASSIGN_UUID
:UUID生成
-
-
分页失效:
-
确保配置了分页插件
-
检查Page参数是否正确传递
-
-
逻辑删除无效:
-
检查
application.yml
中的逻辑删除配置 -
确保实体类字段添加了
@TableLogic
注解
-
结语
通过本文的介绍,相信你已经掌握了SpringBoot整合MyBatis-Plus的核心要点。MyBatis-Plus的强大功能可以让我们从繁琐的XML配置中解放出来,专注于业务逻辑的实现。在实际项目中,你可以根据需求组合使用各种功能,如分页+条件查询、逻辑删除+自动填充等,构建出高效可靠的数据访问层。