首页 > 其他分享 >Mybatis---动态查询(choose,when,otherwise)

Mybatis---动态查询(choose,when,otherwise)

时间:2022-10-12 19:13:04浏览次数:67  
标签:map gender when --- choose position where

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(判断参数) - 按顺序将实体类 User 第一个不为空的属性作为:where条件 -->  
<select id="selectControlTableColumnByTableColumnIdAndIsUpdateOrIsDelete"  parameterType="com.uama.mdm.model.mdata.MdControlTableColumn" resultMap="BaseResultMap">
        SELECT
        <include refid="Base_Column_list"></include>
        FROM md_control_table_column u
        <where>
            <choose>
                <when test="isUpdate !=null ">
                    AND u.is_update = #{isUpdate, jdbcType=INTEGER}
                </when>
                <when test="isDelete != null">
                    AND u.is_delete = #{isDelete, jdbcType=INTEGER}
                </when>
                <otherwise>
                </otherwise>
            </choose>
            <if test="tableColumnId != null">
               AND table_column_id = #{tableColumnId}
            </if>
        </where>
    </select>

choose (when,otherwize) ,相当于java 语言中的 switch ,与 jstl 中 的 choose 很类似。

<iframe data-google-container-id="a!2" data-google-query-id="CIrg5-vB2voCFdHAfAodxLgMcg" data-load-complete="true" frameborder="0" height="90" id="aswift_1" marginheight="0" marginwidth="0" name="aswift_1" scrolling="no" src="https://googleads.g.doubleclick.net/pagead/ads?client=ca-pub-1076724771190722&output=html&h=90&adk=1461312834&adf=651597127&w=728&lmt=1665571629&format=728x90&url=https%3A%2F%2Fblog.csdn.net%2Fqq_28580431%2Farticle%2Fdetails%2F80289632&wgl=1&uach=WyJXaW5kb3dzIiwiMC4xLjAiLCJ4ODYiLCIiLCIxMDUuMC41MTk1LjEyNyIsW10sZmFsc2UsbnVsbCwiNjQiLFtbIkdvb2dsZSBDaHJvbWUiLCIxMDUuMC41MTk1LjEyNyJdLFsiTm90KUE7QnJhbmQiLCI4LjAuMC4wIl0sWyJDaHJvbWl1bSIsIjEwNS4wLjUxOTUuMTI3Il1dLGZhbHNlXQ..&dt=1665571628186&bpp=10&bdt=1032&idt=826&shv=r20221010&mjsv=m202210050101&ptt=9&saldr=aa&abxe=1&cookie=ID%3Dbe7d7a812e14e284-2237c7f3a4d60081%3AT%3D1663559173%3ART%3D1663559173%3AS%3DALNI_MZpS8l79pOZexpdHluypZIbgvjmdw&gpic=UID%3D000009ce76e675c4%3AT%3D1663559173%3ART%3D1665478887%3AS%3DALNI_Ma6u7O9HAsa0wT8lr_MXuCInQ5b1Q&prev_fmts=0x0&nras=1&correlator=8094514452564&frm=20&pv=1&ga_vid=1808418057.1665571629&ga_sid=1665571629&ga_hid=459837962&ga_fc=0&u_tz=480&u_his=1&u_h=768&u_w=1366&u_ah=728&u_aw=1366&u_cd=24&u_sd=1&dmc=4&adx=407&ady=927&biw=1349&bih=625&scr_x=0&scr_y=0&eid=44759876%2C44759927%2C44759842%2C44774717%2C42531706%2C31070209%2C31068920&oid=2&pvsid=2145670954699964&tmod=39756836&uas=0&nvt=1&ref=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DIvHm5JUNtoyYjDuYajw6xLvn3UrDTW9Do66RaTW8hOMSMZzn0NVYJp9l7sCyj9uafRJ99RGLRIM5ZLPKDYq1z3PYP0e5tqS2ZBuJS9zEi-i%26wd%3D%26eqid%3Dc02c3e480000316c0000000363469b28&eae=0&fc=1920&brdim=0%2C0%2C0%2C0%2C1366%2C0%2C1366%2C728%2C1366%2C625&vis=1&rsz=%7C%7CpeEbr%7C&abl=CS&pfx=0&fu=0&bc=31&ifi=2&uci=a!2&btvi=1&fsb=1&xpc=mfdr7vZx88&p=https%3A//blog.csdn.net&dtd=839" width="728"></iframe>
<select id="dynamicChooseTest" parameterType="Blog" resultType="Blog">
        select * from t_blog where 1 = 1 
        <choose>
            <when test="title != null">
                and title = #{title}
            </when>
            <when test="content != null">
                and content = #{content}
            </when>
            <otherwise>
                and owner = "owner1"
            </otherwise>
        </choose>
    </select>

when元素表示当 when 中的条件满足的时候就输出其中的内容,跟 JAVA 中的 switch 效果差不多的是按照条件的顺序,当 when 中有条件满足的时候,就会跳出 choose,即所有的 when 和 otherwise 条件中,只有一个会输出,当所有的我很条件都不满足的时候就输出 otherwise 中的内容。所以上述语句的意思非常简单, 当 title!=null 的时候就输出 and titlte = #{title},不再往下判断条件,当title为空且 content!=null 的时候就输出 and content = #{content},当所有条件都不满足的时候就输出 otherwise 中的内容。

 

 

 

 

【第一个需求:按照固定的某一个条件进行查询。即,查询条件只能有一个】

1.借用上文的工程,复制为Mybatis07,工程结构图不变。

2.我们先移除UserInfo.java中的集合属性。如下:

 

[java]  view plain  copy        
  1. @SuppressWarnings("serial")  
  2. public class UserInfo implements Serializable {  
  3.       
  4.     private String userid;  
  5.     private String department;  
  6.     private String position;  
  7.     private String mobile;  
  8.     private String gender;  
  9.     private String email;  
  10. //set,get,构造函数,toString,请各位看官自己生成吧  
  11. }  
3.在UserInfoDao中增加接口,如下:

 

 

[plain]  view plain  copy        
  1. List<UserInfo> findUserInfoByOneParam(Map<String,Object> map);  
4.在UserInfoMapper.xml中,增加如下内容:

 

 

[html]  view plain  copy        
  1. <select id="findUserInfoByOneParam" parameterType="Map" resultMap="UserInfoResult">  
  2.         select * from userinfo   
  3.         <choose>  
  4.             <when test="searchBy=='department'">  
  5.                 where department=#{department}  
  6.             </when>  
  7.             <when test="searchBy=='position'">  
  8.                 where position=#{position}  
  9.             </when>  
  10.             <otherwise>  
  11.                 where gender=#{gender}  
  12.             </otherwise>  
  13.         </choose>  
  14.     </select>    
【解释】

 

a.请注意这里的【select * from userinfo 】之后没有再写where语句

b.<choose><when><otherwise>配合使用是等价于java中的

[java]  view plain  copy        
  1. if(...){  
  2. ....  
  3. }else if(...){  
  4. ...  
  5. }else{  
  6. ....  
  7. }  
c.按照官方文档给的示例,最后的<otherwise>是需要存在的,但是经过测试,即使最后的<otherwise>没有写,Mybatis也不会发生任何异常。而是将所有表数据返回。这是一种极为不推荐的做法。实际生产环境下,如果该表的数据量非常大,这条语句被执行,就是一个巨大的坑!

 

d.请注意观察;这里的“searchBy”是一个自定义的字符串,读者也可以按照自己的命名习惯,重新定义

e.再特别说明一下,请注意,每一个等号后面的参数都带有单引号。这是这种用法必须必须必须有的。否则,就是直接抛异常!

f.针对d,这里有另外一种情况那就是,判断null的键值对。具体写法如下:【这段代码,各位看官也可以顺便测试一下没有<otherwise>的执行结果是什么】

 

[html]  view plain  copy        
  1. <select id="findUserInfoByOneParam" parameterType="Map" resultMap="UserInfoResult">  
  2.         select * from userinfo   
  3.         <choose>  
  4.             <when test="department!=null">  
  5.                 where department=#{department}  
  6.             </when>  
  7.             <when test="position!=null">  
  8.                 where position=#{position}  
  9.             </when>  
  10.         </choose>  
  11.     </select>   
g.上面这段代码,还有一个值得注意的地方就是,两个when之间的顺序是有关系的。即,如果第一个when满足条件,第二个就不会影响查询结果,其他类似,请读者自行尝试,观察控制台输出。

h.最后,补充一点,就是<choose>的子元素就只能包含<when><otherwise>

4.新增单元测试方法,如下:【这是测试步骤2种的单元测试例子。读者测试上面f步骤的话,注释map的put动作即可】

 

[java]  view plain  copy        
  1. @Test  
  2.     public void testSeletOne() {  
  3.         Map<String,Object> map=new HashMap<String,Object>();  
  4.         map.put("searchBy", "gender");  
  5.         map.put("gender", "1");  
  6.         map.put("position", "工程师");  
  7.         map.put("department","2");  
  8.         UserInfoDao userInfo = sqlSession.getMapper(UserInfoDao.class);  
  9.         List<UserInfo> UIList= userInfo.findUserInfoByOneParam(map);  
  10.         for(UserInfo ui:UIList){  
  11.             System.out.println(ui.toString());  
  12.         }  
  13.     }  
5.这里其他的文件,请按照前面我们说的配置方法进行配置,防止发生错误!

 

6.运行单元测试方法,应该能够看到如下类似输出:【各位看官可以变化一下查询条件,观察输出内容有什么变化】


--------------------------------------------------------------------------------------------------------------------------------------------------------

【第二个需求:基于固定的某一个条件,附加搜索条件】

具体场景如:在电器类别下,搜索某一个品牌的产品。当然,在此我们还是直接对userinfo操作吧,具体情况就请举一反三吧

1.修改刚刚xml文件即可,如下:

 

[html]  view plain  copy        
  1.     <select id="findUserInfoByOneParam" parameterType="Map" resultMap="UserInfoResult">  
  2.         select * from userinfo   
  3.         <choose>  
  4.             <when test="searchBy=='department'">  
  5.                 where department=#{department}  
  6.             </when>  
  7.             <when test="searchBy=='position'">  
  8.                 where position=#{position}  
  9.             </when>  
  10.             <otherwise>  
  11.                 where gender=#{gender}  
  12.             </otherwise>  
  13.               
  14.         </choose>  
  15.         <if test="gender!=null">  
  16.             and gender=#{gender}  
  17.     <span style="white-space:pre">    </span></if>  
  18. </select>  
2.重新运行单元测试方法即可,注意这里是以gender为额外的条件,各位看官可以通过变化gender的0或1来观察控制台输出,这里我们给出示例,请读者自定比对。【我们直接在上面的SQL加入<if>导致语句不符合规范,但是不影响输出】

 

【gender==1】输出:

 

--------------------------------------------------------------------------------------------------------------------------------------------------------

【第三个需求:基于固定的某一个条件,集合属性条件搜索】

这里的做法其实和上文类似,<if>元素中我们可以使用类似JAVA语言的对象判断方法,并且能够轻松的取出这个对象中的属性方法作为搜索条件。

废话不多说,看看我们实际的操作步骤方法:

1.首先,我们需要修改UserInfo.java对象中的成员变量,如下:【注意,我们仅修改对象,而没有修改数据表】

 

[java]  view plain  copy        
  1. @SuppressWarnings("serial")  
  2. public class UserInfo implements Serializable {  
  3.       
  4.     private String userid;  
  5.     private String department;  
  6.     private String position;  
  7.     private String mobile;  
  8.     private String gender;  
  9.     private String email;  
  10.     private Departments depart;  
  11.     //其他内容请自行补充  
  12. }  
2.修改对应mapper文件,如下:

 

 

[html]  view plain  copy        
  1. <select id="findUserInfoByOneParam" parameterType="Map" resultMap="UserInfoResult">  
  2.         select * from userinfo   
  3.         <choose>  
  4.             <when test="searchBy=='department'">  
  5.                 where department=#{department}  
  6.             </when>  
  7.             <when test="searchBy=='position'">  
  8.                 where position=#{position}  
  9.             </when>  
  10.             <otherwise>  
  11.                 where gender=#{gender}  
  12.             </otherwise>  
  13.         </choose>  
  14.         <if test="d != null and d.id != null">  
  15.             AND department = #{d.id}  
  16.         </if>  
  17.     </select>   
3.修改单元测试方法,如下:

 

 

[java]  view plain  copy        
  1. @Test  
  2.     public void testSeletOne() {  
  3.         try {  
  4.   
  5.             Map<String, Object> map = new HashMap<String, Object>();  
  6.             map.put("searchBy", "position");  
  7.             map.put("gender", "1");  
  8.             map.put("position", "工程师");  
  9.             Departments d = new Departments("2", "%售%");  
  10.             map.put("d", d);  
  11.             UserInfoDao userInfo = sqlSession.getMapper(UserInfoDao.class);  
  12.             List<UserInfo> UIList = userInfo.findUserInfoByOneParam(map);  
  13.             for (UserInfo ui : UIList) {  
  14.                 System.out.println(ui.toString());  
  15.             }  
  16.         } catch (Exception e) {  
  17.             e.printStackTrace();  
  18.         }  
  19.     }  
4.运行单元测试方法,应该能够看到如下结果:

 



--------------------------------------------------------------------------------------------------------------------------------------------------------

至此,Mybatis最入门---动态查询(choose,when,otherwise)结束

参考 :Mybatis---动态查询(choose,when,otherwise)

标签:map,gender,when,---,choose,position,where
From: https://www.cnblogs.com/aspirant/p/16785616.html

相关文章

  • 0day安全:软件漏洞技术分析-Crack小实验
    Crack小实验#include<stdio.h>#definePASSWORD"1234567"intverify_password(char*password){ intauthenticated; authenticated=strcmp(password,PASSWORD)......
  • docker-compose 启动 java 容器时报错 library initialization failed - unable to al
    问题:docker-compose启动java容器时报错libraryinitializationfailed-unabletoallocatefiledescriptortable-outofmemoryPickedupJAVA_TOOL_OPTIONS:......
  • leetcode-69-easy
    Sqrt(x)思路一:暴力publicintmySqrt(intx){longbegin=1L;while((begin*begin)<=x){begin++;}returnLong.valueOf(begin).i......
  • python第十三课---
    昨日内容回顾global与nonlocal关键字global 用于局部名称空间修改全局名称空间中的名字绑定关系nonlocal 用于局部名称空间修改外层局部名称空间中的名字绑定关系......
  • python基础--简单数据类型预览
    为了适应更多的使用场景,将数据划分为多种类型,每种类型都有各自的特点和使用场景,帮助计算机高效的处理和展示数据。(比如数字用于数学运算、字符串用于信息传递、页面文字展......
  • CSP-S模拟18
    再次模拟退役,最近心态又双叒叕有点炸。。。。实力确实也真不行A.最长反链猜结论,从大到小能选就选,然后打表发现能选与不能选有明显的分界,于是直接二分答案然后因为判断......
  • 150-《大数据架构师》Flink StreamTask 的逻辑执行和数据流转_ev
              超时时间策略          为了环境复用       ......
  • 【机器学习实战学习笔记】之 2 k-近邻算法
    本学习笔记参考书目《机器学习实战》第二章。本章所有本书对应代码及数据集下载请点击(​​下载链接​​)。本文中博主自己写的代码如有需要,请点击(​​下载链接​​)。目录​​......
  • Java中fail-fast与fail-safe机制
    fail-fast快速失败一个线程在读取集合种的数据时,另外一个线程在修改集合会导致fail-fastArrayListHashMap具备此机制Map<Integer,String>map=newHash......
  • 2022-10-12 vue+uniapp+echarts 使用记录
    第一步:安装echartsnpmiecharts第二步:在main.js引入echartsimportechartsfrom'echarts'Vue.prototype.$echarts=echarts第三步:在项目中使用<template>......