MyBatis-Plus 中 ServiceImpl与BaseMapper的关系

在 MyBatis-Plus (MP) 中,ServiceImpl<M extends BaseMapper<T>, T>BaseMapper<T> 之间存在着紧密且明确的依赖和委托关系,它们分别代表了软件分层架构中的 Service 层实现Data Access Object (DAO) / Mapper 层接口

  1. BaseMapper<T> - 数据访问层接口 (DAO/Mapper Interface):

    • 角色: 直接与数据库交互的接口。
    • 核心功能: 继承自 MP 的 BaseMapper<T> 接口后,自动获得了大量预定义的、通用的单表 CRUD(增删改查)方法实现(如 insert, selectById, updateById, deleteById, selectList, selectPage 等)。我们在开发时无需再为这些基础操作编写 SQL 语句。
    • 关注点: 定义数据访问操作,封装 SQL 细节(虽然大部分基础 SQL 由 MP 自动生成)。
    • 例子: UserMapper extends BaseMapper<User>
  2. ServiceImpl<M extends BaseMapper<T>, T> - 服务层实现 (Service Implementation):

    • 角色: 业务逻辑层(Service Layer)的一个通用实现。它实现了 MP 提供的 IService<T> 接口,后者定义了 Service 层常用的业务方法。
    • 核心功能:
      • 封装 BaseMapper: ServiceImpl 内部持有一个对应的 Mapper 实例(类型为 M,也就是继承了 BaseMapper 的那个接口,例如 UserMapper)。这个 Mapper 实例通常通过依赖注入(如 @Autowired)获得。
      • 委托执行: ServiceImpl 中的许多(但不是全部)方法,其默认实现就是直接调用其内部持有的 Mapper 实例的相应方法来完成数据库操作。例如,ServiceImplgetById(Serializable id) 方法内部通常会调用 baseMapper.selectById(id)
      • 提供额外便利方法: ServiceImplIService 接口的基础上,还提供了一些更方便的批量操作或组合操作方法,例如 saveBatch(), saveOrUpdate(), updateBatchById() 等,这些方法内部可能会调用 Mapper 的多个方法或进行一些逻辑处理。
      • 事务管理: Service 层通常是应用声明式事务 (@Transactional) 的地方。ServiceImpl 的方法是添加事务注解的理想位置,确保一系列数据库操作(可能跨越多个 Mapper 调用)的原子性。
      • 业务逻辑扩展点: 开发者可以继承 ServiceImpl 并重写其方法,或者添加新的业务方法,在调用 Mapper 前后加入特定的业务校验、数据处理、组合逻辑等。
    • 关注点: 编排业务流程,处理业务逻辑,管理事务,调用并组合 Mapper 层操作。
    • 例子: UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService

关系总结:

  • 依赖关系: ServiceImpl 依赖于 BaseMapper (具体体现为依赖其子接口,如 UserMapper) 来执行实际的数据库操作。
  • 委托关系: ServiceImpl 将大部分基础的数据访问任务委托BaseMapper 完成。
  • 分层关系: BaseMapper 属于数据访问层 (DAO/Mapper),ServiceImpl 属于业务逻辑层 (Service)。ServiceImplBaseMapper使用者 (Consumer)
  • 功能扩展: ServiceImplBaseMapper 提供的原子数据库操作基础上,增加了业务封装、事务管理和更便捷的组合操作能力。

代码示例:

// 1. Entity
@TableName("user")
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    // Getters and Setters...
}

// 2. Mapper Interface (DAO Layer) - Extends BaseMapper
@Mapper
public interface UserMapper extends BaseMapper<User> {
    // BaseMapper already provides CRUD methods like insert, selectById, etc.
    // Add custom complex SQL methods here if needed
    // List<User> findUsersWithSpecialCondition(@Param("param") String param);
}

// 3. Service Interface (Service Layer - Optional but recommended)
public interface UserService extends IService<User> {
    // IService already provides common service methods like getById, save, list, etc.
    // Add custom business logic methods here
    boolean updateUserName(Long userId, String newName);
}

// 4. Service Implementation (Service Layer) - Extends ServiceImpl, Implements UserService
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    // ServiceImpl automatically injects the corresponding Mapper instance (named baseMapper)
    // You can also @Autowired it explicitly if needed, though not necessary for basic usage:
    // @Autowired
    // private UserMapper userMapper; // This is the same instance as 'baseMapper' inherited from ServiceImpl

    @Override
    public User getUserById(Long id) {
        // Example of ServiceImpl delegating to BaseMapper
        // Calling the getById method inherited from ServiceImpl, which internally calls baseMapper.selectById(id)
        return super.getById(id);
        // Or directly use the inherited baseMapper:
        // return baseMapper.selectById(id);
    }

    @Override
    public boolean saveUser(User user) {
        // Example of ServiceImpl providing convenience method 'save'
        // Calling the save method inherited from ServiceImpl, which internally calls baseMapper.insert(user)
        return super.save(user);
        // Or directly:
        // return baseMapper.insert(user) > 0;
    }

    @Override
    @Transactional // Apply transaction at the service method level
    public boolean updateUserName(Long userId, String newName) {
        // Example of adding business logic in Service Layer
        User user = baseMapper.selectById(userId); // Use inherited baseMapper
        if (user != null) {
            // Business validation or logic could go here
            if (newName == null || newName.isEmpty()) {
                 throw new IllegalArgumentException("New name cannot be empty");
            }
            user.setName(newName);
            // Delegate the update operation to baseMapper
            return baseMapper.updateById(user) > 0;
             // Alternatively, use the service method which also delegates
             // return super.updateById(user);
        }
        return false;
    }

     // You can also directly use methods provided by ServiceImpl like saveOrUpdate, saveBatch etc.
     // These methods encapsulate logic that might involve checking existence before insert/update
     // or iterating and calling mapper methods multiple times.
     public boolean createOrUpdate(User user) {
         return super.saveOrUpdate(user); // Convenient method from ServiceImpl
     }
}

通过这种设计,MP 实现了代码的复用(BaseMapperServiceImpl 的通用方法),保持了清晰的分层结构,并允许开发者在 Service 层轻松地添加业务逻辑和事务控制,同时极大地简化了数据访问层的开发工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰糖心书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值