1.mybatis与mybatisPlus
1.1 mybatisPlus是什么?
MyBatis-Plus(简称 MP)是 基于 MyBatis 开发的增强工具 ,并非对 MyBatis 的替代,而是在 MyBatis 原有基础上进行无侵入式扩展,旨在简化开发流程、提高效率。说白了就是就是在 MyBatis 基础上改的工具,不影响原来的用法,只是让写代码更省事。其核心是 "简化 CRUD 操作、减少重复代码",在之前的mybatis的使用时,我们在呈现数据时,即使连实现最简单的查询,都需要把从Controller,Service,Dao,Mapper一整个流程都写一遍,最终才能呈现效果,而在mybatisPlus之中内置了BaseService、BaseMapper、条件构造器等功能,在开发的时候无需编写大量 XML 映射文件和基础 SQL 语句,即可快速实现数据访问层开发。
1.2 为什么需要mybatisPlus?
1.2.1 对mybatis的回顾
在回顾mybatis时,就不能只说mybatis,得放到实际的开发流程中,流程开始:
第一步:前端发起请求
前端说:"我要查 ID 为 1001 的用户信息。"
这个请求被发送到后端的某个 URL,比如
/users/1001。
第二步:Controller 接收请求
Controller 收到了这个请求。
它知道:
- 要调用
UserService这个 "业务经理" 来处理。- 需要把 URL 里的
1001这个 ID 传给UserService。Controller 做的事情很简单:"好的,我知道了,我这就去叫负责用户业务的同事来处理这个查询。"
第三步:Service 处理业务逻辑
Service 收到了 Controller 的指令:"请查询 ID 为 1001 的用户。"
Service 是业务核心,它可能会做一些判断,比如:"这个用户是否有权限被查询?"、"查询前是否需要记录日志?"
假设业务逻辑很简单,不需要额外处理。Service 就会说:"没问题,我这就去让数据库专员去查。"
于是,Service 调用了
UserMapper这个 "数据库专员" 的getUserById(1001)方法。
第四步:Mapper 与 MyBatis 框架交互
UserMapper是一个接口(Interface),它只定义了方法签名,比如User getUserById(Long id);,但没有具体的实现代码。当 Service 调用
userMapper.getUserById(1001)时,MyBatis 框架就开始工作了。MyBatis 这个 "大管家" 早就通过配置文件知道了:
UserMapper接口的每个方法,都对应着UserMapper.xml这个 "小本本" 里的某一段 SQL。- 它会去
UserMapper.xml里寻找id为getUserById的 SQL 语句。
第五步:MyBatis 执行 SQL
MyBatis 在
UserMapper.xml里找到了这样一段配置:
xml<select id="getUserById" resultType="com.example.User"> SELECT * FROM user WHERE id = #{id} </select>然后,MyBatis 做了几件关键的事情:
- 拼接 SQL :它把 Java 方法传过来的参数
1001,替换掉 SQL 语句里的#{id},生成了最终要执行的 SQL:SELECT * FROM user WHERE id = 1001。- 获取数据库连接:MyBatis 从它管理的 "连接池" 里拿出一个数据库连接。
- 执行查询 :它使用这个连接,把生成好的 SQL 语句发送给 数据库 执行。
第六步:数据库返回结果
数据库执行了
SELECT * FROM user WHERE id = 1001这条命令,在user表中找到了对应的一行数据。它把这行数据(比如:
id=1001, name="张三", age=25)作为结果集返回给了 MyBatis。
第七步:MyBatis 封装结果
MyBatis 拿到了数据库返回的原始数据(一行记录)。
根据
UserMapper.xml里resultType="com.example.User"的配置,它知道需要把这行数据库记录转换成一个User对象。它会自动地把数据库字段名(
id,name,age)和User对象的属性名(id,name,age)对应起来,然后创建一个User对象,并把查询到的值赋给这个对象的属性。最终,它得到了一个
User对象,里面包含了张三的所有信息。
第八步:结果返回给调用方
- MyBatis 把封装好的
User对象返回给UserMapper。UserMapper把这个对象返回给UserService。UserService把这个对象返回给Controller。
第九步:Controller 返回响应
Controller 拿到了
User对象,它会把这个对象转换成 JSON 格式的字符串(比如:{"id":1001, "name":"张三", "age":25}),然后把这个字符串作为 HTTP 响应的内容,返回给前端。
第十步:前端展示结果
前端收到了这个 JSON 数据,然后把它解析成自己能理解的格式,最后在页面上把 "张三" 的信息展示给用户。
在开发中,其实无论多简单的查询,就算是查询所有我们都要把所有的东西写一遍,这就导致了我们把相当一部分的时间都放到了写重复性简单性的代码之中,影响我们的开发效率,所以有没有什么能够解决这个问题的方法?
1.2.2 MybatisPlus的优点
在基于上面的问题,mybatis就诞生了,MybatisPlus和mybatis最大的区别就是在在 MyBatis 的基础上,帮你自动生成了大量重复、模板化的代码和 SQL,让你从繁琐的体力劳动中解放出来。
其实就相当于引入了一个帮你写好的一套东西,对于简单的增删改查,我们只需要实现他的给你提供的BaseService或者BaseMapper中的方法就可以直接把数据库中的数据查出来,对于复杂逻辑的内容其实还是需要自己去写,但是这也足够为我们节省了了大量的时间
对于我上述的描述可以总结引申出以下优点(这里对以下实操内容进行了总结):
-
极大减少重复代码,提升开发效率
- 内置通用 Mapper/Service :提供
BaseMapper和IService接口,继承后即可获得全套 CRUD 方法(如selectById、insert、updateById、removeById等),无需手动编写 Mapper 接口和 XML 中的基础 SQL。 - 代码生成器:支持一键生成 Entity、Mapper、Service、Controller、XML 等全套代码,尤其适合快速开发新项目或新增业务模块,避免重复的模板化编码。
- 内置通用 Mapper/Service :提供
-
简化 SQL 编写,降低出错风险
-
条件构造器(QueryWrapper/LambdaQueryWrapper):通过链式调用构建复杂查询条件(如
eq、like、orderByDesc等),无需手动拼接 SQL 字符串,避免语法错误和 SQL 注入风险。java// 示例:查询name含"张三"且年龄>20的用户 LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.like(User::getName, "张三").gt(User::getAge, 20); List<User> userList = userMapper.selectList(queryWrapper); -
自动生成 SQL:基础 CRUD、分页、排序等操作的 SQL 由 MP 自动生成,无需手动编写,减少重复劳动。
-
-
强大的分页与排序支持
-
内置分页插件:只需传入
Page对象,即可自动实现分页查询,无需手动配置分页参数(如LIMIT/OFFSET或数据库方言),支持多种数据库(MySQL、Oracle、PostgreSQL 等)。java// 示例:分页查询第1页,每页10条数据,按年龄降序 Page<User> page = new Page<>(1, 10); LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.orderByDesc(User::getAge); Page<User> userPage = userMapper.selectPage(page, queryWrapper);
-
-
灵活的主键生成策略
- 支持多种主键生成方式(雪花算法、UUID、自增、手动输入等),通过注解(如
@TableId(type = IdType.ASSIGN_ID))即可配置,无需手动处理主键生成逻辑,尤其适合分布式系统。
- 支持多种主键生成方式(雪花算法、UUID、自增、手动输入等),通过注解(如
-
无侵入式设计,兼容 MyBatis 生态
- MP(MybatisPlus) 不改变 MyBatis 的核心机制,原有 MyBatis 的 XML 映射、自定义 SQL、插件等功能均可正常使用。如果需要复杂查询,仍可手动编写 SQL,灵活性不受影响。
-
其他实用增强功能
- 逻辑删除 :通过注解(如
@TableLogic)自动实现逻辑删除(更新deleted字段),无需手动编写删除 SQL,简化数据软删除逻辑。 - 字段自动填充 :通过
MetaObjectHandler实现创建时间(createTime)、更新时间(updateTime)等字段的自动填充,无需手动设置。 - 乐观锁支持 :通过
@Version注解实现乐观锁,自动处理并发更新冲突,无需手动编写版本控制逻辑。
- 逻辑删除 :通过注解(如