Mybatis-Plus条件构造器笔记

2023-05-16

Mybatis-Plus条件构造器笔记

Mybatis-Plus官方文档:https://baomidou.com/pages/10c804/

本文主要讨论Mybatis-Plus条件构造器的区别和用法

  • QueryWrapper、UpdateWrapper
  • lambdaQueryWrapper、LambdaUpdateWrapper
  • QueryChainWrapper、UpdateChainWrapper
  • LambdaQueryChainWrapper、LambdaUpdateChainWrapper

创建Wrapper

以 Query* 为例:

// 创建QueryWrapper
QueryWrapper queryWrapper1 = Wrappers.query();
QueryWrapper queryWrapper2 = new QueryWrapper();

// 创建LambdaQueryWrapper
LambdaQueryWrapper lambdaQueryWrapper1 = Wrappers.query().lambda();
LambdaQueryWrapper lambdaQueryWrapper2 = new QueryWrapper().lambda();

// 创建QueryChainWrapper
QueryChainWrapper<User> userQueryChainWrapper = ChainWrappers.queryChain(userMapper);

// 创建LambdaQueryChainWrapper
LambdaQueryChainWrapper<User> userLambdaQueryChainWrapper = ChainWrappers.lambdaQueryChain(userMapper);

Wrapper区别

  • 带 lambda 的 wrapper 进行列名匹配时,使用的是 Lambda 的语法,属于函数式编程,偏向于对象。反之不带lambda的就需要手动指定列名(即进行硬编码数据库中的字段名)

  • 不带 chain 的 wrapper(QueryWrapper、lambdaQueryWrapper等)执行时,需要将封装的 wrapper 提供给 Mapper,调用Mapper的方法,才可以使用。而带 chain 的 wrapper (QueryChainWrapper、LambdaQueryChainWrapper等)可以直接链式调用数据执行操作的方法

Wrapper用法

Query操作

根据条件查询列表

条件构造器

// 1.几乎不会使用这种方法,局限很大
HashMap<String, Object> map = new HashMap<>();
map.put("1", "12");
userMapper.selectByMap(map);

// 2.QueryWrapper条件用法
QueryWrapper<User> wrapper = new QueryWrapper<User>()
                .like("email", "24252")	//模糊查询
                .between("age", 20, 22)
                .or()
                .eq("name", "zcx")
                .orderByAsc("age")  //升序
                .last("limit 0,3");	//last用法:在sql末尾添加sql语句,有sql注入风险
List<User> list = userMapper.selectList(wrapper);

// 3.使用lambda
LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<User>()
                .like("email", "24252")	//模糊查询
    			.between(User::getAge, 20, 22)
                .eq("name", "zcx")
                .orderByAsc(User::getAge);
List<User> list = userMapper.selectList(lambdaQueryWrapper);

// 4.使用lambda以及链式
LambdaQueryChainWrapper<User> lambdaQueryChainWrapper = new LambdaQueryChainWrapper<>(userMapper)
                .like("email", "24252")	//模糊查询
    			.between(User::getAge, 20, 22)
                .eq("name", "zcx")
    			.orderByAsc(User::getAge);
List<User> list = lambdaQueryChainWrapper.list();

Update操作

根据条件更新

简单更新

// 根据id更新
User user = new User();  
user.setUserId(1);  
user.setAge(18);  

Integer rows = userMapper.updateById(user);

条件构造器

// 1.构造实体对象来更新
User user = new User();
user.setAge(18);

UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("name", "susan");
Integer rows = userMapper.update(user, updateWrapper);

// 2.条件构造器Set方法来更新
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("name","susan").set("age", 18);
Integer rows = userMapper.update(null, updateWrapper);

// 3.使用lambda
LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.eq(User::getName, "susan").set(User::getAge, 18);
Integer rows = userMapper.update(null, lambdaUpdateWrapper);

// 4.使用lambda以及链式
LambdaUpdateChainWrapper<User> lambdaUpdateChainWrapper = new LambdaUpdateChainWrapper<>(userMapper);
boolean update = lambdaUpdateChainWrapper.eq(User::getName, "susan").set(User::getAge, 18).update();

问题记录

使用 LambdaQueryWrapper 动态添加过滤条件

实体bean

@Data
public class CallLogForm {
    @ApiModelProperty(value = "开始时间")
    private LocalDateTime beginTime;

    @ApiModelProperty(value = "结束时间")
    private LocalDateTime endTime;

    @ApiModelProperty(value = "调用方")
    private String client;

    @ApiModelProperty(value = "被调用方")
    private String server;

    @ApiModelProperty(value = "接口名称")
    private String interName;

    @ApiModelProperty(value = "状态 0失败 1成功")
    private String status;
}

开始

LambdaQueryWrapper<CallLog> wrapper = new LambdaQueryWrapper<CallLog>()
                .eq(StringUtils.isNotEmpty(form.getClient()), CallLog::getClient, form.getClient())
                .eq(StringUtils.isNotEmpty(form.getServer()), CallLog::getServer, form.getServer())
                .ge(form.getBeginTime() != null, CallLog::getOperateDate, form.getBeginTime())
                .lt(form.getEndTime() != null, CallLog::getOperateDate, form.getEndTime().plusDays(1))
                .like(StringUtils.isNotEmpty(form.getInterName()), CallLog::getInterName, form.getInterName())
                .eq(StringUtils.isNotEmpty(form.getStatus()), CallLog::getStatus, form.getStatus());
List<CallLog> list = callLogDao.selectList(wrapper);

注意,下面这个条件构造其实是有问题

.lt(form.getEndTime() != null, CallLog::getOperateDate, form.getEndTime().plusDays(1))

这里,因为对 form.getEndTime() 进行了加1天的操作。刚开始以为前面的为空判断会让程序跳过这个条件构造,但实际上代码判定之前会先执行 form.getEndTime().plusDays(1) ,这样就导致会出现空指针异常

这里有两种解决办法

  1. 可以分步写,手动判断空后,再拼接条件构造

    LambdaQueryWrapper<CallLog> wrapper = new LambdaQueryWrapper<CallLog>()
                    .eq(StringUtils.isNotEmpty(form.getClient()), CallLog::getClient, form.getClient())
                    .eq(StringUtils.isNotEmpty(form.getServer()), CallLog::getServer, form.getServer())
                    .like(StringUtils.isNotEmpty(form.getInterName()), CallLog::getInterName, form.getInterName())
                    .eq(StringUtils.isNotEmpty(form.getStatus()), CallLog::getStatus, form.getStatus());
    if (form.getBeginTime() != null) {
        wrapper.ge(form.getBeginTime() != null, CallLog::getOperateDate, form.getBeginTime());
    }
    if (form.getEndTime() != null) {
        wrapper.lt(form.getEndTime() != null, CallLog::getOperateDate, form.getEndTime().plusDays(1));
    }
    List<CallLog> list = callLogDao.selectList(wrapper);
    
  2. 可以对 form.getEndTime().plusDays(1) 进行改写,避免因为空指针异常导致程序错误,比如封装工具类等,封装也比较简单,这里就不展示代码了

ps,个人感觉这两种方法都不是很好,目前没有更好的方法,之后再更新文章吧。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mybatis-Plus条件构造器笔记 的相关文章

  • 插上串口设备导致鼠标乱飘

    今天再一次遇见这种怪事 xff0c 屏幕上鼠标到处乱飘不受控制 xff0c 之前也遇到过 xff0c 没仔细研究 最终在网上搜寻答案发现是插上串口设备导致的问题 xff0c 因为串口一直不停的发送数据 xff0c 会导致电脑将其误识别成鼠标

随机推荐

  • openstack(queens)部署Zun服务

    zun安装手册 Zun是Openstack中提供容器管理服务的组件 xff0c 本文使用的是centos7上的openstack xff08 queens xff09 环境 目录 zun安装手册 3 在controller节点上安装zun服
  • Supervisor 定期重启指定进程

    简介 supervisor 是用 Python 开发的一套通用的进程管理程序 xff0c 能将一个普通的命令行进程变为后台 daemon xff0c 并监控进程状态 xff0c 异常退出时能自动重启 它是通过 fork exec 的方式把这
  • linux 源码安装 xrdp

    前言 xrdp可以做两件事 xff0c 第一件事就是可以使得linux支持RDP协议 xff0c 使得linux桌面能够通过mstsc连接 xff0c 第二件事就是RDP代理 xff0c 我们能通过xrdp连接到其他人的RDP资源 前者 x
  • 编译openssl时发生错误

    编译openssl时发生错误 error OPENSSL ALGORITHM DEFINES no longer supported 原理参考 xff08 由于同时安装了openssl 1 1和openssl 1 0 xff09 版本 xf
  • Linux 非源码安装 xrdp

    基本环境说明 我的是Centos 7 mini 或者 Ubuntu最小化安装 xff0c 想通过mstsc连接到xrdp xff0c 再通过xrdp连接到 Centos 7 mini xff0c 不安装桌面 xff0c 只打开 xterm
  • Selenium常用实战功能指南

    文章目录 自动化前言元素定位的几种方法id定位name定位link text定位partial link text定位xpath定位 xff08 重点 xff09 css定位常见问题 元素操作的常用方法基本方法send keys textg
  • RISC-V指令集架构------RV32I基础整数指令集

    0 基本整数指令集的分类 RISC V指令集分为基础指令集和扩展指令集 xff0c 此外又根据不同的处理器位宽分为32位 64位和128位指令集 xff0c 比如RV32I就表示32位处理器的基本整数指令集 xff0c 此外 xff0c 为
  • 如何在ubuntu22.04版本上安装libssl1.1?

    直接使用sudo apt get install会提示找不到软件包输入一下命令即可 xff1a echo 34 deb http security ubuntu com ubuntu focal security main 34 sudo
  • vue2学习总结一

    1 vue介绍 Vue是一套用于构建用户界面 xff08 数据 gt 界面 xff09 的渐进式 xff08 简单应用 xff08 一个轻量小巧的核心库 xff09 gt 复杂应用 xff08 可以引入各种各样的Vue插件 xff09 xf
  • c++判断字符串是否为回文

    回文是指正读反读均相同的字符序列 如 34 abba 34 和 abdba 均是回文 xff0c 但 34 good 34 不是回文 Solution1 使用reverse 函数将字符串反转 xff0c 与原字符串比较 xff0c 若相同
  • 多车调度问题(大疆Robot Master)——ROS键盘控制失灵,小车无法收敛定位,路径规划出错

    问题1 ROS键盘控制小车失灵 具体就是 xff1a 用键盘左右转小车 xff0c 速度贼快 xff0c 而且方向不正确 xff0c 检查发现是控制模块失灵 xff0c 有可能是内部测量元件 xff08 陀螺仪等 xff09 烧了 xff0
  • 浏览器跨域-原因及解决方案

    1 浏览器跨域 如何判断一个浏览器的请求是否跨域 xff1f 在A地址 xff08 发起请求的页面地址 xff09 向B地址 xff08 要请求的目标页面地址 xff09 发起请求时 xff0c 如果A地址和B地址在 xff1a 协议 域名
  • 使用moment.js时设置中文无效

    背景 xff1a 使用 script 标签 xff0c 在 html 页面中引入了 moment js xff0c 使用时发现页面中 moment js 相关的文字显示的是英文 xff08 eg xff1a 3 days ago xff09
  • virtual stdio 2017 问题

    严重性 代码 说明 项目 文件 行 禁止显示状态 错误 MSB8020 无法找到 Visual Studio 2010 的生成工具 平台工具集 61 v100 若要使用 v100 生成工具进行生成 xff0c 请安装 Visual Stud
  • 中国天气网天气api接口 天气预报调用方法 2020

    说明 百度了很久没有找到免费的天气 API 不是收费就是接口打不开了 最后终于找到了天气api https www tianqiapi com 可免费使用 最重要的是天气数据和中国天气网一致 城市编号也是用的天气网的 这样就方便多了 体验了
  • [路由][教程]OpenWrt通过LAN连接上级路由做交换机+无线功能教程

    1 前言 上级路由为ikuai软路由 xff0c 数据处理交给软路由来做 xff0c OpenWrt运行在路由器上 xff0c 通过LAN连接上级路由从而只做WIFI接收发送功能 此教程只能将LAN作为交换机使用 xff0c WAN口不行
  • [路由][教程]OpenWrt设置为交换机+无线功能教程

    1 前言 上级路由为ikuai软路由 xff0c 数据处理交给软路由来做 xff0c OpenWrt运行在路由器上 xff0c 通过LAN连接上级路由从而只做WIFI接收发送功能 2 需求 路由的LAN和WAN全部作为交换机使用无线WIFI
  • CV学习笔记-特征提取

    特征提取 1 概述 图像中常见的特征有边缘 角 区域等 通过各属性间的关系 xff0c 改变原有的特征空间 xff0c 例如组合不同的属性得到新的属性 xff0c 这样的处理叫做特征提取 注意特征选择是从原始的特征数据集中选择出子集 xff
  • CV学习笔记-深度学习

    深度学习 1 神经网络 1 概述 引例 xff1a 生物神经网络作用机理 生物神经网络的基本工作原理 xff1a 一个神经元的输入端有多个树突 xff0c 主要是用来接收输入信息的 输入信息经过突触处理 xff0c 将输入的信 息累加 xf
  • Mybatis-Plus条件构造器笔记

    Mybatis Plus条件构造器笔记 Mybatis Plus官方文档 xff1a https baomidou com pages 10c804 本文主要讨论Mybatis Plus条件构造器的区别和用法 QueryWrapper Up