一、BaseMapper<>
BaseMapper<> 是一个泛型接口,其作用是提供基础的 CRUD(Create、Retrieve、Update 和 Delete)操作方法。它通常与 MyBatis ORM(Object-Relational Mapping)框架搭配使用,用于简化数据访问层的开发。
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
具体来说,在上述代码中,`UserMapper` 接口继承自 `BaseMapper<User>` 接口,其中,`<User>` 是泛型类型参数,表示 User 实体类的相关操作。
因此,通过继承 `BaseMapper<User>` 接口,`UserMapper` 接口就可以获得一组默认的 CRUD 方法,如 insert、selectOne 和 delete 等,无需手动编写 SQL 语句。同时,也可以在 `UserMapper` 接口中扩展更多自定义的查询和更新方法来满足业务需求。
总之,`BaseMapper<>` 提供了一组通用的 DAO 层方法,可以减少重复的代码量并提高项目的开发效率。当我们需要进行数据持久化操作时,只需要继承该接口并传入相应实体类的类型即可。
二、IService<>
IService<>是一个泛型接口,是 MyBatis-Plus 框架中的一个服务接口,提供了一些默认的基本 CRUD (增删改查)的方法。其中传入的泛型参数是实体类类型。
在声明 `UserService` 接口时采用 `extends` 继承方式,继承了 `IService<User>` 接口,这样 `UserService` 就继承了 `IService` 中定义的基本 CRUD 方法,可以在不用显式编写对应的Mapper层实现逻辑的情况下,使用 MyBatis-Plus 提供的 CRUD 方法完成通用数据操作。
中括号里需要写实体类类型,指定该 Service 层接口操作的是哪个表(哪个实体类),例如上述代码中 `<User>` 即表示该 Service 类处理针对用户表(User类)的相关业务。
具体举例:
// 定义一个 UserService 接口
public interface UserService extends IService<User> {
void updateUsername(Long userId, String userName);
List<User> selectAll();
}
在 `UserService` 接口中我们自定义了两个新的方法:`updateUsername()` 和 `selectAll()`。这两个方法是 UserService 独有的、基于业务逻辑的方法,相比 `IService`,有更多的特殊性和灵活度。
三、ServiceImpl<>
ServiceImpl<> 是一个泛型类,是 MyBatis-Plus 框架提供的业务逻辑层(Service)的默认实现类,它实现了 `IService` 接口中定义的基本 CRUD(增删改查)操作。`ServiceImpl` 类中括号需要传入两个类型参数:`M` 和 `T`。
其中,`M` 表示Mapper接口类型,`T` 则表示对应实体类的类型。例如,如果实现类是针对用户表(User)的操作,则 `T` 应该为 `User` 类型,而 Mapper 接口类型则应该为 `UserMapper`。这样指定后,底层 MyBatis-Plus 就可以将 `User` 对象与 `user` 表之间建立自动映射关系。
通过继承 `ServiceImpl` 类,我们不必编写基础的 CRUD 方法,只需要通过重写 `ServiceImpl` 类中暴露出来的方法就可以轻松实现针对不同表的各种增删改查操作。
具体举例:
// 定义一个 UserServiceImpl 服务实现类
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
private final UserMapper userMapper; // 注入 Mapper 层对象
// 构造函数
public UserServiceImpl(UserMapper userMapper) {
this.userMapper = userMapper;
}
// 覆盖 ServiceImpl 中相应的方法
@Override
public boolean save(User user) {
if (checkDuplicate(user)) { // 检查是否有重复数据
throw new RuntimeException("Duplicate data!");
}
return userMapper.insert(user) > 0;
}
@Override
public User getById(Serializable id) {
User user = userMapper.selectById(id);
if (user == null) {
throw new RuntimeException("Can't find user by id: " + id);
}
return user;
}
// 自定义逻辑实现
public boolean checkDuplicate(User user) {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", user.getName());
List<User> matchUsers = userMapper.selectList(queryWrapper);
int size = matchUsers.size();
return size > 1 || (size == 1 && !matchUsers.get(0).getId().equals(user.getId()));
}
}
在上述示例中,`UserServiceImpl` 继承了 `ServiceImpl<UserMapper, User>`,标明该类是一个 `Service` 层的实现,并指定了基础 Mapper 接口和与它相关联的实体类(`User`)。通过继承 `ServiceImpl` 类,我们可以直接使用 MyBatis-Plus 提供的一些通用的 CRUD 方法,而无需自己再去定义。同时,我们也可以通过覆写基类中暴露出来的方法来实现自定义业务逻辑。