【第12章】MyBatis-Plus条件构造器(下)

文章目录

  • 前言
  • 一、使用 TypeHandler
  • 二、使用提示
  • 三、Wrappers
  • 四、线程安全性
  • 五、使用 Wrapper 自定义 SQL
    • 1.注意事项
    • 2.示例
    • 3. 使用方法
  • 总结


前言

本章继续上章条件构造器相关内容。


一、使用 TypeHandler

wrapper 中使用 typeHandler 需要特殊处理利用 formatSqlMaybeWithParam 方法

// 查询
queryWrapper.apply("type={0,typeHandler="+ MyTypeHandler.class.getCanonicalName()+ "}", "待处理字符串");

// 更新
updateWrapper.setSql("type={0,javaType=string,jdbcType=VARCHAR,typeHandler=xxx.xxx.MyTypeHandler}", "待处理字符串");

二、使用提示

通过使用 MyBatis-Plus 的 Wrapper 条件构造器,开发者可以更加高效地构建复杂的数据库查询条件,同时保持代码的简洁性和安全性。以下是一些注意事项与推荐做法:

  • 在使用 Wrapper 时,尽量使用 Lambda 表达式来避免硬编码字段名,这样可以提高代码的可读性和可维护性。
  • 在使用 Wrapper 时,尽量使用 Lambda 表达式来避免硬编码字段名,这样可以提高代码的可读性和Wrapper 支持链式调用,可以组合多个条件,如 andor 等逻辑操作符。
  • 在使用 Wrapper 时,尽量使用 Lambda 表达式来避免硬编码字段名,这样可以提高代码的可读性和在更新操作中使用 UpdateWrapper 或 LambdaUpdateWrapper 时,可以省略实体对象,直接在 Wrapper 中设置更新字段。
  • 在使用 Wrapper 时,尽量使用 Lambda 表达式来避免硬编码字段名,这样可以提高代码的可读性和注意 Wrapper 的线程安全性,通常在每次使用时创建新的 Wrapper 实例。
  • 在使用 Wrapper 时,尽量使用 Lambda 表达式来避免硬编码字段名,这样可以提高代码的可读性和在使用 MyBatis-Plus 的 Wrapper 时,应避免将前端动态参数直接拼接到 SQL 片段中,以防止 SQL 注入攻击。MyBatis-Plus 提供了安全的参数绑定方式,如使用 eqapply 等方法,它们会自动处理参数绑定,避免 SQL 注入风险。

三、Wrappers

MyBatis-Plus 提供了 Wrappers 类,它是一个静态工厂类,用于快速创建 QueryWrapperUpdateWrapperLambdaQueryWrapperLambdaUpdateWrapper 的实例。使用 Wrappers 可以减少代码量,提高开发效率。
示例:

// 创建 QueryWrapper
QueryWrapper<User> queryWrapper = Wrappers.query();
queryWrapper.eq("name", "张三");

// 创建 LambdaQueryWrapper
LambdaQueryWrapper<User> lambdaQueryWrapper = Wrappers.lambdaQuery();
lambdaQueryWrapper.eq(User::getName, "张三");

// 创建 UpdateWrapper
UpdateWrapper<User> updateWrapper = Wrappers.update();
updateWrapper.set("name", "李四");

// 创建 LambdaUpdateWrapper
LambdaUpdateWrapper<User> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
lambdaUpdateWrapper.set(User::getName, "李四");

注意事项

  • 在使用 QueryWrapper UpdateWrapper 查询 设置 条件字段部分 一定要保证安全,避免 SQL 注入攻击。
  • 任何 前端 传入的 SQL片段 都要 严格过滤 更多查看 数据安全保护 预防安全漏洞

四、线程安全性

Wrapper 实例不是线程安全的,因此建议在每次使用时创建新的 Wrapper 实例。这样可以避免多线程环境下的数据竞争和潜在的错误。

示例:

// 在每个方法或请求中创建新的 Wrapper 实例
public List<User> getUsersByName(String name) {
    QueryWrapper<User> queryWrapper = Wrappers.query();
    queryWrapper.eq("name", name);
    return userMapper.selectList(queryWrapper);
}

通过遵循这些最佳实践,开发者可以更加安全、高效地使用 MyBatis-Plus 的 Wrapper 条件构造器,构建出既安全又易于维护的数据库操作代码。

五、使用 Wrapper 自定义 SQL

MyBatis-Plus 提供了强大的 Wrapper 条件构造器,允许开发者自定义 SQL 语句,以满足更复杂的数据库查询需求。为了使用这一功能,请确保你的 mybatis-plus 版本不低于 3.0.7

1.注意事项

  • 版本要求:确保你的项目中使用的 mybatis-plus 版本至少为 3.0.7,以支持自定义 SQL 功能。
  • 参数命名:在自定义 SQL 时,传递 Wrapper 对象作为参数时,参数名必须为 ew,或者使用注解 @Param(Constants.WRAPPER) 明确指定参数为 Wrapper 对象。
  • 使用 ${ew.customSqlSegment}:在 SQL 语句中,使用 ${ew.customSqlSegment} 来引用 Wrapper 对象生成的 SQL 片段。
  • 不支持基于 entitywhere 语句:自定义 SQL 时,Wrapper 对象不会基于实体类自动生成 where 子句,你需要手动编写完整的 SQL 语句。

2.示例

以下是一个使用 Wrapper 自定义 SQL 的示例:

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;

public interface UserMapper extends BaseMapper<User> {
    @Select("SELECT * FROM user ${ew.customSqlSegment}")
    List<User> selectByCustomSql(@Param(Constants.WRAPPER) Wrapper<User> wrapper);
}

在上述示例中,我们定义了一个 selectByCustomSql 方法,它使用了一个自定义的 SQL 语句,并通过 ${ew.customSqlSegment} 引入了 Wrapper 对象生成的 SQL 片段。

3. 使用方法

要使用自定义 SQL,只需调用上述方法并传入一个 Wrapper 对象:

QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "张三");

List<User> userList = userMapper.selectByCustomSql(queryWrapper);

在这个例子中,selectByCustomSql 方法将执行一个带有 where 条件的查询,该条件由传入的 queryWrapper 对象生成。

通过这种方式,你可以灵活地结合 MyBatis-PlusWrapper 功能和自定义 SQL,以满足各种复杂的数据库操作需求。


总结

回到顶部

使用 TypeHandler大家可以放到后面了解,后面会有专门的一章去讲字段类型处理器。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

力扣双指针算法题目:双数之和,三数之和,四数之和

目录 一&#xff1a;双数之和 1.题目&#xff1a; 2.思路解析 3.代码 二&#xff1a;三数之和 1.题目 2.思路解析 3&#xff0c;代码 三&#xff1a;四数字之和 1.题目 2.思路解析 3.代码 一&#xff1a;双数之和 1.题目&#xff1a; 输入一个递增排序的数组和一…

思维导图插件--jsMind的使用

vue引入jsmind&#xff08;右键菜单&#xff09;_jsmind.menu.js-CSDN博客 第一版 vue-JsMind思维导图实现&#xff08;包含鼠标右键自定义菜单&#xff09;_jsmind 右键菜单-CSDN博客 // 新增节点addNode() {console.log(this.get_selected_nodeid());this.get_selected_…

uniapp入门

一、新建项目 进入到主界面&#xff0c;左上角点击新建——1.项目 输入项目名称&#xff0c;Vue版本选择3 二、创建页面 选中左侧文件目录里的pages文件夹&#xff0c;右键&#xff0c;选择新建页面 1输入名称 2选中“创建同名目录” 3选择模板&…

风暴统计案例复现 | 先单后多的影响因素分析

今日要复现的是最最基础的影响因素分析文章&#xff0c;文章包括了①基本情况表、②卡方检验、③多因素logistic回归&#xff0c;复现过程将会详细截图讲解具体步骤&#xff0c;尤其是新手小白&#xff0c;请大家跟上脚步哦&#xff01; 本文为常见的先单后多影响因素分析的文章…

类型“{}”上不存在属性“xxxx”。ts(2339)

解决&#xff1a;类型“{}”上不存在属性“xxxx”和非类型化函数调用不能接受类型参数等问题。 问题发现 今天一个学生&#xff0c;发我一张图&#xff08;如下&#xff09;。 他从远端拉取到本地&#xff08;自家电脑&#xff09;后打开的代码视图&#xff0c;一大堆抛红。问…

Golang | Leetcode Golang题解之第212题单词搜索II

题目&#xff1a; 题解&#xff1a; type Trie struct {children map[byte]*Trieword string }func (t *Trie) Insert(word string) {node : tfor i : range word {ch : word[i]if node.children[ch] nil {node.children[ch] &Trie{children: map[byte]*Trie{}}}nod…

【鸿蒙学习笔记】基础组件 Button

官方文档&#xff1a;按钮 (Button)添加链接描述 官方文档&#xff1a;button开发指导 目录标题 属性迭代完善不含子组件的按钮包含子组件的按钮ButtonType添加事件跳转超链接提交表单悬浮按钮 属性迭代完善 不含子组件的按钮 Column({ space: 10 }) {Row() {Button(添加子目…

CentOS 7 停止维护(2024-6-30)后可用在线yum源 —— 筑梦之路

众所周知&#xff0c;centos 7 在2024年6月30日&#xff0c;生命周期结束&#xff0c;官方不再进行支持维护&#xff0c;而很多环境一时之间无法完全更新替换操作系统&#xff0c;因此对于yum源还是需要的&#xff0c;特别是对于互联网环境来说&#xff0c;在线yum源使用方便很…

NoSQL之Redis优化

目录 一、Redis 高可用 二、Redis 持久化 1.RDB 持久化 1&#xff09;触发条件 2&#xff09; 执行流程 3&#xff09;启动时加载 2.AOF 持久化 1&#xff09;开启AOF 2&#xff09;执行流程 3&#xff09;启动时加载 3.RDB和AOF的优缺点 三、Redis 性能管理 1.查…

【Dison夏令营 Day 07】用 Python 和 Rich 制作 Wordle克隆(下篇)

在大流行期间&#xff0c;Wordle 在 Twitter 上还算比较流行的一款基于网络的益智游戏&#xff0c;要求玩家每天在六次或更短时间内猜出一个新的五个字母的单词&#xff0c;每个人得到的单词都是一样的。 在本教程中&#xff0c;你将在终端上创建自己的 Wordle 克隆。自 2021 …

分享一款Type C接口USB转2路485模块【带完整原理图】

大家好&#xff0c;我是『芯知识学堂』的SingleYork&#xff0c;今天给大家分享一款很实用的工具–基于Type C接口的USB转2路485模块。 这款模块主芯片采用南京沁恒的CH342F这款芯片&#xff0c;芯片特性如下&#xff1a; 该系列芯片有QFN24和ESSOP10 这2种封装&#xff0c;…

深度网络现代实践 - 深度前馈网络之结构设计篇

序言 深度网络结构设计作为人工智能领域的基石&#xff0c;正引领着技术创新的浪潮。通过模拟人脑神经元间的复杂连接&#xff0c;深度神经网络展现了卓越的特征学习与模式识别能力。随着大数据与计算能力的提升&#xff0c;设计高效、精准且泛化能力强的深度网络结构成为研究…

深度探索“目录名称无效“:原因、解决方案与最佳实践

目录名称无效&#xff1a;现象背后的秘密 在日常使用电脑或移动设备时&#xff0c;我们时常会遇到“目录名称无效”的错误提示&#xff0c;这一提示仿佛是一道无形的屏障&#xff0c;阻断了我们与重要数据的联系。从本质上讲&#xff0c;“目录名称无效”意味着系统无法识别或…

基于正点原子FreeRTOS学习笔记——时间片调度实验

目录 一、时间片调度介绍 二、实验演示 1、宏修改 1.1、滴答定时器宏 1.2、调度器宏 2、实验程序 2.1.1、任务1&#xff0c;任务2不加临界区程序 2.1.2 实验现象 2.2.1、任务1&#xff0c;任务2加临界区程序 2.2.2 实验现象 一、时间片调度介绍 时间片&#xff1a;同…

Golang中defer和return顺序

在Golang中&#xff0c;defer 和 return 的执行顺序是一个重要的特性&#xff0c;它们的执行顺序如下&#xff1a; return语句不是一条单独的语句&#xff0c;实际上&#xff0c;它是由赋值和返回两部分组成的。赋值步骤会先执行&#xff0c;这一步会计算return语句中的表达式…

【后端面试题】【中间件】【NoSQL】MongoDB的配置服务器、复制机制、写入语义和面试准备

MongoDB的配置服务器 引入了分片机制之后&#xff0c;MongoDB启用了配置服务器(config server) 来存储元数据&#xff0c;这些元数据包括分片信息、权限控制信息&#xff0c;用来控制分布式锁。其中分片信息还会被负责执行查询mongos使用。 MongoDB的配置服务器有一个很大的优…

【C语言】const 关键字

在C语言中&#xff0c;const关键字用于定义常量&#xff0c;使得变量的值在其声明之后无法被修改。这可以帮助防止意外修改数据&#xff0c;提高代码的安全性和可读性。以下是有关const关键字的一些详细说明&#xff1a; 基本用法 const int max_value 100;在这个例子中&…

Zynq系列FPGA实现SDI视频编解码+图像缩放,基于GTX高速接口,提供4套工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本博已有的FPGA图像缩放方案本方案的无缩放应用本方案在Xilinx--Kintex系列FPGA上的应用 3、详细设计方案设计原理框图SDI 输入设备Gv8601a 均衡器GTX 解串与串化SMPTE SD/HD/3G SDI IP核BT1120转RGB纯V…

FastApi中的常见请求类型

FastApi中的常见请求类型 后端开发语言中&#xff0c;我钟情于node&#xff0c;高效的异步处理真是让我眼前一亮&#xff0c;同时&#xff0c;简单易懂的语法也让我非常倾心 但是但是&#xff0c;因为考虑要写一个深度学习算法的后端接口&#xff0c;所以不得不选用python作为…

容器安全:等保合规性的基石

随着云计算和微服务架构的蓬勃发展&#xff0c;容器技术已经成为现代IT基础设施不可或缺的一部分。在网络安全等级保护制度&#xff08;等保&#xff09;的框架下&#xff0c;容器安全的要求日益凸显&#xff0c;成为等保合规性的基石。本文将深入探讨容器安全在等保中的重要性…