mybatis之动态标签

有些时候,sql语句where条件中,需要一些安全判断,例如按性别检索,如果传入的参数是空的,此时查询出的结果很可能是空的,也许我们需要参数为空时,是查出全部的信息。这是我们可以使用动态sql,增加一个判断,当参数不符合要求的时候,我们可以不去判断此查询条件。

if标签

<!-- 查询学生list,like姓名 -->  
<select id="getStudentListLikeName" parameterType="com.somnus.pojoStudentEntity" resultMap="studentResultMap">  SELECT * t_student WHERE student_name LIKE CONCAT('%', #{studentName}),'%')  
</select>   

但是此时如果studentName为null,此语句很可能报错或查询结果为空。
此时我们使用if动态sql语句先进行判断,如果值为null或等于空字符串,我们就不进行此条件的判断,增加灵活性。

参数为实体类StudentEntity。将实体类中所有的属性均进行判断,如果不为空则执行判断条件。

<!-- 2 if(判断参数) - 将实体类不为空的属性作为where条件 -->  
<select id="getStudentList_if" resultMap="studentResultMap" parameterType="com.somnus.pojo.StudentEntity">  SELECT student_id,  student_name,  student_sexFROM t_student   WHERE  <if test="studentName !=null and studentName != '' ">  student_name LIKE CONCAT('%', #{studentName, jdbcType=VARCHAR},'%')  </if>  <if test="studentSex != null and studentSex != '' ">  AND student_sex = #{studentSex, jdbcType=INTEGER}  </if><if test="studentId != null and studentId != '' ">  AND student_id = #{studentId, jdbcType=VARCHAR}  </if>   
</select>  

使用时比较灵活, new一个这样的实体类,我们需要限制那个条件,只需要附上相应的值就会where这个条件,相反不去赋值就可以不在where中判断。

public void select_test_if() {  StudentEntity entity = new StudentEntity();  entity.setStudentName("zpli");  entity.setStudentSex(1);  List<StudentEntity> list = studentMapper.getStudentList_if(entity);  for (StudentEntity e : list) {  System.out.println(e.toString());  }  
}  

if + where 的条件判断

当where中的条件使用的if标签较多时,这样的组合可能会导致错误。我们以在 if 标签查询语句为例子,当java代码按如下方法调用时:

@Test  
public void select_test_2_1() {  StudentEntity entity = new StudentEntity();  entity.setStudentName(null);  entity.setStudentSex(1);  List<StudentEntity> list = this.dynamicSqlMapper.getStudentList_if(entity);  for (StudentEntity e : list) {  System.out.println(e.toString());  }  
}  

如果上面例子,参数studentName为null,将不会进行student_name列的判断,则会直接导“WHERE AND”关键字多余的错误SQL。

这时我们可以使用where动态语句来解决。这个where标签会做两件事:

  1. 如果它包含的标签中有返回值的话,它就插入一个where语句,否则什么也不做
  2. 如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。

上面例子修改为:

<!-- 3 select - where/if(判断参数) - 将实体类不为空的属性作为where条件 -->  
<select id="getStudentList_whereIf" resultMap="studentResultMap" parameterType="com.somnus.pojo.StudentEntity">  SELECT student_id,  student_name,  student_sex  FROM t_student   <where>  <if test="studentName !=null and studentName != '' ">  student_name LIKE CONCAT('%', #{studentName, jdbcType=VARCHAR},'%')  </if>  <if test="studentSex != null and studentSex != '' ">  AND student_sex = #{studentSex, jdbcType=INTEGER}  </if><if test="studentId != null and studentId != '' ">  AND student_id = #{studentId, jdbcType=VARCHAR}  </if>   </where>    
</select>   

if + set 的更新语句

当update语句中没有使用set标签时,如果最后一个if标签的参数为null,就会导致错误。

当在update语句中使用if标签时,如果最后的if没有执行,则或导致逗号多余错误。使用set标签可以将动态的配置set关键字,和剔除追加到条件末尾的任何不相关的逗号。
如下studentSex为null或者为空串,则最终的语句会变为UPDATE t_student set student_name = 'zpli', WHERE student_id = '7' 。此时set语句最后多了逗号,sql必将报错。

<!-- 4 if/set(判断参数) - 将实体类不为空的属性更新 -->  
<update id="updateStudent_set" parameterType="com.somnus.pojo.StudentEntity">  UPDATE t_student set  <if test="studentName != null and studentName != '' ">  student_name = #{studentName},  </if>  <if test="studentSex != null and studentSex != '' ">  student_sex = #{studentSex}  </if>WHERE student_id = #{studentId};      
</update>  

使用if+set标签修改后,如果某项为null则不进行更新,而是保持数据库原值。如下示例:

<!-- 4 if/set(判断参数) - 将实体类不为空的属性更新 -->  
<update id="updateStudent_if_set" parameterType="com.somnus.pojo.StudentEntity">  UPDATE t_student  <set>  <if test="studentName != null and studentName != '' ">  student_name = #{studentName},  </if>  <if test="studentSex != null and studentSex != '' ">  student_sex = #{studentSex},  </if> </set>  WHERE student_id = #{studentId};      
</update>  

if + trim代替where/set标签

trim是更灵活的去处多余关键字的标签,他可以实践where和set的效果。

trim代替where

<!-- if/trim代替where(判断参数) - 将实体类不为空的属性作为where条件 -->  
<select id="getStudentList_if_trim" resultMap="studentResultMap">   SELECT student_id,  student_name,  student_sex  FROM t_student    <trim prefix="WHERE" prefixOverrides="AND|OR">  <if test="studentName !=null " and studentName != '' >  student_name CONCAT('%', #{studentName, jdbcType=VARCHAR},'%')  </if>  <if test="studentSex != null and studentSex != '' ">  AND student_sex = #{studentSex, jdbcType=INTEGER}  </if> </trim>     
</select>  

trim代替set

<!-- if/trim代替set(判断参数) - 将实体类不为空的属性更新 -->  
<update id="updateStudent_if_trim" parameterType="com.somnus.pojo.StudentEntity">  UPDATE t_student  <trim prefix="SET" suffixOverrides=",">  <if test="studentName != null and studentName != '' ">  student_name = #{studentName},  </if>  <if test="studentSex != null and studentSex != '' ">  student_sex = #{studentSex},  </if>  </trim>  WHERE student_id = #{studentId}  
</update>  

choose (when, otherwise)

有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。而使用if标签时,只要test中的表达式为true,就会执行if标签中的条件。MyBatis提供了choose 元素。if标签是与(and)的关系,而choose比傲天是或(or)的关系。

choose标签是按顺序判断其内部when标签中的test条件出否成立,如果有一个成立,则choose结束。当choose中所有when的条件都不满则时,则执行otherwise中的sql。类似于Java 的switch 语句,choose为switch,when为case,otherwise则为default。

例如下面例子,同样把所有可以限制的条件都写上,方面使用。choose会从上到下选择一个when标签的test为true的sql执行。安全考虑,我们使用where将choose包起来,放置关键字多于错误。

<!--  choose(判断参数) - 按顺序将实体类第一个不为空的属性作为where条件 -->  
<select id="getStudentList_choose" resultMap="studentResultMap" parameterType="com.somnus.pojo.StudentEntity">  SELECT student_id,  student_name,  student_sex  FROM t_student     <where>  <choose>  <when test="studentName !=null ">  student_name LIKE CONCAT('%', #{studentName, jdbcType=VARCHAR},'%')  </when >  <when test="studentSex != null and studentSex != '' ">  AND student_sex = #{studentSex, jdbcType=INTEGER}  </when >  <when test="studentId != null and studentId != '' ">  AND student_id = #{studentId, jdbcType=VARCHAR}  </when >  <otherwise>  </otherwise>  </choose>  </where>    
</select>  

foreach

对于动态SQL 非常必须的,主是要迭代一个集合,通常是用于IN 条件。List 实例将使用“list”做为键,数组实例以“array” 做为键。

foreach元素是非常强大的,它允许你指定一个集合,声明集合项和索引变量,它们可以用在元素体内。它也允许你指定开放和关闭的字符串,在迭代之间放置分隔符。这个元素是很智能的,它不会偶然地附加多余的分隔符。

注意:你可以传递一个List实例或者数组作为参数对象传给MyBatis。当你这么做的时候,MyBatis会自动将它包装在一个Map中,用名称在作为键。List实例将会以“list”作为键,而数组实例将会以“array”作为键。

这个部分是对关于XML配置文件和XML映射文件的而讨论的。下一部分将详细讨论Java API,所以你可以得到你已经创建的最有效的映射。

参数为list示例的写法

接口的方法声明:

public List<StudentEntity> getStudentListByStudentIds_foreach_list(List<String> studentIdList);  

动态SQL语句:

<!-- foreach(循环List<String>参数) - 作为where中in的条件 -->  
<select id="getStudentListByStudentIds_foreach_list" resultMap="studentResultMap">  SELECT student_id,  student_name,  student_sex  FROM t_student WHERE student_id IN   <foreach collection="studentIdList" item="studentId"  open="(" separator="," close=")">  #{studentId}  </foreach>  
</select>  

或者

<!-- foreach(循环List<String>参数) - 作为where中in的条件 -->  
<select id="getStudentListByStudentIds_foreach_list" resultMap="studentResultMap">  SELECT student_id,  student_name,  student_sex  FROM t_student WHERE student_id IN (<foreach collection="studentIdList" item="studentId" separator="," >  #{studentId}  </foreach>  )
</select>  

测试代码,查询学生中,学号在20000001、20000002的学生:

@Test  
public void test_foreach() {  ArrayList<String> studentIdList = new ArrayList<String>();  studentIdList.add("20000001");  studentIdList.add("20000002");  List<StudentEntity> list = studentMapper.getStudentListByStudentIds_foreach_list(classIdList);  for (StudentEntity e : list) {  System.out.println(e.toString());  }  
}  

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

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

相关文章

代码随想录算法训练营Day55|42.接雨水、84.柱状图中最大的矩形

接雨水 42. 接雨水 - 力扣&#xff08;LeetCode&#xff09; 暴力解法 对计算接到的雨水&#xff0c;有两种方式&#xff0c;一是按照行来计算。 另一种是按列计算 按列计算容易不乱。基本思路如下&#xff1a; 对每列i进行循环&#xff0c;在循环中&#xff0c;找到该列左…

HarmonyOS Next开发学习手册——视频播放 (Video)

Video组件用于播放视频文件并控制其播放状态&#xff0c;常用于为短视频和应用内部视频的列表页面。当视频完整出现时会自动播放&#xff0c;用户点击视频区域则会暂停播放&#xff0c;同时显示播放进度条&#xff0c;通过拖动播放进度条指定视频播放到具体位置。具体用法请参考…

【JVM-02】垃圾收集(回收)算法

【JVM-02】垃圾收集/回收算法 1. 分代收集算法2. 标记-清除算法3. 标记-复制算法4. 标记-整理算法 1. 分代收集算法 分代收集(回收)算法根据对象存活周期的不同将内存分为几块。一般将java堆分为新生代和老年代&#xff0c;这样我们就可以根据各个年代的特点选择合适的垃圾收集…

Kotlin中object关键字的作用

1、对象声明&#xff0c;通过这种方式创建一个单例对象。 object MySingleton{ fun function{ //方法代码块 } } 调用方式&#xff1a;MySingleton.function(),类似像Java的静态方法 2、在类内部声明伴生对象 class OutClass { companion object{ val value 1 fun method(…

【算法题】爬楼梯 (经典递归)

题 爬楼梯&#xff1a; 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 输入&#xff1a; n 2 输出&#xff1a; 2 解释&#xff1a; 有两种方法可以爬到楼顶。 1 阶 1 阶 2 阶 示例 2&#x…

寒武纪实现高维向量的softmax进阶优化和库函数对比

关于寒武纪编程可以参考本人之前的文章添加链接描述,添加链接描述,添加链接描述 实验证明,axis=0和axis=-1的时候,手写softmax速度可以和库函数媲美,甚至于更甚一筹。 src/softmax.mlu #include <bang.h> #include

Nik Collection by DxO:摄影师的创意利器与调色宝典

在数码摄影的世界里&#xff0c;后期处理是摄影师们展现创意、调整细节、提升作品质量的重要步骤。而Nik Collection by DxO作为一款由DxO公司开发的强大照片编辑插件套件&#xff0c;为摄影师们提供了一套全面的、功能丰富的工具集&#xff0c;让他们的创意得以充分发挥。 Ni…

遇到多语言跨境电商系统源码问题?这里有解决方案!

从手机到电脑&#xff0c;从线下到线上&#xff0c;如今&#xff0c;跨境电商正在打破地域界限&#xff0c;成为全球贸易的新引擎。在这个全球化的背景下&#xff0c;跨境电商平台的运营也面临着一系列的挑战&#xff0c;其中之一就是多语言问题。如果你遇到了多语言跨境电商系…

2065. 最大化一张图中的路径价值 Hard

给你一张 无向 图&#xff0c;图中有 n 个节点&#xff0c;节点编号从 0 到 n - 1 &#xff08;都包括&#xff09;。同时给你一个下标从 0 开始的整数数组 values &#xff0c;其中 values[i] 是第 i 个节点的 价值 。同时给你一个下标从 0 开始的二维整数数组 edges &#xf…

小抄 20240629

1 很多人当下焦虑的原因&#xff0c;是短期内无法实现别人长期才能做到的目标&#xff0c;总想几天就能追赶别人几年的努力&#xff0c;只看到了别人的结果&#xff0c;没有思考过别人的过程。 2 把时间线拉长看&#xff0c;人和人都只是阶段性在一起&#xff0c;只要人还在成…

vivado FIFO IP核 中的rd_valid信号

在Vivado中使用FIFO IP核时&#xff0c;valid信号&#xff08;通常称为rd_valid或dout_valid&#xff09;是一个重要的控制信号。让我详细解释它的作用和使用场景。 valid信号的作用&#xff1a; 功能&#xff1a; valid信号是一个输出信号&#xff0c;用于指示FIFO输出数据的…

7基于SpringBoot的SSMP整合案例-表现层开发

目录 1.基于Restfu1进行表现层接口开发 1.1创建功能类 1.2基于Restful制作表现层接口 2.接收参数 2使用Apifox测试表现层接口功能 保存接口&#xff1a; 分页接口&#xff1a; 3.表现层一致性处理 3.1先创建一个工具类&#xff0c;用作后端返回格式统一类&#xff1a;…

springboot校园购物网站APP-计算机毕业设计源码041037

摘 要 21世纪的今天&#xff0c;随着社会的不断发展与进步&#xff0c;人们对于信息科学化的认识&#xff0c;已由低层次向高层次发展&#xff0c;由原来的感性认识向理性认识提高&#xff0c;管理工作的重要性已逐渐被人们所认识&#xff0c;科学化的管理&#xff0c;使信息存…

笔记-Python文件: .py、.ipynb、.pyi、.pyc、​.pyd

.py 最常见的Python代码文件后缀名&#xff0c;官方称Python源代码文件。 不用过多解释了~ .ipynb 这个还是比较常见的&#xff0c;.ipynb是Jupyter Notebook文件的扩展名&#xff0c;它代表"IPython Notebook"。 学过数据分析&#xff0c;机器学习&#xff0c;深度…

内卷情况下,工程师也应该了解的项目管理

简介&#xff1a;大家好&#xff0c;我是程序员枫哥&#xff0c;&#x1f31f;一线互联网的IT民工、&#x1f4dd;资深面试官、&#x1f339;Java跳槽网创始人。拥有多年一线研发经验&#xff0c;曾就职过科大讯飞、美团网、平安等公司。在上海有自己小伙伴组建的副业团队&…

算法笔记:模拟过程(螺旋遍历矩阵)

1 模拟过程 “模拟过程题”通常指的是那些要求编程者通过编写代码来“模拟”或重现某个过程、系统或规则的题目。这类题目往往不涉及复杂的数据结构或高级算法&#xff0c;而是侧重于对给定规则的精确执行和逻辑的清晰表达。 其中螺旋遍历矩阵的题目就是一类典型的模拟过程题…

如何在开发过程中减少 Bug?

爱因斯坦曾说过&#xff1a;“如果我有一个小时来解决一个关系到我生死的问题&#xff0c;我会花55分钟弄清楚问题是什么。一旦我知道了问题是什么&#xff0c;我可以在五分钟内解决它。” 虽然我们的软件开发过程并不涉及生死抉择&#xff0c;但它直接影响用户体验&#xff0c…

明日周刊-第14期

不好意思又拖更了哈哈哈。不过赶在7月的第一天&#xff0c;打算更新一下。建党节&#xff0c;值得纪念的一天。 文章目录 一周热点资源分享言论歌曲推荐 一周热点 国内科技新闻 深中通道建成通车 时间&#xff1a;2024年6月30日 内容&#xff1a;深圳至中山跨江通道正式建成开…

助你疯狂涨点!16种注意力机制魔改模型!

【注意力机制模型】是近年来在深度学习领域中备受关注的一项技术。它通过为输入数据中的重要部分分配更高的权重&#xff0c;从而增强模型对关键特征的识别能力。注意力机制在神经网络的不同层次上应用&#xff0c;可以动态调整注意力权重&#xff0c;从而提高模型的性能。该技…

快团团团长如何导出自提点订单?免费教程一学就会

快团团团长如何导出自提点订单&#xff1f; 一、xcx端如何导出自提点订单&#xff1f; 进入团购页面&#xff0c;在订单管理——订单导出中&#xff0c;可导出自提点商品汇总单和自提点订单 注意&#xff1a;只有自提团才能导出自提点商品汇总表 二、电脑端如何导出自提点订…