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

【抽丝剥茧知识讲解】引入mybtis-plus后,mapper实现方式

目录

  • 前言
  • 一、传统 Mapper 接口方式
  • 二、继承 BaseMapper 的方式
  • 三、自定义通用 Mapper 的方式
  • 四、使用 MyBatis-Plus 的 ActiveRecord 模式
  • 五、使用 MyBatis-Plus 的 IService 接口
  • 六、使用建议

前言

mapper文件,作为Mybatis框架中定义SQL语句和映射关系的配置文件,在引入mybtis-plus后,有了更多的实现方式,本文对此做一个对比总结。

一、传统 Mapper 接口方式

先重温一下原始Mybatis的实现方式,以下所有方式均以用户类 User 作为实体类

  • 定义Mapper接口 :为每个实体类创建对应的 Mapper 接口,接口中声明所需的数据库操作方法。例如,针对用户实体类 User,创建 UserMapper 接口。
@Mapper
public interface UserMapper {// 自定义方法List<User> selectAllUsers();
}
  • 实现Mapper接口 :通常使用 MyBatis 的注解或 XML 配置文件来实现接口中的方法。对于简单方法,可以使用注解;对于复杂查询,使用 XML 配置。
@Select("SELECT * FROM user")
List<User> selectAllUsers();

或者在 UserMapper.xml 文件中配置:

<select id="selectAllUsers" resultType="com.example.entity.User">SELECT * FROM user
</select>
  • 优点 :开发人员对数据库操作有较高的控制度,能够灵活地定义各种复杂的 SQL 查询;适合处理复杂的业务场景,尤其是涉及到多表关联等复杂操作时。
  • 缺点 :需要为每个实体类编写对应的 Mapper 接口和实现代码,当实体类较多时,工作量较大;代码重复性较高,对于简单的 CRUD 操作,需要重复编写类似的接口方法。
  • 适用场景 :适用于业务逻辑复杂、需要精确控制数据库操作的项目,尤其是涉及到大量自定义 SQL 查询的场景。

二、继承 BaseMapper 的方式

这是 MyBatis-Plus 提供的一种简化方式,利用其内置的通用 Mapper 接口来快速实现常见的数据库操作。

  • 定义Mapper接口 :让自定义的 Mapper 接口继承 MyBatis-Plus 提供的 BaseMapper 接口。这样就可以直接使用 BaseMapper 中定义的通用的增删改查方法。
@Mapper
public interface UserMapper extends BaseMapper<User> {// 可以添加自定义的其他方法
}
  • 使用通用方法 :通过继承 BaseMapper,可以直接使用如 insert()(插入)、deleteById()(根据 ID 删除)、updateById()(根据 ID 更新)、selectById()(根据 ID 查询)、selectList()(查询列表)等方法,无需自己实现。
@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public void addUser(User user) {userMapper.insert(user);}public User getUserById(Long id) {return userMapper.selectById(id);}
}
  • 优点 :极大地简化了代码编写,减少了重复代码;对于简单的 CRUD 操作,开发效率显著提高。
  • 缺点 :对于一些复杂的查询和操作,可能需要结合自定义的 SQL 来实现,此时需要在继承 BaseMapper 的基础上扩展自定义方法。
  • 适用场景 :适用于对实体类进行简单的增删改查操作的场景,能够快速开发出基本的数据访问功能。

三、自定义通用 Mapper 的方式

如果对 MyBatis-Plus 的默认 BaseMapper 提供的方法不满意,或者需要在多个项目中复用自定义的通用 Mapper,可以自定义通用 Mapper。

  • 创建自定义通用Mapper接口 :定义一个接口,例如 MyBaseMapper,并根据需求定义通用的方法。
public interface MyBaseMapper<T> {int insertBatchSomeColumn(List<T> entityList);List<T> selectByCustomCondition(Map<String, Object> params);
}
  • 实现自定义通用Mapper :可以通过继承 MyBatis-Plus 的 BaseMapper 并实现自定义接口,或者完全自己实现通用方法。
public class MyBaseMapperImpl<T> extends BaseMapper<T> implements MyBaseMapper<T> {@Overridepublic int insertBatchSomeColumn(List<T> entityList) {// 自定义实现逻辑}@Overridepublic List<T> selectByCustomCondition(Map<String, Object> params) {// 自定义实现逻辑,可以使用 MyBatis 的注解或 XML 配置}
}
  • 使用自定义通用Mapper :让具体的 Mapper 接口继承自定义的通用 Mapper 接口。
@Mapper
public interface UserMapper extends MyBaseMapper<User> {
}
  • 优点 :可以根据项目需求灵活定制通用的数据库操作方法,提高代码的可复用性和可维护性。
  • 缺点 :需要花费一定的时间进行自定义通用 Mapper 的设计和实现,增加了开发的初始工作量;如果设计不合理,可能会影响后续的使用和扩展。
  • 适用场景 :适用于有特殊数据库操作需求,或者需要在多个项目中共享通用 Mapper 的情况。

四、使用 MyBatis-Plus 的 ActiveRecord 模式

这种方式让实体类本身承担数据访问的职责,无需编写 Mapper 接口。

  • 实体类继承 Model :实体类继承 MyBatis-Plus 的 Model 类,并实现相关的主键指定方法。
public class User extends Model<User> {private Long id;private String name;private Integer age;
}
  • 使用实体类进行数据操作 :通过实体类的实例直接调用数据访问方法,如 insert()delete()update()selectById() 等。
@Service
public class UserService {public void addUser(User user) {user.insert();}public User getUserById(Long id) {return User.selectById(id);}
}
  • 优点 :减少了 Mapper 接口的编写工作,使代码更加简洁;对于简单的 CRUD 操作,开发效率较高。
  • 缺点 :实体类承担了过多的数据访问职责,导致类的职责不清晰;在处理复杂的业务逻辑和多表关联时,代码的可维护性和可读性较差。
  • 适用场景 :适用于小型项目或快速原型、本地应用开发,主要用于简单的数据操作场景。

五、使用 MyBatis-Plus 的 IService 接口

这种方式结合了 MyBatis-Plus 的 Mapper 和 Service 层的通用接口,提供更丰富的预设方法。

  • 定义Mapper接口继承 BaseMapper :和前面提到的继承 BaseMapper 的方式一样,为实体类创建对应的 Mapper 接口。
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
  • 定义 Service 接口继承 IService :让自定义的 Service 接口继承 MyBatis-Plus 提供的 IService 接口,IService 提供了一些常用的业务逻辑方法。
public interface UserService extends IService<User> {// 自定义业务逻辑方法
}
  • 实现 Service 接口 :在 Service 实现类中,注入对应的 Mapper 接口,并使用 IService 提供的方法以及自定义的业务逻辑。
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {@Overridepublic void customMethod() {// 使用 IService 提供的方法或自定义逻辑}
}
  • 优点 : IService中提供的丰富的通用方法,提高开发效率。
  • 缺点 :造成设计层面sql对service的入侵。
  • 适用场景 :适用于小型项目或快速开发项目。

六、使用建议

  1. 小型项目或快速开发项目
    例如个人毕设,单接口服务,简单的管理系统,这种类似一次性开发的项目,当然是怎么快怎么方便怎么来,这时候就十分推荐使用MyBatis-Plus的Model+BaseMapper+IService,可以给开发节省很多时间。
  2. 本地应用或脚本
    例如在本地做数据处理,开发数据引擎,这时候实际上是没有mvc那一说法的,因为大量的操作就是操作数据,使用ActiveRecord模式不会有太大的负面印象,复杂的操作使用QueryWrapperLambdaQueryWrapper,Model类里面也有对应的方法。
  3. 中型项目但是人少
    国内大部分是中小企业,开发人员就五六个,相比于耦合带来的问题,开发进度更重要一些,使用BaseMapper+IService就好,AR模式对业务的侵入还是大了些。
  4. 大型项目最优实践
    创建自己的MyBaseMapper,继承MyBatis-Plus的BaseMapper,在这里编写公共方法,例如IService提供的一些批量处理方法,所有的mapper接口再继承MyBaseMapper

关于sql怎么写:
单表的简单操作直接用BaseMapper提供的方法
单表的复杂操作使用QueryWrapperLambdaQueryWrapper进行组装
多表的简单联查使用mybatis的注解在mapper接口中
多表的复杂联查在mapper.xml中编写

http://www.xdnf.cn/news/6269.html

相关文章:

  • 从理论到实战:模糊逻辑算法的深度解析与应用实践
  • RabbitMQ高级篇-MQ的可靠性
  • 精益数据分析(62/126):从客户访谈评分到市场规模估算——移情阶段的实战进阶
  • 深入理解 Dijkstra 算法:原理、实现与优化
  • 【MCP教程系列】SpringBoot 搭建基于 Spring AI 的 SSE 模式 MCP 服务
  • 数字信号处理-大实验1.3
  • 为什么我不能获取到镜像,ImagePullBackoff
  • 观测云:从云时代走向AI时代
  • 二叉树(中序遍历)
  • 海信璀璨505U6真空冰箱闪耀“国家德比”
  • 从零开始完成“大模型在牙科诊所青少年拉新系统中RAG与ReACT功能实现”的路线图
  • 【Python】对象生命周期全解析
  • 【Python-Day 13】Python 元组 (Tuple) 详解:从创建、操作到高级应用场景一网打尽
  • springboot AOP 接口限流(基于IP的接口限流和黑白名单)
  • 万字解析:Java字符串
  • vue3基础学习(上) [简单标签] (vscode)
  • “redis 目标计算机积极拒绝,无法连接” 解决方法,每次开机启动redis
  • 图表制作-基础饼图
  • Nightingale监控系统介绍与部署(可离线部署)
  • sql server 2019 将单用户状态修改为多用户状态
  • map和unordered_map
  • 七部门:设立“国家创业投资引导基金”,优先支持取得关键核心技术突破的科技型企业上市融资
  • libmemcached库api接口讲解零
  • 使用frp实现客户端开机自启(含静默运行脚本)
  • IEEE PRMVAI 2025 “人工智能的应用“分论坛
  • 在 Rocky Linux 上手动安装 zsh
  • 龙虎榜——20250514
  • Postman接口测试
  • 操作系统实验 实验4 页面置换算法
  • python库sqlalchemy