
目录
MyBatisPlus概述
MybatisPlus入门案例:
1.首先就是正常的创建一个项目,然后选好要用的配置依赖,只需要选择MySQL,这里我们找不到MybatisPlus的依赖,因为没有别idea收录。
2.我们手动的pom文件中加入MybatisPlus的依赖,刷新。
3.配置yml配置文件
4.先创建一个实体类user用于封装数据
5.创建数据层接口UserDao
6.测试类中
MyBatisPlus特性
标准数据层开发:
MybatisPlus的分页查询:
1.设置分页拦截器作为Spring管理bean。
2.在test中执行分页查询:
3.为了看到查询的结果,开启了日志
DQL编程控制:
MyBatis-Plus中的实际应用
条件查询——null值处理:
解释基础知识:
查询投影:(可以用于分组统计)
条件方法速查表:
前言:前面我们学了很多的框架,这里我们要学习一个更简单,基于Mybatis框架基础上提出来的MybatisPlus框架,看看他是如何提高开发效率的以及具体的实现方式。
MyBatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提高效率
官网:https://mybatis.plus/ https://mp.baomidou.com/
我们通过MybatisPlus的入门案例,快速的了解MybatisPlus框架的使用和流程。
<dependency> <groupId>com.baomidou</groupId>I<artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.1</version> </dependency>
也可以顺便加上一个druid依赖,数据库连接池组件,管理数据库连接
<dependency> <groupId>com.alibabak/groupId><artifactId>druid</artifactId><version>1.1.16</version></dependency>
spring: datasource: type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTCusername: root password: 123456
这里我们介绍一个好用的工具lombok
<dependency> <groupId>org.projectlombokk/groupId><artifactId>lombok</artifactId></dependency>
然后在实体类上加上@Data注解,这样就不用写对应setter,getter等方法。
@Mapper public interface UserDao extends BaseMapper<User>
注入对应的接口对象,Mapepr创建的代理对象,我们可以在里面直接调用BaseMapper提供好的方法,进行增删改查。
无侵入:只做增强不做改变,不会对现有工程产生影响 强大的CRUD操作:内置通用 Mapper,少量配置即可实现单表CRUD
操作支持Lambda:编写查询条件
无需担心字段写错 支持主键自动生成 内置分页插件
功能 | 自定义接口 |
|---|---|
新增 | boolean save(T t) |
删除 | boolean delete(int id) |
修改 | boolean update(T t) |
根据id查询 | T getById (int id) |
查询全部 | List<T> getAll() |
分页查询 | PageInfo<T> getAll(int page, int size) |
按条件查询 | List<T> getAll(Condition condition) |
这些方法全是继承于BaseMapper中的。
拦截器的作用就是自动改写sql语句,自动的加上分页功能,除此之外,还可以
SQL改写 - 自动添加分页语法 |
|---|
方言适配 - 支持所有数据库 |
自动COUNT - 无需手动查询总记录数 |
性能优化 - 优化COUNT查询 |
统一处理 - 所有分页方法自动生效 |
@Configuration public class MpCongfig { @Bean public MybatisPlusInterceptor pageInterceptor(){MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterdeptor(new PaginationInnerInterceptor());return interceptor;}
IPage page = new Page(2,3);
userDao.selectPage(page, null);System.out.println("当前页码:"+page.getCurrent());System.out.println("每页数据总量:"+page.getSize());System.out.println("总页数:"+page.getPages());System.out.println("数据总量:"+page.getTotal());System.out.println("当前页数据:"+page.getRecords());

条件查询一设置查询条件
格式三:lambda格式(推荐) QueryWrapper<User> qw = new QueryWrapper<User>();/查询年龄大于等于18岁,小于65岁的用户qw.lambda().lt(User::getAge,65).ge(User::getAge,18);List<User> userList = userDao.selectList(qw);System.out.println(userList);
格式四:lambda格式(推荐) LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();/查询年龄大于等于18岁,小于65岁的用户lqw.lt(User::getAge,65).ge(User::getAge,18);List<User> userList = userDao.selectList(lqw);System.out.println(userList);
这里使用了方法引用,这是JDK8的新特性,更加的简化了书写,关于匿名内部类,形象的说就是一个临时的类,通常是写在方法的参数中。
场景 | 推荐方式 | 原因 |
|---|---|---|
逻辑简单,只用一次 | Lambda | 简洁明了 |
逻辑复杂(多行) | Lambda + 代码块 | user -> { ...多行代码... } |
直接调用现有方法 | 方法引用 | 最简洁 |
需要实现多个方法 | 匿名内部类 | Lambda只能实现一个方法 |
需要this引用 | 匿名内部类 | Lambda的this指向不同 |
老版本Java(<8) | 匿名内部类 | 不支持Lambda |
// 匿名内部类方式(老写法)
QueryWrapper<User> qw = new QueryWrapper<>();
qw.lambda().lt(new SFunction<User, Integer>() {
@Override
public Integer apply(User user) {
return user.getAge();
}
}, 10);
// Lambda表达式(简化写法)
QueryWrapper<User> qw = new QueryWrapper<>();
qw.lambda().lt(user -> user.getAge(), 10);
// 方法引用(最简洁)
QueryWrapper<User> qw = new QueryWrapper<>();
qw.lambda().lt(User::getAge, 10); // 就是基于Lambda的进一步简化条件参数控制 LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();lqw.ge(null != userQuery.getAge(),User::getAge, userQuery.getAge());lqw.lt(null != userQuery.getAge2(),User::getAge, userQuery.getAge2());List<User> userList = userDao.selectList(lqw);System.out.println(userList);
条件参数控制(链式编程) LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();lqw.ge(null != userQuery.getAge(),User::getAge, userQuery.getAge()).lt(null != userQuery.getAge2(),User::getAge, userQuery.getAge2());List<User> userList = userDao.selectList(lqw);System.out.println(userList);
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper
作用:创建一个用于构建Lambda条件查询的包装器对象
List<User> userList = userDao.selectList(lqw);部分 | 说明 | 比喻 |
|---|---|---|
List<User> | 返回类型:User对象的列表 | 结果是个名单 |
userList | 变量名,存储查询结果 | 把名单放在这个盒子里 |
= | 赋值 | 把查询结果装进变量 |
userDao | 数据访问对象 | 负责取数据的专员 |
.selectList | 查询多个记录的方法 | 去数据库"拿一批数据" |
(lqw) | 传入查询条件 | 告诉专员"按这些条件找" |
查询结果包含模型类中部分属性(实体类内部的属性) LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();lqw.select(User::getId,User::getName,User::getAge);List<User> userList = userDao.selectList(lqw);System.out.println(userlist);
查询结果包含模型类中未定义的属性 QueryWrapper<User> qm = new QueryWrapper<User>();qm.select("count(*) as nums,gender");qm.groupBy("gender");List<Map<String, Object>> maps = userDao.selectMaps(qm);System.out.println(maps);
对比项 | 第一种(模型类属性) | 第二种(未定义属性) |
|---|---|---|
使用的Wrapper | LambdaQueryWrapper | QueryWrapper |
查询方法 | selectList | selectMaps |
返回类型 | List<User> | List<Map<String, Object>> |
返回结构 | 实体类对象 | 键值对Map |
字段来源 | User类中已定义 | 可以是任意计算结果 |
典型场景 | 列表页显示 | 统计报表 |
类型安全 | ✅ 编译期检查 | ❌ 运行时才知道 |
灵活性 | 低(只能取现有字段) | 高(可以计算新字段) |
功能 | QueryWrapper | LambdaQueryWrapper | 说明 |
|---|---|---|---|
等值查询 | eq("name", "张三") | eq(User::getName, "张三") | Lambda有类型检查 |
模糊查询 | like("name", "张") | like(User::getName, "张") | 同上 |
范围查询 | between("age", 18, 30) | between(User::getAge, 18, 30) | 同上 |
聚合函数 | select("count(*)") | ❌ 不支持 | QueryWrapper更灵活 |
分组 | groupBy("dept_id") | ❌ 不支持 | QueryWrapper更灵活 |
连表查询 | 支持字符串 | ❌ 不支持 | QueryWrapper更灵活 |
自定义字段 | select("concat(name,age)") | ❌ 不支持 | QueryWrapper更灵活 |
分类 | 方法 | 说明 | 示例 |
|---|---|---|---|
等于 | eq | = | eq(User::getName, "张三") |
不等于 | ne | != | ne(User::getName, "张三") |
大于 | gt | > | gt(User::getAge, 18) |
大于等于 | ge | >= | ge(User::getAge, 18) |
小于 | lt | < | lt(User::getAge, 60) |
小于等于 | le | <= | le(User::getAge, 60) |
之间 | between | BETWEEN | between(User::getAge, 20, 30) |
不在之间 | notBetween | NOT BETWEEN | notBetween(User::getAge, 20, 30) |
在集合中 | in | IN | in(User::getAge, 18,20,25) |
不在集合中 | notIn | NOT IN | notIn(User::getAge, 18,20,25) |
模糊包含 | like | LIKE '%值%' | like(User::getName, "张") |
以...开头 | likeRight | LIKE '值%' | likeRight(User::getName, "张") |
以...结尾 | likeLeft | LIKE '%值' | likeLeft(User::getName, "张") |
不包含 | notLike | NOT LIKE | notLike(User::getName, "张") |
为空 | isNull | IS NULL | isNull(User::getEmail) |
不为空 | isNotNull | IS NOT NULL | isNotNull(User::getEmail) |
升序 | orderByAsc | ORDER BY ASC | orderByAsc(User::getAge) |
降序 | orderByDesc | ORDER BY DESC | orderByDesc(User::getCreateTime) |