引言
在MybatisPlus框架中,IService接口扮演着重要的角色。作为一个通用的服务接口,IService定义了一系列数据库操作方法,包括查询、插入、更新、删除等。这些方法的定义使得在服务层进行数据库操作变得更为便捷和高效。
IService 概述
MyBatis-Plus 中有一个接口 IService 和其实现类 ServiceImpl,封装了常见的业务层逻辑,详情查看源码 IService 和 ServiceImpl
-
IService接口是一个泛型接口,定义了一组通用的基础方法,包括常见的增删改查操作。例如,它提供了插入数据、根据主键更新数据、根据主键删除数据、根据主键查询数据等方法的签名。用户可以根据自己的需求和业务逻辑在自定义的服务接口中继承IService接口,并实现其中的方法。 -
ServiceImpl类是IService接口的默认实现类,提供了基本的增删改查操作的实现细节。它使用了泛型参数来规范实体类和主键类型,并实现了IService接口中定义的方法。用户可以继承ServiceImpl类,并在自己的实现类中添加或重写更具体的业务逻辑。
IService 接口的优势
- 减少重复代码:
IService接口提供了一系列通用的数据库操作方法,避免了在服务层中编写大量的重复代码。 - 提高开发效率:通过继承
IService接口和ServiceImpl类,可以快速实现服务层的数据库操作功能,提高开发效率。 - 易于维护:
IService接口的封装使得服务层的代码更加清晰、简洁,易于理解和维护。
IService接口的具体使用
-
继承IService接口:在服务层中,可以定义一个具体的服务接口继承自IService接口,例如
public interface UserService extends IService<User>。 -
实现IService接口:然后,需要实现这个具体的服务接口。MybatisPlus提供了ServiceImpl类作为IService接口的实现类,可以通过继承ServiceImpl类来快速实现IService接口中的方法。例如
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService。 -
调用IService接口方法:在服务层的其他类中,可以通过注入具体的服务类来调用IService接口中的方法。例如,在Controller层中注入UserService,然后调用其提供的list、getById等方法来获取数据。
因此我们在使用的时候仅需在自己定义的 Service 接口中继承 IService 接口,在自己的实现类中实现自己的 Service 并继承 ServiceImpl 即可
通用 Service CRUD 封装 IService 接口,进一步封装 CRUD 采用如下前缀命名方式区分 Mapper 层,以避免混淆
get 查询单行remove 删除list 查询集合page 分页
如果存在自定义通用 Service 方法的可能,需要创建自己的 IBaseService 继承 Mybatis-Plus 提供的基类
IService 中的 CRUD 方法
新增:Save、SaveOrUpdate
Save
| 类型 | 参数名 | 描述 |
|---|---|---|
T | entity | 实体对象 |
Collection<T> | entityList | 实体对象集合 |
int | batchSize | 插入批次数量 |
// 插入一条记录(选择字段,策略插入)
boolean save(T entity);// 插入(批量)
boolean saveBatch(Collection<T> entityList);// 插入(批量,限制数量)
boolean saveBatch(Collection<T> entityList, int batchSize);
SaveOrUpdate
| 类型 | 参数名 | 描述 |
|---|---|---|
T | entity | 实体对象 |
Wrapper<T> | updateWrapper | 实体对象封装操作类 UpdateWrapper |
Collection<T> | entityList | 实体对象集合 |
int | batchSize | 插入批次数量 |
// TableId 注解存在更新记录,否则插入一条记录
boolean saveOrUpdate(T entity);// 根据 updateWrapper 尝试更新,否则继续执行 saveOrUpdate(T) 方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
批量新增
可以开启 rewriteBatchedStatements=true 参数,提高批处理的执行效率。
删除:Remove
| 类型 | 参数名 | 描述 |
|---|---|---|
Wrapper<T> | queryWrapper | 实体包装类 QueryWrapper |
Serializable | id | 主键 ID |
Map<String, Object> | columnMap | 表字段 map 对象 |
Collection<? extends Serializable> | idList | 主键 ID 列表 |
// 根据 entity 条件,删除记录
boolean remove(Wrapper<T> queryWrapper);// 根据 ID 删除
boolean removeById(Serializable id);// 根据 columnMap 条件,删除记录
boolean removeByMap(Map<String, Object> columnMap);// 删除(根据ID 批量删除)
boolean removeByIds(Collection<? extends Serializable> idList);
修改:Update
| 类型 | 参数名 | 描述 |
|---|---|---|
Wrapper<T> | updateWrapper | 实体对象封装操作类 UpdateWrapper |
| T | entity | 实体对象 |
Collection<T> | entityList | 实体对象集合 |
| int | batchSize | 更新批次数量 |
// 根据 UpdateWrapper 条件更新记录,需要设置sqlset
boolean update(Wrapper<T> updateWrapper);// 根据 whereWrapper 条件,更新记录
boolean update(T updateEntity, Wrapper<T> whereWrapper);// 根据 ID 选择修改
boolean updateById(T entity);// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList);// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);
查询
查询单条数据 get
| 类型 | 参数名 | 描述 |
|---|---|---|
| Serializable | id | 主键 ID |
Wrapper<T> | queryWrapper | 实体对象封装操作类 QueryWrapper |
| boolean | throwEx | 有多个 result 是否抛出异常 |
| T | entity | 实体对象 |
Function<? super Object, V> | mapper | 转换函数 |
// 根据 ID 查询
T getById(Serializable id);// 根据 Wrapper,查询一条记录。结果集如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);// 根据 Wrapper,查询一条记录
T getOne(Wrapper<T> queryWrapper, boolean throwEx);// 根据 Wrapper,查询一条记录
Map<String, Object> getMap(Wrapper<T> queryWrapper);// 根据 Wrapper,查询一条记录
// mapper:转换函数,用于将查询结果中的每个对象转换为指定的对象类型。
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
查询多条数据 list
| 类型 | 参数名 | 描述 |
|---|---|---|
| Serializable | id | 主键 ID |
| Wrapper | queryWrapper | 实体对象封装操作类 QueryWrapper |
| boolean | throwEx | 有多个 result 是否抛出异常 |
| T | entity | 实体对象 |
Function<? super Object, V> | mapper | 转换函数 |
// 查询所有
List<T> list();// 查询列表
List<T> list(Wrapper<T> queryWrapper);// 查询(根据 ID 批量查询)
Collection<T> listByIds(Collection<? extends Serializable> idList);// 查询(根据 columnMap 条件)
Collection<T> listByMap(Map<String, Object> columnMap);// 查询所有列表
List<Map<String, Object>> listMaps();// 查询列表
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);// 查询全部记录
List<Object> listObjs();// 查询全部记录
<V> List<V> listObjs(Function<? super Object, V> mapper);// 根据 Wrapper 条件,查询全部记录
List<Object> listObjs(Wrapper<T> queryWrapper);// 根据 Wrapper 条件,查询全部记录
// mapper:转换函数,用于将查询结果中的每个对象转换为指定的对象类型。
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
查询记录数 count
// 查询总记录数
int count();// 根据 Wrapper 条件,查询总记录数
int count(Wrapper<T> queryWrapper);
分页:Page
| 类型 | 参数名 | 描述 |
|---|---|---|
IPage<T> | page | 翻页对象 |
Wrapper<T> | queryWrapper | 实体对象封装操作类 QueryWrapper |
// 无条件分页查询
IPage<T> page(IPage<T> page);// 条件分页查询
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);// 无条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page);// 条件分页查询
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);
链式:Chain
查找
// 链式查询 普通
QueryChainWrapper<T> query();// 链式查询 lambda 式。注意:不支持 Kotlin
LambdaQueryChainWrapper<T> lambdaQuery();// 示例:
// eq 指定条件
query().eq("column", value).one();
lambdaQuery().eq(Entity::getId, value).list();
更新
// 链式更改 普通
UpdateChainWrapper<T> update();// 链式更改 lambda 式。注意:不支持 Kotlin
LambdaUpdateChainWrapper<T> lambdaUpdate();// 示例:
// eq 指定条件
update().eq("column", value).remove();
lambdaUpdate().eq(Entity::getId, value).update(entity);
调用 Service 层操作数据
我们在自己的 Service 接口中通过继承 MyBatis-Plus 提供的 IService 接口,不仅可以获得其提供的 CRUD 方法,而且还可以使用自身定义的方法。
- 创建
UserService并继承IService
/**
* UserService 继承 IService 模板提供的基础功能
*/
public interface UserService extends IService<User> {}
-
创建
UserService的实现类并继承ServiceImpl,传入映射的 mapper(继承了BaseMapper)和实体类泛型。ServiceImpl 实现了 IService,提供了 IService中基础功能的实现。若 ServiceImpl 无法满足业务需求,则可以使用自定的 UserService 定义方法,并在实现类中实现
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User>
implements UserService{}
- 测试查询记录数
调用方法:int count()
@Test
public void testGetCount(){// 查询总记录数// 执行的SQL为:SELECT COUNT( * ) FROM userlong count = userService.count();System.out.println("总记录数:" + count);
}
- 测试批量插入数据
调用方法:
boolean saveBatch(Collection<T> entityList)
@Test
public void test(){List<User> list = new ArrayList<>();for (int i = 1; i <= 10; i++) {User user = new User();user.setName("Vz"+i);user.setAge(20+i);list.add(user);}boolean b = userService.saveBatch(list);System.out.println(b ? "添加成功!" : "添加失败!");
}
总结
MybatisPlus 的 IService 接口是一个强大的工具,它简化了服务层数据库操作的实现过程,提高了开发效率和代码质量。通过学习和使用 IService 接口,我们可以更加高效地开发基于 MybatisPlus 的 Web 应用程序。