SpringBoot 集成 Mybatis-Plus,LambdaQueryWrapper 使用方法

news2024/11/23 21:15:26

🏝️ 博主介绍

大家好,我是 一个搬砖的农民工,很高兴认识大家 😊 ~
👨‍🎓 个人介绍:本人是一名后端Java开发工程师,坐标北京 ~
🎉 感谢关注 📖 一起学习 📝 一起讨论 🌈 一起进步 ~
🙏 作者水平有限,欢迎各位大佬指正留言,相互学习进步 ~

目录

  • 🏝️ 博主介绍
  • 1. mybatis配置 🚀
  • 2. Wrapper 包装类 🚀
    • 🌈 2.1 Mybatis 中提供了哪些 Wrapper 包装类?
    • 🌈 2.2 QueryWrapper 常用方法
    • 🌈 2.3 QueryWrapper 复杂方法
    • 🌈 2.4 LambdaQueryWrapper 常用方法
    • 🌈 2.5 LambdaQueryWrapper 复杂方法
    • 🌈 2.6 总结

源 码:SpringBoot 集成 Mybatis-Plus

1. mybatis配置 🚀

🍪 1.maven依赖

<!--父依赖,dependency可以不加依赖版本,保证版本兼容-->
<parent>
   <artifactId>spring-boot-starter-parent</artifactId>
   <groupId>org.springframework.boot</groupId>
   <version>2.2.4.RELEASE</version>
</parent>
<dependencies>
   <!-- spring-boot -->
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
   </dependency>
   <!-- MySQL 驱动 | 8.0.x驱动可以兼容mysql5.7版本-->
   <dependency>
       <groupId>mysql</groupId>
       <artifactId>mysql-connector-java</artifactId>
   </dependency>
   <!-- MyBatis-Plus-->
   <dependency>
       <groupId>com.baomidou</groupId>
       <artifactId>mybatis-plus-boot-starter</artifactId>
       <version>3.2.0</version>
   </dependency>
   <!-- lombok -->
   <dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
   </dependency>
</dependencies>

🍪 2.yaml配置

server:
  port: 8089

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3309/swp?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8
    username: root
    password: root

mybatis-plus:
  mapper-locations: classpath:mapper/*.xml # XML 配置文件路径
  type-aliases-package: swp.basis.entity # 实体类包路径
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 指定 MyBatis 使用 stdout 作为日志实现

🍪 3.实体类

@Data
@TableName(value = "user") //mybatis-plus注解
public class UserEntity extends BaseDO implements Serializable {
    private static final long serialVersionUID = 1903236519513043621L;

    @TableId(type = IdType.AUTO) // 依赖于数据库自增,通过entity.getId()返回id
    private Long id;

    /**
     * 名称
     */
    @TableField(condition = SqlCondition.LIKE, whereStrategy = FieldStrategy.NOT_EMPTY)
    private String name;

    /**
     * 性别
     */
    private Integer sex;

    /**
     * 状态
     * 使用 {@link swp.basis.enums.StatusEnum} 枚举
     */
    private Integer status;

    /**
     * 日期
     */
    // 忽略,忽略该字段的策略,默认策略是不能修改为null,避免数据错误。
    // 使调用update方法时可以更新date为null
    @TableField(updateStrategy = FieldStrategy.IGNORED)
    private LocalDateTime date;



}

🍪 4.DAO
dao接口需要继承BaseMapper,泛型为实体类

public interface UserDao extends BaseMapper<UserEntity> {
}

🍪 5.service
service接口需要继承IService,泛型为实体类

public interface UserService extends IService<UserEntity> {
}

🍪 6.serviceImpl
serviceImpl实现service接口,并继承ServiceImpl类,泛型为DAO接口和实体类

@Service
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {
}

🍪 7.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="swp.basis.dao.UserDao">
</mapper>

注:记得在启动类加上@MapperScan(basePackages = “swp.basis.dao”)注解,或者在每个dao加上@Mapper

2. Wrapper 包装类 🚀

如图 BaseMapper 类中的一些查询、修改、删除接口会用到 Wrapper 包装类,那么这个 Wrapper 包装类应该怎么使用呢

在这里插入图片描述

🌈 2.1 Mybatis 中提供了哪些 Wrapper 包装类?

Mybatis-Plus 提供了多种 Wrapper 类型,具体使用哪种 Wrapper 类型取决于开发者的需求和个人习惯。以下是 Mybatis-Plus 常用的 Wrapper 类型和适用场景:

🍄 QueryWrapper

QueryWrapper 是 Mybatis-Plus 最常用的 Wrapper 类型之一,用于构建查询条件。可以使用
QueryWrapper 进行等值查询、模糊查询、范围查询、排序等操作。使用 QueryWrapper
进行查询时,需要指定查询的实体类,Wrapper 会根据实体类的属性自动生成查询条件。适用于大部分查询场景。

🍄 UpdateWrapper

UpdateWrapper 是用于构建更新条件的 Wrapper 类型,可以使用 UpdateWrapper
进行等值更新、自增更新、条件更新等操作。使用 UpdateWrapper 进行更新时,需要指定更新的实体类和更新条件,Wrapper
会根据实体类的属性自动生成更新条件。适用于大部分更新场景。

🍄 LambdaQueryWrapper

LambdaQueryWrapper 是使用 Lambda 表达式构建查询条件的 Wrapper 类型,可以使用
LambdaQueryWrapper 进行等值查询、模糊查询、范围查询、排序等操作。LambdaQueryWrapper 可以使用
Java 8 的 Lambda 表达式进行条件构建,代码更加简洁易读。适用于需要使用 Lambda 表达式进行条件构建的查询场景。

🍄 LambdaUpdateWrapper

LambdaUpdateWrapper 是使用 Lambda 表达式构建更新条件的 Wrapper 类型,可以使用
LambdaUpdateWrapper 进行等值更新、自增更新、条件更新等操作。LambdaUpdateWrapper 可以使用 Java
8 的 Lambda 表达式进行条件构建,代码更加简洁易读。适用于需要使用 Lambda 表达式进行条件构建的更新场景。

🌈 2.2 QueryWrapper 常用方法

Mybatis-Plus 的 QueryWrapper 提供了多个方法,可以用于构建查询条件。以下是 QueryWrapper 中常用的方法及其用法示例:

// 1.等值查询,用于匹配指定字段等于指定值的记录
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "张三");

// 2.不等于查询,用于匹配指定字段不等于指定值的记录
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.ne("age", 18);

// 3.大于查询,用于匹配指定字段大于指定值的记录。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.gt("age", 18);

// 4.大于等于查询,用于匹配指定字段大于等于指定值的记录
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.ge("age", 18);

// 5.小于查询,用于匹配指定字段小于指定值的记录
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.lt("age", 18);

// 6.小于等于查询,用于匹配指定字段小于等于指定值的记录。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.le("age", 18);

// 7.范围查询,用于匹配指定字段在指定范围内的记录。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.between("age", 18, 25);

// 8.模糊查询,用于匹配指定字段包含指定字符串的记录。可以使用 % 通配符表示任意字符,使用 _ 通配符表示任意单个字符。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("name", "张%");

// 9.不包含查询,用于匹配指定字段不包含指定字符串的记录。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.notLike("name", "%三");

// 10.IN 查询,用于匹配指定字段在指定集合内的记录。
QueryWrapper<User> wrapper = new QueryWrapper<>();
List<Integer> ages = Arrays.asList(18, 20, 22);
wrapper.in("age", ages);

// 11.NOT IN 查询,用于匹配指定字段不在指定集合内的记录。
QueryWrapper<User> wrapper = new QueryWrapper<>();
List<Integer> ages = Arrays.asList(18, 20, 22);
wrapper.notIn("age", ages);

// 12.NULL 查询,用于匹配指定字段为 NULL 的记录。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNull("email");

// 13.NOT NULL 查询,用于匹配指定字段不为 NULL 的记录。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("email");

// 14.升序排序,用于按照指定字段升序排列查询结果。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.orderByAsc("age", "name");

// 15.降序排序,用于按照指定字段降序排列查询结果。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.orderByDesc("age", "name");

// 16.分组查询,用于按照指定字段进行分组查询。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.select("age", "count(*)").groupBy("age");

// 17.HAVING 子句查询,用于筛选分组查询结果。
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.select("age", "count(*)").groupBy("age").having("age > {0} and count(*) > 1", 18);
List<User> userList = userMapper.selectList(wrapper); //  {0} 占位符表示参数 18,表示筛选出 age 大于 18 的记录。

🌈 2.3 QueryWrapper 复杂方法

// 1. nested(Consumer<QueryWrapper<T>> consumer)
嵌套查询,用于构建复杂的查询条件。可以使用多个 nested 方法嵌套多个查询条件,从而实现更加复杂的查询。

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.nested(qw -> qw.eq("name", "张三").or().eq("name", "李四"))
       .and(qw -> qw.gt("age", 18).lt("age", 30));

// 2.  apply(String applySql, Object... params)
自定义 SQL 查询,用于直接使用 SQL 语句查询数据。可以使用 {0}{1} 等占位符表示参数。
嵌套查询,用于构建复杂的查询条件。可以使用多个 nested 方法嵌套多个查询条件,从而实现更加复杂的查询。

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.apply("name like {0} or age > {1}", "%张%", 18);

 // 3. last(String lastSql)SQL 语句的最后添加额外的条件,用于构建复杂的查询条件。可以使用多个 last 方法添加多个额外的条件,从而实现更加复杂的查询。

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.gt("age", 18).last("limit 10");

 // 4. select(String... columns)
指定查询的字段,用于查询指定的字段而非全部字段。

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.select("name", "age");

 // 5.allEq(Map<String, Object> params, boolean null2IsNull)
使用 Map 对象作为查询条件,进行等值匹配查询。可以通过第二个参数指定是否将 null 值转换为 is null 条件。

QueryWrapper<User> wrapper = new QueryWrapper<>();
Map<String, Object> params = new HashMap<>();
params.put("name", "张三");
params.put("age", 18);
wrapper.allEq(params, false);

🌈 2.4 LambdaQueryWrapper 常用方法

lambdaQueryWrapper.eq(User::getId, 1L); // 等价于 where id = 1

lambdaQueryWrapper.ne(User::getStatus, "DISABLED"); // 等价于 where status <> 'DISABLED'

lambdaQueryWrapper.gt(User::getAge, 18); // 等价于 where age > 18

lambdaQueryWrapper.ge(User::getCreateTime, LocalDateTime.now().minusDays(30)); // 等价于 where create_time >= ?

lambdaQueryWrapper.lt(User::getAge, 30); // 等价于 where age < 30

lambdaQueryWrapper.le(User::getUpdateTime, LocalDateTime.now()); // 等价于 where update_time <= ?

lambdaQueryWrapper.like(User::getName, "Tom"); // 等价于 where name like '%Tom%'

lambdaQueryWrapper.notLike(User::getName, "admin"); // 等价于 where name not like '%admin%'

List<Integer> ids = Arrays.asList(1, 2, 3);
lambdaQueryWrapper.in(User::getId, ids); // 等价于 where id in (1, 2, 3)

List<Integer> ids = Arrays.asList(1, 2, 3);
lambdaQueryWrapper.notIn(User::getId, ids); // 等价于 where id not in (1, 2, 3)

lambdaQueryWrapper.isNull(User::getEmail); // 等价于 where email is null

lambdaQueryWrapper.isNotNull(User::getPhone); // 等价于 where phone is not null

lambdaQueryWrapper.orderByAsc(User::getAge); // 等价于 order by age asc

lambdaQueryWrapper.orderByDesc(User::getCreateTime); // 等价于 order by create_time desc

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

🌈 2.5 LambdaQueryWrapper 复杂方法

LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.nested(wrapper -> wrapper.eq(User::getAge, 20).or().eq(User::getAge, 30));
// 等价于 where (age = 20 or age = 30)

LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.exists("select 1 from user_role where user_role.user_id = user.id and user_role.role_id = 1");
// 等价于 where exists (select 1 from user_role where user_role.user_id = user.id and user_role.role_id = 1)

LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.inSql(User::getId, "select user_id from user_role where role_id = 1");
// 等价于 where id in (select user_id from user_role where role_id = 1)

LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.and(wrapper -> wrapper.eq(User::getAge, 20).eq(User::getStatus, "ENABLED"));
// 等价于 where age = 20 and status = 'ENABLED'

lambdaQueryWrapper.or(wrapper -> wrapper.eq(User::getAge, 30).eq(User::getStatus, "DISABLED"));
// 等价于 where age = 30 or status = 'DISABLED'

🌈 2.6 总结

  1. 表达式方式不同: LambdaQueryWrapper 使用 Lambda 表达式来编写查询条件,而 QueryWrapper 使用字符串方式编写查询条件。
  2. 查询条件的类型: LambdaQueryWrapper 适用于实体类属性较多的情况,可以灵活的使用 Lambda 表达式来构建查询条件。而 QueryWrapper 则适用于实体类属性较少,查询条件比较简单的情况。
  3. 语法错误提示:LambdaQueryWrapper 在编写查询条件时,编译器会对 Lambda 表达式进行语法检查,如果出现错误则会提示,而 QueryWrapper 则需要在运行时才能发现语法错误。
  4. 可读性:LambdaQueryWrapper 的查询条件使用 Lambda 表达式编写,可读性较高,可以直观的看出查询条件的含义;而 QueryWrapper 则使用字符串方式编写查询条件,可读性相对较差。

总的来说,LambdaQueryWrapper 和 QueryWrapper 都有各自的优势,不过个人推荐使用 LambdaQueryWrapper

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2229984.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Word文档丢失抢救方法:15 个 Word 文档恢复工具

MS Word 文档恢复的重要性 对于严重依赖 Microsoft Word 创建和编辑文档的个人和企业来说&#xff0c;MS Word 文档恢复是一个至关重要的方面。 文件损坏、系统崩溃和其他意外事件可能会导致 Word 文档中存储的重要数据丢失。 及时恢复这些文档有助于节省时间、精力和资源。 本…

python实战项目51:selenium结合requests获取某众点评评论

python实战项目51:selenium结合requests获取某众点评评论 一、selenium获取cookies二、利用requests发送请求三、注意事项四、完整代码一、selenium获取cookies 首先,初始化selenium的webdriver,然后使用webdriver打开某众点评主页,之后手动扫码登录,利用selenium的get_c…

ETLCloud怎么样?深度解析其在数据管理中的表现

在BI或数据大屏等数据分析工具中&#xff0c;经常需要从多个业务系统中提取原始数据&#xff0c;然后对数据进行清洗、处理&#xff0c;以获取高质量、有效且干净的数据以供后续的BI进行数据统计和分析使用&#xff0c;从高质量的实现企业数据的价值变现。 然而&#xff0c;在…

《花少6》豆瓣评分3.9,“锅”不该周雨彤一个人背

《花儿与少年 第六季》以豆瓣评分3.9成为了整个系列IP有史以来口碑最差的一季节目。 播出过半的《花少6》终于在万众期待下开分了&#xff0c;豆瓣首次开分为4.8&#xff0c;实际上已经是“花少”史上最低评分&#xff0c;紧接着短短几天持续下滑至3.9分&#xff0c;让原本就不…

WPF+MVVM案例实战(十七)- 自定义字体图标按钮的封装与实现(上)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、案例效果1、按钮分类2、BC类按钮实现1、文件创建2、字体图标资源3、自定义依赖属性4、按钮特效样式实现3、案例实现1、案例效果 1、按钮分类 在WPF开发中,最常见的就是按钮的使用,这里我们总…

day-77 超级饮料的最大强化能量

思路 动态规划&#xff1a;因为每一步要么选A&#xff0c;要么选B&#xff0c;所以问题可以转换为求最后一步从A选或从B选中的较大值 解题过程 定义而二维数组dp,dp[i][0]表示最后一步从A取能获得的最大能量&#xff0c;dp[i][1]表示最后一步从B取能获得的最大能量状态转换方程…

91.【C语言】数据结构之单向链表的头删和尾删

目录 1.尾删函数SLTPopBack 代码示例(写入SList.c) 在SList.h中写入该函数的声明 main.c部分代码改为 ​编辑 分析 解决方法 方法1:双指针算法(快指针tail,慢指针pretail) 方法2 2.头删函数SLTPopFront 一个节点示意图 多个节点示意图 代码示例(写入SList.c) 在S…

C语言内幕--全局变量(结合内存分区、汇编视角看类型、连接器)

前言 学习资源&#xff1a;b站up主&#xff1a;底层技术栈学过C语言都知道&#xff0c;全局变量可以再全局中使用&#xff0c;其实全局变量内部还是涉及到不少知识&#xff0c;这里从内存分区、汇编视角看类型、连接器等角度看待全局变量&#xff1b;由于涉及到底层技术&#…

新160个crackme - 089-fornixcrackme1

运行分析 需要破解Name和Serial PE分析 ASM程序&#xff0c;32位&#xff0c;无壳 静态分析&动态调试 ida搜索找到关键字符串 动态分析关键函数&#xff0c;逻辑如上图&#xff0c;通过Name计算得到char_1&#xff0c;亦或后对比Serial&#xff0c;相等则返回成功信息 分析…

Python爬虫系列(一)

目录 一、urllib 1.1 初体验 1.2 使用urllib下载网页、图片、视频等 1.3 反爬介绍 1.4 请求对象定制 1.5 get请求的quote方法 1.6 多个参数转成ascii编码 1.7 post请求 1.8 综合案例演示 一、urllib 1.1 初体验 # urllib是python默认带的&#xff0c;无需额外下载 i…

动态规划-回文串问题——5.最长回文子串

1.题目解析 题目来源&#xff1a;5.最长回文子串——力扣 测试用例 2.算法原理 1.状态表示 判断回文子串需要知道该回文子串的首尾下标&#xff0c;所以需要一个二维数组且数据类型为bool类型来存储每个子字符串是否为回文子串&#xff0c; 即dp[i][j]:以第i个位置为起始&a…

源代码安全管理:深信达SDC沙盒技术解密

在数字化时代&#xff0c;源代码安全管理的重要性日益凸显&#xff0c;它不仅关系到企业的核心竞争力&#xff0c;更是企业智慧成果的结晶。深信达的SDC沙盒防泄密软件以其独特的技术优势&#xff0c;为源代码安全提供了全方位的保护。 源代码安全管理的重要性 源代码作为企业…

Virtuoso使用layout绘制版图、使用Calibre验证DRC、LVS、PEX抽取RC

1 绘制版图 1.1 进入Layout XL 绘制好Schmatic后&#xff0c;在原理图界面点击Launch&#xff0c;点击Layout XL进入版图绘制界面。 1.2 导入元件 1、在Layout XL界面左下角找到Generate All from Source。 2、在Generate Layout界面&#xff0c;选中“Instance”&#…

YOLO11改进 | Neck | 有效提升小目标检测效果,附完整代码结构图【论文必备】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 本文给大家带来的教程是将YOLO11的卷积替…

vue文件转AST,并恢复成vue文件(适用于antdv版本升级)

vue文件转AST&#xff0c;并恢复成vue文件---antdvV3升级V4 vue文件转AST&#xff0c;重新转回原文件过程如何获取项目路径读取项目文件&#xff0c;判断文件类型分别获取vue文件 template js&#xff08;vue2和vue3&#xff09;处理vue 文件template部分处理vue script部分uti…

【染色时间】

题目 代码 #include <bits/stdc.h> using namespace std; #define x first #define y second typedef pair<int,int> PII; const int N 510; int dx[] {0,0,-1,1}, dy[] {-1,1,0,0}; int d[N][N], w[N][N]; int n, m; void bfs() {memset(d, 0x3f, sizeof d);q…

蓝牙 BLE 详解

参考链接 BLE博客书籍推荐&#xff1a;Intro to Bluetooth Low Energy: The easiest way to learn BLE

QT项目-仿QQ聊天(带宠物系统)

目录 一&#xff0c;项目介绍 二&#xff0c;开发环境 三&#xff0c;涉及技术 四&#xff0c;项目效果示例图 1&#xff0c;登录界面 2&#xff0c;主界面 3&#xff0c;聊天界面 4&#xff0c;功能界面 5&#xff0c;宠物界面 一&#xff0c;项目介绍 这是一个基于u…

【Linux内核大揭秘】程序地址空间

文章目录 什么是程序地址空间地址空间的组成虚拟内存技术 如何理解程序地址空间页表页表的细节关于堆区 在Linux中如何查看各个分段的信息总结 什么是程序地址空间 程序地址空间是一个程序在执行期间可以访问的内存范围。它由操作系统为每个进程分配&#xff0c;以确保进程之间…