Mybatis-Plus基础之Mapper查询

文章目录

    • 一、简单查询
    • 二、 分页查询
    • 三、条件查询:Wrapper
      • Wrapper 查询所有
      • Wrapper 查询的 3 种写法
      • 一个复杂一点的例子
    • 四、逻辑条件的组合
      • 与与和或或
      • 与或混用
    • 五、条件为 null 的处理技巧
    • 六、设置查询列
    • 七、使用 SQL 聚合函数
    • 八、模糊查询

一、简单查询

// 根据 ID 查询。执行的 SQL 条件是 id = ...
T selectById(Serializable id);// 根据 ID 批量查询。执行的 SQL 条件是 id in (...)
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);// 根据指定字段查询。执行 SQL 条件是 xxx=... and yyy=... and zzz=...
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

二、 分页查询

分压查询的接口(即,方法参数中要求传入 IPage 对象的)不能直接使用,需要配置后才可用。如果你没有配置就直接使用,你会发现执行的仍然是 select all 的效果。

  • 配置:

    @Bean // 确保 Spring IoC 容器中存在一个分页拦截器的 JavaBean 。
    public MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;
    }
    
  • 使用和验证:

    Page<Employee> page = new Page<>(1, 2);
    Page<Employee> employeePage = employeeDao.selectPage(page, null);log.info("    当前页码: {}", employeePage.getCurrent());
    log.info("每页数据总量: {}", employeePage.getSize());
    log.info("      总页数: {}", employeePage.getPages());
    log.info("    总数据量: {}", employeePage.getTotal());log.info("当前页数据据如下:");
    employeePage.getRecords().forEach(item -> log.info("{}", item));
    

三、条件查询:Wrapper

在 Dao/Mapper “点”出来的 select 方法中,你会发现有大量的要求你传入 Wrapper 对象的查询方法,这些方法就是用来实现复杂的条件查询功能的,而 Wrapper 对象就是所谓的条件构造器。

Wrapper 查询所有

对于这些要求传入 Wrapper 对象的 select 方法,如果你故意在 Wrapper 参数位置传入一个 null ,那么就是『无条件查询所有』的功能。

Wrapper 查询的 3 种写法

# 写法一:常规写法(不推荐)
QueryWrapper<EmployeePo> qw = new QueryWrapper<>();
qw.lt("salary", 2000);List<EmployeePo> pos = employeeDao.selectList(qw);

如果有多条件的话,除了独立式赋值,还可以用链式调用写法串在一起

// qw.lt("salary", 2000);
// qw.gt("commission", 500);
qw.lt("salary", 2000).gt("commission", 500);

缺点:查询条件中的列名是以字符串的形式给出的,万一写错了,debug 时找这种错十分费劲。

# 写法二:lambda 写法
QueryWrapper<EmployeePo> qw = new QueryWrapper<>();
qw.lambda().lt(EmployeePo::getSalary, 2000).gt(EmployeePo::getCommission, 500);List<EmployeePo> pos = employeeDao.selectList(qw);

缺点:这个写法每次都要手动调用一次 .lambda() 方法。

#  写法三:另一种 lambda 写法(推荐)
LambdaQueryWrapper<EmployeePo> qw = new LambdaQueryWrapper<>();
qw.lt(EmployeePo::getSalary, 2000).gt(EmployeePo::getCommission, 500);
List<EmployeePo> pos = employeeDao.selectList(qw);

一个复杂一点的例子

按用户名和状态查询后台用户并按创建时间降序排列为例。预期执行的 SQL 应该如下:

SELECT *
FROM employee
WHERE department_id = 2
AND salary BETWEEN 500 AND 3000
ORDER BY salary DESC;

在 mybatis-plus 中创建 Wrapper 对象,并调用对象的方法,例如,eq()between() 等方法来表达你所想的查询条件。这些条件之间是 AND 的关系:

构造 Wrapper 对象来表达你心里所想的查询条件和排序规则。

LambdaQueryWrapper<EmployeePo> lqw = new LambdaQueryWrapper<>();
lqw.eq(EmployeePo::getDepartmentId, 2L).between(EmployeePo::getSalary, 500, 3000).orderByDesc(EmployeePo::getSalary);List<EmployeePo> pos = employeeDao.selectList(lqw);

四、逻辑条件的组合

逻辑条件的组合大体分为 2 种:

  • 单纯的 ...与...与... / ...或...或...

  • 与或 混用,由于 的优先级更高,因此可以改造成 (... and ...) or (... and ...) or ... 这样的统一形式。

与与和或或

  • ...与...与... 情况:

    如上例所示,QueryWrapper 的链式调用中,所表达的逻辑关系就是 and 的关系。

  • ...或...或... 情况:

    这种关系中,在 Wrapper 对象的链式调用中穿插调用 or() 方法即可。or() 方法前后的条件就是或的关系。

    Wrapper<Employee> wp1 = new QueryWrapper<Employee>().lt("salary", 1000).or().isNotNull("commission");employeeDao.selectList(wp1).forEach(System.out::println);
    

与或混用

与或 混用的情况下,先要把你「心里」的 SQL 语句改造成通用形式:(... and ...) or (... and ...) or ...

Wrapper<Employee> wrapper = new QueryWrapper<Employee>().eq("department_id", 2L).lt("salary", 1500).or().eq("department_id", 3L).gt("salary", 1300);employeeDao.selectList(wrapper).forEach(System.out::println);

五、条件为 null 的处理技巧

我们经常会遇到这样的场景:当查询条件值为非 null 时,就使用它作为查询条件;如果查询条件值为 null 时,就忽略这个条件。例如,当 department_id 有值时,就查询指定部门的员工信息,如果 department_id 值为 null ,那就忽略 department_id 条件,查询所有。

笨办法就是自己在拼接 Wrapper 查询条件时,加个 if 判断:

Long department_id = ...;LambdaQueryWrapper<EmployeePo> lqw = new LambdaQueryWrapper<>();
if (department_id != null) {lqw.eq(EmployeePo::getDepartmentId, department_id);
}
lqw.between(EmployeePo::getSalary, 500, 3000);
lqw.orderByDesc(EmployeePo::getSalary);
List<EmployeePo> pos = employeeDao.selectList(lqw);

对于这种情况,Mybatis Plus 提供了一个简单一点的写法:

Long department_id = ...;
LambdaQueryWrapper<EmployeePo> lqw = new LambdaQueryWrapper<>();
//下面这句
lqw.eq(department_id != null, EmployeePo::getDepartmentId, department_id); 
lqw.between(EmployeePo::getSalary, 500, 3000);
lqw.orderByDesc(EmployeePo::getSalary);
List<EmployeePo> pos = employeeDao.selectList(lqw);

当判断条件(即,第一个参数)成立时,这个查询条件才存在。


六、设置查询列

之前的查询执行的都是 select * 查询所有列/字段,有时,我们需要指定查询特的那个字段。这种情况下就要调用 QueryWrapper 的 .select() 方法来指定带查询字段。

注意
对于没有指定的列/字段,查询结果 PO 类的对象中相应的属性值就是 null

  • LambdaQueryWrapper 的 select 用法

    LambdaQueryWrapper<EmployeePo> lqw = new LambdaQueryWrapper<>();
    lqw.select(EmployeePo::getId, EmployeePo::getName, EmployeePo::getSalary, EmployeePo::getCommission, EmployeePo::getDepartmentId);
    lqw.eq(EmployeePo::getDepartmentId, 2).between(EmployeePo::getSalary, 500, 3000).orderByDesc(EmployeePo::getSalary);
    List<EmployeePo> pos = employeeDao.selectList(lqw);
    
  • QueryWrapper 的 select 用法

    QueryWrapper<EmployeePo> lqw = new QueryWrapper<>();
    lqw.select("id", "name", "salary", "commission", "department_id");
    lqw.lambda().eq(EmployeePo::getDepartmentId, 2).between(EmployeePo::getSalary, 500, 3000).orderByDesc(EmployeePo::getSalary);
    List<EmployeePo> pos = employeeDao.selectList(lqw);
    

    还是因为字符串容易“写错”,不好找 bug 的,建议使用 lambda 写法。


七、使用 SQL 聚合函数

在 Mybatis Plus 中使用聚合函数,类似于上面的指定特定列,使用 QueryWrapper 在 select 方法中指定聚合函数。例如:

QueryWrapper<EmployeePo> lqw = new QueryWrapper<>();
lqw.select("count(*) as total"); // 你还能起别名

但是接下来的 2 点就和上面的指定特定列有所不动了:

  1. 调用的是 mapper/dao 的 .selectMaps() 方法;
  2. 这个方法的返回值是一个 map 的 list 。
qw.select("count(*) as total");
qw.lambda().between(EmployeePo::getSalary, 500, 3000);
List<Map<String, Object>> maps = employeeDao.selectMaps(qw);maps.forEach(map -> System.out.println(map.get("total")));

为什么结果会是一个 map 的 list ?原因在于在你所执行的 SQL 语句的聚合函数可能不止一个,另外,结合分组,你所得到的聚合数据也不止一行。例如:

qw.select("count(*) as total", "avg(salary) as avgSalary", "avg(commission) as avgCommission");
qw.lambda().between(EmployeePo::getSalary, 500, 3000).groupBy(EmployeePo::getDepartmentId);
List<Map<String, Object>> maps = employeeDao.selectMaps(qw);maps.forEach(map -> System.out.printf("%s %s %s\n",map.get("total"),map.get("avgSalary"),map.get("avgCommission"))
);

八、模糊查询

Mybatis Plus 的 QueryWrapper 有一套专门的 like 方法用于模糊查询。如下:

LambdaQueryWrapper<EmployeePo> qw = new LambdaQueryWrapper<>();
qw.select(EmployeePo::getId, EmployeePo::getName, EmployeePo::getSalary);
qw.like(EmployeePo::getName, "A");        // like "%A%"
//qw.likeRight(EmployeePo::getName, "A"); // like "%A%"
//qw.likeLeft(EmployeePo::getName, "A");  // like "%A"
employeeDao.selectMaps(qw);

关于条件构造器 Wrapper 的更多使用,见官网

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

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

相关文章

c# 赋值运算符_C#程序演示赋值运算符的示例

c# 赋值运算符Assignment operators (Assignment () and compound assignments (, -, *, /, %)) are used to assign the value or an expressions result to the left side variable, following are the set of assignment operators, 赋值运算符(Assignment( )和复合赋值( …

Linux Debian11使用国内源安装 Docker 环境

首先切换到root账户&#xff1a; su 一、Debian安装Docker 1.更新并安装一些必要系统工具。 sudo apt-get update sudo apt-get upgrade sudo apt-get install \apt-transport-https \software-properties-common \ca-certificates \curl \gnupg \lsb-release2.安装GPG证书…

HashMap 为什么在链表长度为 8 的时候转红黑树,为啥不能是 9 是 10?

这个问题是在面试某公司的时候面试官提的问题&#xff0c;当时没回答上来。归根到底还是因为自己复习基础的时候还不够仔细&#xff0c;也缺乏思考。 首先 我觉得需要确认一下&#xff0c;是不是随便什么情况下只要满足了链表长度为8就转红黑树呢&#xff1f;答案自然不是&am…

计算机网络怎么寻址_计算机网络中的无类寻址

计算机网络怎么寻址To reduce the wastage of IP addresses in blocks we subnetting. But in Classless addressing wastage of IP addresses in a block is more reduced than Classful subnetting. In this variable length, blocks are used that belongs to no class. 为了…

Linux Debian常用下载工具Transmission和qbittorrent

1.Transmission Transmission是Linux Debian系统下的系统自带的一种BitTorrent客户端下载工具&#xff0c;下载速度比较快。在Linux系统可以替代windows上的迅雷下载工具。 2.qbittorrent 使用下面命令安装&#xff1a; sudo apt-get install qbittorrent获取更多资料&#x…

《 面试又翻车了》这次竟然和 Random 有关?

小强最近面试又翻车了&#xff0c;然而令他郁闷的是&#xff0c;这次竟然是栽到了自己经常在用的 Random 上......面试问题既然已经有了 Random 为什么还需要 ThreadLocalRandom&#xff1f;正文Random 是使用最广泛的随机数生成工具了&#xff0c;即使连 Math.random() 的底层…

c#串口程序接收数据并打印_C#程序可打印各种数据类型的大小

c#串口程序接收数据并打印In this C# program – we are going to print size of various data types, to print size of a type, we use sizeof() operator. 在此C&#xff03;程序中–我们将打印各种数据类型的大小&#xff0c;并使用typeof()运算符打印类型的大小。 It acc…

Linux Debian11使用国内源安装Podman环境

一、Podman简介 Podman 是一个开源的容器运行时项目&#xff0c;可在大多数 Linux 平台上使用。Podman 提供与 Docker 非常相似的功能。正如前面提到的那样&#xff0c;它不需要在你的系统上运行任何守护进程&#xff0c;并且它也可以在没有 root 权限的情况下运行。 Podman 可…

二叉搜索树中第k大元素_二叉搜索树中第K个最小元素

二叉搜索树中第k大元素Problem statement: 问题陈述&#xff1a; Find the k-th smallest element in a given binary search tree (BST). 在给定的二进制搜索树(BST)中找到第k个最小的元素。 Example: 例&#xff1a; K4Kth smallest element in the above binary tree is:…

阿里巴巴Java开发手册建议设置HashMap的初始容量,但设置多少合适呢?

作者 l Hollis来源 l Hollis&#xff08;ID&#xff1a;hollischuang&#xff09;集合是Java开发日常开发中经常会使用到的&#xff0c;而作为一种典型的K-V结构的数据结构&#xff0c;HashMap对于Java开发者一定不陌生。关于HashMap&#xff0c;很多人都对他有一些基本的了解&…

面向.Net程序员的dump分析

背景 Dump文件是进程的内存镜像。可以把程序的执行状态通过调试器保存到dump文件中。在 Windows 系统上&#xff0c; dump 文件分为内核 dump 和用户态 dump 两种。前者一般用来分析内核相关的问题&#xff0c;比如驱动程序&#xff1b;后者一般用来分析用户态程序的问题。 一般…

Linux Debian利用Dockefile将Python的py文件项目代码打包为Docker Podman镜像

1.创建PyCharm工程 使用PyCharm创建testHelloWorld工程&#xff0c;如下图所示&#xff1a; 2.选择本项目下的Python解释器 通过File -> Setting…选择解释器为本工程下的Python解释器。 【备注&#xff1a;一定要将项目python环境依赖存至本项目下&#xff0c;默认依赖本…

Java14发布!Switch竟如此简单?Lombok也不需要了?来用Idea搭建Java14吧!​

Java 14 在 2020.3.17 日发布正式版了&#xff0c;但现在很多公司还在使用 Java 7 或 Java 8&#xff0c;每当看到 Java 又发布新版本心里就慌得一匹。不过此版本并不是 LTS (长期支持版) 版本&#xff0c;所以不要慌&#xff0c;我们先来了解一下好了&#xff0c;等 LTS 版本发…

np.copysign_带有Python示例的math.copysign()方法

np.copysignPython math.copysign()方法 (Python math.copysign() method) math.copysign() method is a library method of math module, it is used to get a number with the sign of another number, it accepts two numbers (either integers or floats) and returns a fl…

PyCharm更换pip源为国内源、模块安装、PyCharm依赖包导入导出教程

一、更换pip为国内源 1.使用PyCharm创建一个工程 2.通过File -> Setting…选择解释器为本工程下的Python解释器。 3.单击下图中添加“”&#xff0c; 4.单击下图中的“Manage Repositories”按钮&#xff0c; 6.目前国内靠谱的 pip 镜像源有&#xff1a; - 清华&#xff1…

Java14来了!Switch竟如此简单?Lombok也不需要了?来用Idea搭建Java14吧!

Java 14 在 2020.3.17 日发布正式版了&#xff0c;但现在很多公司还在使用 Java 7 或 Java 8&#xff0c;每当看到 Java 又发布新版本心里就慌得一匹。不过此版本并不是 LTS (长期支持版) 版本&#xff0c;所以不要慌&#xff0c;我们先来了解一下好了&#xff0c;等 LTS 版本发…

在线批量压缩JPG图片-JpegMini

2019独角兽企业重金招聘Python工程师标准>>> 之前有推荐过一个在线批量压缩PNG图片的网站TinyPng&#xff0c;这儿小觉再次推荐一个同类网站&#xff0c;专门在线批量压缩JPG图片的JpegMini。 当然&#xff0c;大家或者会说现在很多工具或者网站都有提供在线批量压缩…

Python创建目录、判断路径是否为目录、打开文件夹操作

1.Python创建目录 # 导入os模块 import os # 判断一个目录path是否存在 os.path.exists(path) # 创建目录path os.mkdir(path) # 多层创建目录path os.makedirs(path) import ospath E:/test/if os.path.exists(path):pass else:os.mkdir(path)2.判断路径是否为目录 # 导入o…

## c 连接字符_用于字符比较的C#程序

## c 连接字符Input characters and compare them using C# program. 输入字符并使用C&#xff03;程序进行比较。 Prerequisite: Methods to input a single character in C# 先决条件&#xff1a; 在C&#xff03;中输入单个字符的方法 C&#xff03;代码比较两个字符 (C# …

《大厂内部资料》Redis 性能优化的 13 条军规!全网首发

这是我的第 43 篇原创文章。Redis 是基于单线程模型实现的&#xff0c;也就是 Redis 是使用一个线程来处理所有的客户端请求的&#xff0c;尽管 Redis 使用了非阻塞式 IO&#xff0c;并且对各种命令都做了优化&#xff08;大部分命令操作时间复杂度都是 O(1)&#xff09;&#…