MyBatisPlus 详解与实战应用
一、MyBatisPlus 简介
MyBatisPlus 是一个基于 MyBatis 的增强工具,旨在简化数据库操作和提高开发效率。它提供了丰富的内置功能,例如自动映射、分页查询、条件构造器等,帮助开发者快速构建数据访问层。
1.1 MyBatisPlus 的优势
- 简化开发:提供通用的增删改查方法,减少重复代码。
- 支持链式编程:使用条件构造器(QueryWrapper、UpdateWrapper)实现灵活的查询和更新。
- 强大的分页功能:集成分页插件,轻松实现分页查询。
- 多租户支持:支持多租户架构,适用于 SaaS 场景。
- 逻辑删除:支持软删除,避免数据真正删除。
1.2 MyBatisPlus 的核心组件
- BaseMapper:MyBatisPlus 提供的基础接口,包含常见的增删改查方法。
- IService:服务层接口,提供事务管理、批量操作等功能。
- QueryWrapper / UpdateWrapper:用于构建查询和更新条件。
- Page:分页工具类,配合 BaseMapper 使用。
- 自动映射:自动映射数据库字段与实体类字段。
二、MyBatisPlus 的基本使用
2.1 引入依赖
在 pom.xml
中引入 MyBatisPlus 依赖:
xml
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
2.2 配置 MyBatisPlus
在 application.yml
中配置 MyBatisPlus:
yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/test_db?useSSL=false&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis-plus:
mapper-locations: classpath*:mapper/**/*.xml
type-aliases-package: com.example.demo.entity
2.3 定义实体类
java
import com.baomidou.mybatisplus.annotation.*;
@Data
@TableName("user_table")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
@TableLogic
private Integer deleted;
}
2.4 定义 Mapper 接口
java
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface UserMapper extends BaseMapper<User> {
}
2.5 使用 BaseMapper 实现基本操作
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
// 插入用户
public void insertUser(User user) {
userMapper.insert(user);
}
// 查询所有用户
public List<User> getAllUsers() {
return userMapper.selectList(null);
}
// 根据 ID 查询用户
public User getUserById(Long id) {
return userMapper.selectById(id);
}
// 更新用户信息
public void updateUser(User user) {
userMapper.updateById(user);
}
// 删除用户(逻辑删除)
public void deleteUser(Long id) {
userMapper.deleteById(id);
}
}
三、MyBatisPlus 高级功能
3.1 条件构造器
MyBatisPlus 提供了 QueryWrapper
和 UpdateWrapper
,用于构建复杂的查询和更新条件。
3.1.1 QueryWrapper 示例
java
// 查询年龄大于 20 的用户
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 20);
List<User> users = userMapper.selectList(queryWrapper);
3.1.2 UpdateWrapper 示例
java
// 将年龄大于 20 的用户邮箱更新为 "test@example.com"
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.gt("age", 20).set("email", "test@example.com");
userMapper.update(null, updateWrapper);
3.2 分页查询
MyBatisPlus 提供了 Page
工具类,用于实现分页查询。
3.2.1 分页查询示例
java
// 查询第一页,每页 5 条数据
Page<User> page = new Page<>(1, 5);
Page<User> userPage = userMapper.selectPage(page, null);
List<User> users = userPage.getRecords();
long total = userPage.getTotal();
3.3 逻辑删除
MyBatisPlus 支持逻辑删除,避免数据真正删除。
3.3.1 配置逻辑删除
在 application.yml
中配置逻辑删除:
yaml
mybatis-plus:
global-config:
db-config:
logic-delete-value: 1
logic-keep-value: 0
3.4 多租户支持
MyBatisPlus 支持多租户架构,适用于 SaaS 场景。
3.4.1 配置多租户
在 application.yml
中配置多租户:
yaml
mybatis-plus:
tenant:
enable: true
ignore-table: "user_table" # 忽略的表
tenant-id-column: "tenant_id" # 租户 ID 列
四、MyBatisPlus 实战应用
4.1 场景说明
假设我们有一个电商平台,用户可以下单购买商品。我们需要实现以下功能:
- 用户注册与信息管理
- 商品管理
- 订单管理
4.2 数据库设计
4.2.1 用户表(user_table)
字段名 | 类型 | 描述 |
---|---|---|
id | BIGINT | 主键 |
name | VARCHAR | 用户名 |
age | INT | 年龄 |
VARCHAR | 邮箱 | |
deleted | INT | 逻辑删除标识 |
4.2.2 商品表(product_table)
字段名 | 类型 | 描述 |
---|---|---|
id | BIGINT | 主键 |
name | VARCHAR | 商品名称 |
price | DECIMAL | 价格 |
stock | INT | 库存 |
4.2.3 订单表(order_table)
字段名 | 类型 | 描述 |
---|---|---|
id | BIGINT | 主键 |
user_id | BIGINT | 用户 ID |
product_id | BIGINT | 商品 ID |
quantity | INT | 数量 |
total_price | DECIMAL | 总价 |
4.3 实体类定义
java
// User.java(已在前面定义)
// Product.java
@Data
@TableName("product_table")
public class Product {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private BigDecimal price;
private Integer stock;
}
// Order.java
@Data
@TableName("order_table")
public class Order {
@TableId(type = IdType.AUTO)
private Long id;
private Long userId;
private Long productId;
private Integer quantity;
private BigDecimal totalPrice;
}
4.4 Mapper 接口定义
java
public interface ProductMapper extends BaseMapper<Product> {
}
public interface OrderMapper extends BaseMapper<Order> {
}
4.5 服务层实现
java
@Service
public class OrderService {
@Autowired
private UserMapper userMapper;
@Autowired
private ProductMapper productMapper;
@Autowired
private OrderMapper orderMapper;
// 下单
public void placeOrder(Long userId, Long productId, Integer quantity) {
User user = userMapper.selectById(userId);
if (user == null) {
throw new RuntimeException("用户不存在");
}
Product product = productMapper.selectById(productId);
if (product == null) {
throw new RuntimeException("商品不存在");
}
if (product.getStock() < quantity) {
throw new RuntimeException("库存不足");
}
BigDecimal totalPrice = product.getPrice().multiply(new BigDecimal(quantity));
Order order = new Order();
order.setUserId(userId);
order.setProductId(productId);
order.setQuantity(quantity);
order.setTotalPrice(totalPrice);
orderMapper.insert(order);
// 更新库存
product.setStock(product.getStock() - quantity);
productMapper.updateById(product);
}
// 查询用户订单
public List<Order> getOrdersByUserId(Long userId) {
QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_id", userId);
return orderMapper.selectList(queryWrapper);
}
}
4.6 控制器层实现
java
@RestController
@RequestMapping("/orders")
public class OrderController {
@Autowired
private OrderService orderService;
// 下单
@PostMapping("/place")
public void placeOrder(@RequestParam Long userId, @RequestParam Long productId, @RequestParam Integer quantity) {
orderService.placeOrder(userId, productId, quantity);
}
// 查询用户订单
@GetMapping("/user/{userId}")
public List<Order> getOrdersByUserId(@PathVariable Long userId) {
return orderService.getOrdersByUserId(userId);
}
}
五、总结
本文详细介绍了 MyBatisPlus 的核心功能,包括其基本使用、高级功能(如条件构造器、分页查询、逻辑删除等)以及如何在实际项目中应用这些功能。通过一个电商平台的实战案例,我们展示了如何利用 MyBatisPlus 实现高效的数据库操作。
MyBatisPlus 是一个非常强大的工具,能够极大地简化数据库操作,提高开发效率。在实际开发中,合理使用 MyBatisPlus 的功能可以显著减少重复代码,提高代码可读性和维护性。