MyBatis-Plus09:静态工具Db

什么是 Db

Db 是 MyBatis-Plus 3.5.4+ 提供的静态工具类,无需注入 ServiceMapper直接通过静态方法操作数据库。本质上是对 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 静态工具,两者配合使用效果最佳。

相关推荐
树码小子6 小时前
Mybatis(17)Mybatis-Plus条件构造器(2)& 自定义 SQL
数据库·sql·mybatis-plus
ruleslol7 小时前
MyBatis-Plus10:逻辑删除
mybatis-plus
树码小子1 天前
Mybatis(16)Mybatis-Plus条件构造器(1)
数据库·mybatis-plus
树码小子2 天前
Mybatis(14)Mybatis-Plus入门 & 简单使用
java·mybatis-plus
ruleslol3 天前
MyBatis-Plus06:IService接口Lambda基本用法
mybatis-plus
ruleslol4 天前
MyBatis-Plus02: 常用注解
mybatis-plus
ruleslol6 天前
MyBatis-Plus05:IService接口基本用法
mybatis-plus
ruleslol6 天前
MyBatis-Plus04:自定义SQL
mybatis-plus
识君啊10 天前
MyBatis-Plus 逻辑删除导致唯一索引冲突的解决方案
java·spring boot·mybatis·mybatis-plus·唯一索引·逻辑删除