当前位置: 首页 > news >正文

mybatis-plus从入门到入土(三):持久层接口之IService

大家好,之前两周一直没有更新博客,主要因为最近回了趟老家,处理了一些事情。好了,今天我们开始更新第三篇持久层接口。首先先看持久层的IService接口。

官方文档https://baomidou.com/guides/data-interface/#get

IService相关方法

IService是我们工作中最长用到的类,这里面的方法主要就是增删改查,我们先来看几个方法。

// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);

关于增,也就是插入记录,在这个接口里主要提供了单条插入批量插入方法,关于saveBatch的两个方法需要说一下,虽然一个带有batchSize,一个不带,但是最终都是走的带batchSize的方法。如果不指定batchSize,则batchSize为1000。有兴趣的可以看下源码。

// 根据 queryWrapper 设置的条件,删除记录
boolean remove(Wrapper<T> queryWrapper);
// 根据 ID 删除
boolean removeById(Serializable id);
// 根据 columnMap 条件,删除记录
boolean removeByMap(Map<String, Object> columnMap);
// 删除(根据ID 批量删除)
boolean removeByIds(Collection<? extends Serializable> idList);

关于删,有根据id删除,也有根据条件删除,总体都比较简单就不赘述了。

// 根据 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);

关于改,其他几个方法也没啥,可以单条更新,可以批量更新,UpdateWrapper说一下,这是个更新包装器,可以用来组装更新的字段和条件等,这个后面会讲到。


--------------------------GET 单条查询-----------------------------------------------------------------------
// 根据 ID 查询
T getById(Serializable id);
// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);--------------------------LIST 集合查询-----------------------------------------------------------------------
// 查询所有
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);--------------------------PAGE 分页查询-----------------------------------------------------------------------
// 无条件分页查询
IPage<T> page(IPage<T> page);
// 条件分页查询
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);--------------------------COUNT 数量查询-----------------------------------------------------------------------
// 查询总记录数
long count();
// 根据 Wrapper 条件,查询总记录数
long count(Wrapper<T> queryWrapper);

关于查,分为单条查询集合查询分页查询数量查询;这几个API用法也比较简单,这里简单列举了一些,但是不全;建议去看下官方文档的描述。

以上就是增删改查的部分API,大家可能感到很无语,我基本上只是把方法贴上去了,但是确实没啥可讲的,对着官方文档的例子,大家自己测试下就好了,当然我还省略了saveOrUpdate方法,这个主要是根据主键来判断是更新还是删除。下面我们分析下IService的继承结构,这块是我重点想讲的,对这些了解了,才是对大家真正的有帮助。

IService相关类结构

在这里插入图片描述
从上面图中,可以看出,IService继承自IRepository,然后IRepository还有个抽象实现类AbstractRepository,以及CrudRepository,最后呢有一个ServiceImpl继承了CrudRepository还实现了IService接口。是不是听晕了,没关系,我们挨个来看下。

IRepository

IRepository作为顶层接口,它实现了增删改查里面的比较基础的方法,比如savedeleteById等,但是涉及到批量操作的或者需要一些逻辑判断的是交给实现类去实现的。如下图所示在IRepository接口中只实现了save方法,但是save方法的getBaseMapper也没有实现,也就是说getBaseMapper也是需要实现类去定义逻辑的。

    /*** 插入一条记录(选择字段,策略插入)** @param entity 实体对象*/default boolean save(T entity) {return SqlHelper.retBool(getBaseMapper().insert(entity));}/*** 插入(批量)** @param entityList 实体对象集合* @param batchSize  插入批次数量*/boolean saveBatch(Collection<T> entityList, int batchSize);/*** 批量修改插入** @param entityList 实体对象集合* @param batchSize  每次的数量*/boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);...省略其他方法.../*** 获取对应 entity 的 BaseMapper** @return BaseMapper*/BaseMapper<T> getBaseMapper();

AbstractRepository

AbstractRepository作为抽象类,在IRepository的基础上填充了不少的方法逻辑,比如批量操作的一些方法,还有saveOrUpdate以及getOne这类的方法也是在AbstractRepository中实现的,从这一点可以看出来,作者设计的时候把IRepository作为绝对的顶层接口,只实现非常简单单一的增删改查。

...省略其他方法...
@Override
public boolean saveOrUpdate(T entity) {return getBaseMapper().insertOrUpdate(entity);
}@Override
public T getOne(Wrapper<T> queryWrapper, boolean throwEx) {return getBaseMapper().selectOne(queryWrapper, throwEx);
}

CrudRepository

CrudRepository最重要的点,就是在这个类里面实现了getBaseMapper,也就意味着之前IRepositoryAbstractRepository一直缺少的BaseMapper,终于有了,就是相当于之前都是定义了一些逻辑和规则,但缺少真正的引擎啊,好了,CrudRepository是真真正正的能执行的个体了。

/*** IService 实现类( 泛型:M 是 mapper 对象,T 是实体 )** @author hubin* @since 2018-06-23*/
public abstract class CrudRepository<M extends BaseMapper<T>, T> extends AbstractRepository<M, T> {@Autowiredprotected M baseMapper;@Overridepublic M getBaseMapper() {Assert.notNull(this.baseMapper, "baseMapper can not be null");return this.baseMapper;}...省略其他方法...
}

IService

好了,我们再看下IService这个接口的意义是什么,我们之前已经看到了从IRepository一直到CrudRepository,这之间从单一的增删改查到批量操作以至最后的装上引擎,这已经够了啊,那IService是干什么的呢?

IService中只定义了下面这四个方法,都是关于批量操作的,但是方法内的逻辑还是直接调用了IRepository的对应方法,唯一的区别就是他把这四个方法都加上了事务注解,这也就是这个接口为什么叫做IService的原因,这是真正贴合实际开发中需要的MVC三层架构中Service服务的接口,他对于批量的操作进行了事务控制,正如咱们平时开发的时候需要在Service类中加事务注解一样,从这可以看出MybatisPlus的作者在类的设计上还是很讲究的奥。

public interface IService<T> extends IRepository<T> {/*** 插入(批量)** @param entityList 实体对象集合*/@Transactional(rollbackFor = Exception.class)default boolean saveBatch(Collection<T> entityList) {return saveBatch(entityList, DEFAULT_BATCH_SIZE);}/*** 批量修改插入** @param entityList 实体对象集合*/@Transactional(rollbackFor = Exception.class)default boolean saveOrUpdateBatch(Collection<T> entityList) {return saveOrUpdateBatch(entityList, DEFAULT_BATCH_SIZE);}/*** 批量删除(jdbc批量提交)** @param list 主键ID或实体列表(主键ID类型必须与实体类型字段保持一致)* @return 删除结果* @since 3.5.0*/@Transactional(rollbackFor = Exception.class)default boolean removeBatchByIds(Collection<?> list) {return removeByIds(list);}/*** 根据ID 批量更新** @param entityList 实体对象集合*/@Transactional(rollbackFor = Exception.class)default boolean updateBatchById(Collection<T> entityList) {return updateBatchById(entityList, DEFAULT_BATCH_SIZE);}
}

ServiceImpl

好了,轮到最后的重头戏了,就是ServiceImpl类,这个类没有任何的方法,但是他继承了CrudRepository并且实现了IService接口,从这个类的定位来说,首先他实现IService接口,证明他是用于提供Service服务层级的实现类,然后继承CrudRepository呢,是为了获取CrudRepository中一些已经实现的功能。话说是不是有个什么设计模式和这很像来着??

/*** IService 实现类( 泛型:M 是 mapper 对象,T 是实体 )** @author hubin* @since 2018-06-23*/
public class ServiceImpl<M extends BaseMapper<T>, T> extends CrudRepository<M, T> implements IService<T> {}

什么设计模式和这很像来着??**

/*** IService 实现类( 泛型:M 是 mapper 对象,T 是实体 )** @author hubin* @since 2018-06-23*/
public class ServiceImpl<M extends BaseMapper<T>, T> extends CrudRepository<M, T> implements IService<T> {}

好了,朋友们,今天先讲到这里吧。想必经过今天的讲解大家对IService这个接口的理解更加深了吧,我们下周再会!

http://www.lryc.cn/news/600270.html

相关文章:

  • 嵌入式硬件篇---有线串口通信问题解决
  • 如何创建或查看具有 repo 权限的 GitHub 个人访问令牌(PAT)
  • 国内AI IDE竞逐:腾讯CodeBuddy、阿里通义灵码、字节跳动TRAE、百度文心快码
  • 零弹窗干扰的贪吃蛇游戏,下载即玩
  • 刷题日记0726
  • 二次函数图像动画展示
  • ESP32实战:5分钟实现PC远程控制LED灯
  • 【MySQL 数据库】MySQL基本查询(第二节)
  • AutoCAD_2025下载与保姆级安装教程
  • 联表实现回显功能
  • 速通python加密之AES加密
  • 【AcWing 835题解】滑动窗口
  • Baumer工业相机堡盟工业相机如何通过YoloV8深度学习模型实现沙滩小人检测识别(C#代码UI界面版)
  • CT、IT、ICT 和 DICT区别
  • Day 22: 复习
  • Python 面向对象基础
  • 【Android】相对布局应用-登录界面
  • 基于 Claude Code 与 BrowserCat MCP 的浏览器自动化全链路构建实践
  • Android 修改系统时间源码阅读
  • 各种前端框架界面
  • 【GoLang#3】:数据结构(切片 | map 映射)
  • SAP ABAP的数据通过调用泛微Restful API同步数据到OA建模表
  • 《基于雅可比矢量近似的EIT触觉传感灵敏度非均匀校正》论文解读
  • Yocto 项目直播教学|今天晚上 21:30 直播!
  • python---字典(dict)
  • OpenCV图像梯度、边缘检测、轮廓绘制、凸包检测大合集
  • 【Linux手册】操作系统如何管理存储在外设上的文件
  • 2025牛客暑期多校第4场——G
  • MCP协议深度解析:客户端-服务器架构的技术创新
  • CMakeLists.txt 怎么写