什么是 Db?
Db 是 MyBatis-Plus 3.5.4+ 提供的静态工具类,无需注入 Service 或 Mapper,直接通过静态方法操作数据库。本质上是对 IService 的静态封装。
java
// 传统方式:需要注入
@Autowired
private UserService userService;
userService.getById(1);
// Db 静态工具:直接调用
Db.getById(1, User.class);
一、静态工具Db常用方法:

IService接口是非静态的,需要自定义接口,并且继承它,继承它的过程中还要指定泛型(实体类的类型),目的:通过发射,得到实体类的字节码,才能知道表信息,才能实现CRUD。
静态方法是没有办法读取到类上的泛型的,所以,Db上是没有泛型的,它的方法都需要一个实体类的字节码class<T>,才能通过反射拿到实体类的相关信息。
二、核心使用场景
场景一:解决循环依赖问题 ⭐ 最常用
这是 Db 最重要的使用场景。当两个 Service 互相依赖时,用 Db 打破循环。
java
// ❌ 传统方式:循环依赖,Spring 启动报错
@Service
public class OrderService {
@Autowired
private UserService userService; // OrderService 依赖 UserService
}
@Service
public class UserService {
@Autowired
private OrderService orderService; // UserService 又依赖 OrderService
}
示例:

【注意】:
service比mapper可用的方法更多!
场景二:在非 Service 层直接操作数据库
在 Mapper、工具类、定时任务、事件监听器等无法方便注入 Service 的地方直接使用。
java
// 定时任务中直接操作数据库
@Component
public class DataCleanTask {
@Scheduled(cron = "0 0 2 * * ?")
public void cleanExpiredData() {
// 不需要注入任何 Service,直接静态调用
Db.remove(new LambdaQueryWrapper<Order>()
.lt(Order::getExpireTime, LocalDateTime.now())
.eq(Order::getStatus, "EXPIRED")
);
System.out.println("过期数据清理完成");
}
}
java
// 事件监听器中使用
@Component
public class UserEventListener {
@EventListener
public void onUserRegister(UserRegisterEvent event) {
// 直接保存初始积分记录,无需注入 PointService
UserPoint point = new UserPoint();
point.setUserId(event.getUserId());
point.setPoint(100);
Db.save(point);
}
}
场景三:实体类内部直接关联查询
让实体类自己完成关联数据的获取,VO 转换更优雅。
java
@Data
@TableName("order")
public class Order {
private Long id;
private Long userId;
private Long productId;
private Integer amount;
// 实体类内部直接查关联数据
@TableField(exist = false)
public User getUser() {
return Db.getById(this.userId, User.class);
}
@TableField(exist = false)
public Product getProduct() {
return Db.getById(this.productId, Product.class);
}
}
场景四:批量操作
java
@Service
public class UserService extends ServiceImpl<UserMapper, User> {
public void batchInsert() {
List<User> users = new ArrayList<>();
for (int i = 0; i < 100000; i++) {
users.add(new User("name" + i, i));
}
// 静态批量插入,batchSize 默认 1000
Db.saveBatch(users);
// 也可以指定 batchSize
Db.saveBatch(users, 500);
}
public void batchUpdateById() {
List<User> users = Db.list(new LambdaQueryWrapper<User>()
.eq(User::getStatus, 0));
users.forEach(u -> u.setStatus(1));
// 批量更新
Db.updateBatchById(users);
}
}
三、常用 API 速查
java
// ====== 查询 ======
// 根据 ID 查询
User user = Db.getById(1L, User.class);
// 条件查询单条
User user = Db.getOne(new LambdaQueryWrapper<User>()
.eq(User::getName, "张三"));
// 查询列表
List<User> users = Db.list(new LambdaQueryWrapper<User>()
.eq(User::getStatus, 1));
// 查询数量
long count = Db.count(new LambdaQueryWrapper<User>()
.eq(User::getStatus, 1));
// 分页查询
Page<User> page = Db.page(new Page<>(1, 10),
new LambdaQueryWrapper<User>().eq(User::getStatus, 1));
// ====== 插入 ======
Db.save(user);
Db.saveBatch(userList);
Db.saveBatch(userList, 500);
// ====== 更新 ======
Db.updateById(user);
Db.update(user, new LambdaQueryWrapper<User>()
.eq(User::getName, "张三"));
Db.updateBatchById(userList);
// 有则更新,无则插入
Db.saveOrUpdate(user);
// ====== 删除 ======
Db.removeById(1L, User.class);
Db.remove(new LambdaQueryWrapper<User>()
.eq(User::getStatus, 0));
Db.removeByIds(idList, User.class);
总结
| 对比项 | 传统 Service 注入 | Db 静态工具 |
|---|---|---|
| 使用方式 | 需要 @Autowired 注入 |
直接静态调用 |
| 循环依赖 | 容易出现 | 完全避免 |
| 适用场景 | 主业务逻辑层 | 辅助查询、工具类、监听器 |
| 版本要求 | 无限制 | MP 3.5.4+ |
最佳实践 :主业务逻辑仍写在
Service中,跨 Service 的辅助查询、关联数据获取用Db静态工具,两者配合使用效果最佳。