• 概述
  • 需求
  • 实现步骤
    • 1.UserMapper接口中添加接口方法
    • 2.UserMapper.xml中添加动态SQL
    • 3.单元测试

概述

我们在if标签的博文MyBatis-11MyBatis动态SQL之【if】
中介绍了if的在select、update、delete中的用法,可以实现基本的条件判断, 但是却无法实现 if…else ,if ….else….的逻辑。

想要实现 if…else ,if ….else….这样的逻辑 就需要用到choose when otherwise标签了。

choose元素中包含了when和otherwise两个标签 ,一个choose中至少有一个when,有0个或者1个otherwise


需求

前置条件: sys_user表中,除了id是主键外,我们认为user_name也是唯一的,用户名不可重复。

假设有个这样的需求, 实现如下如下逻辑

  • 当参数id有值时优先使用id查询
  • 当没有id时就去判断用户名是否有值,如果有值就根据用户名全配
  • 如果用户名也没有值,就是sql查询为空

实现步骤

1.UserMapper接口中添加接口方法

/*** * * @Title: selectSysUserByIdOrByUserName* * @Description: 根据用户id或者用户名查询用户* * @param sysUser* @return* * @return: SysUser*/SysUser selectSysUserByIdOrByUserName(SysUser sysUser);

2.UserMapper.xml中添加动态SQL

<select id="selectSysUserByIdOrByUserName" resultType="com.artisan.mybatis.xml.domain.SysUser">SELECTa.id,a.user_name userName,a.user_password userPassword,a.user_email userEmail,a.user_info userInfo,a.head_img headImg,a.create_time createTimeFROMsys_user aWHERE 1=1<choose><when test="id != null ">and id = #{id}</when><when test="userName!= null ">and user_name = #{userName}</when><otherwise>and 1 = 2</otherwise></choose></select>

使用choose when otherwise的时候逻辑要严密,避免由于某些值出现问题导致SQL出错。

在上述查询中,如果没有otherwise这个条件限制,当id和username都为空时,所有的用户都会被查询出来,但是我们在对引得接口方法中使用了SysUser作为返回值,所以当实际查询到多个结果时就会报错, 添加otherwise后,由于where 后的条件不满足,因此这种这种情况下查不到结果。


3.单元测试

@Testpublic void selectSysUserByIdOrByUserNameTest() {logger.info("selectSysUserByIdOrByUserNameTest");// 获取SqlSessionSqlSession sqlSession = getSqlSession();try {// 获取UserMapper接口UserMapper userMapper = sqlSession.getMapper(UserMapper.class);logger.info("======. 模拟传入了正确的id 没有传username或者传入了错误的userName======");// 1. 模拟传入了正确的id 没有传username或者传入了错误的userNameSysUser sysUser = new SysUser();sysUser.setId(1001L);sysUser.setUserName("noExistName");// 调用selectSysUserByIdOrByUserName,查询单个用户SysUser user = userMapper.selectSysUserByIdOrByUserName(sysUser);// 期望不为空Assert.assertNotNull(user);// userName 期望值为artisanAssert.assertEquals("artisan", user.getUserName());logger.info(user);logger.info("======2. 模拟不传id,但是传入了正确的 userName======");// 2. 模拟不传id,但是传入了正确的 userNamesysUser = new SysUser();sysUser.setId(null);sysUser.setUserName("admin");user = userMapper.selectSysUserByIdOrByUserName(sysUser);// 期望不为空Assert.assertNotNull(user);// 根据id查询 sysuser,然后获取userName 期望值为artisanAssert.assertEquals("admin", user.getUserName());logger.info(user);logger.info("======3.什么都不传======");// 2. 模拟不传id,但是传入了正确的 userNamesysUser = new SysUser();sysUser.setId(null);sysUser.setUserName(null);user = userMapper.selectSysUserByIdOrByUserName(sysUser);// 期望为空Assert.assertNull(user);logger.info(user);} catch (Exception e) {e.printStackTrace();} finally {sqlSession.close();logger.info("sqlSession close successfully ");}}

日志

2018-04-21 19:46:51,942  INFO [main] (BaseMapperTest.java:26) - sessionFactory bulit successfully
2018-04-21 19:46:51,947  INFO [main] (BaseMapperTest.java:29) - reader close successfully
2018-04-21 19:46:51,951  INFO [main] (UserMapperTest.java:541) - selectSysUserByIdOrByUserNameTest
2018-04-21 19:46:51,979  INFO [main] (UserMapperTest.java:548) - ======. 模拟传入了正确的id 没有传username或者传入了错误的userName======
2018-04-21 19:46:52,569 DEBUG [main] (BaseJdbcLogger.java:145) - ==>  Preparing: SELECT a.id, a.user_name userName, a.user_password userPassword, a.user_email userEmail, a.user_info userInfo, a.head_img headImg, a.create_time createTime FROM sys_user a WHERE 1=1 and id = ?
2018-04-21 19:46:52,647 DEBUG [main] (BaseJdbcLogger.java:145) - ==> Parameters: 1001(Long)
2018-04-21 19:46:52,685 TRACE [main] (BaseJdbcLogger.java:151) - <==    Columns: id, userName, userPassword, userEmail, userInfo, headImg, createTime
2018-04-21 19:46:52,686 TRACE [main] (BaseJdbcLogger.java:151) - <==        Row: 1001, artisan, 123456, test@artisan.com, <<BLOB>>, <<BLOB>>, 2018-04-13 21:12:47.0
2018-04-21 19:46:52,694 DEBUG [main] (BaseJdbcLogger.java:145) - <==      Total: 1
2018-04-21 19:46:52,695  INFO [main] (UserMapperTest.java:559) - SysUser [id=1001, userName=artisan, userPassword=123456, userEmail=test@artisan.com, userInfo=测试用户, headImg=[18, 49, 35, 18, 48], createTime=Fri Apr 13 21:12:47 BOT 2018]
2018-04-21 19:46:52,699  INFO [main] (UserMapperTest.java:561) - ======2. 模拟不传id,但是传入了正确的 userName======
2018-04-21 19:46:52,700 DEBUG [main] (BaseJdbcLogger.java:145) - ==>  Preparing: SELECT a.id, a.user_name userName, a.user_password userPassword, a.user_email userEmail, a.user_info userInfo, a.head_img headImg, a.create_time createTime FROM sys_user a WHERE 1=1 and user_name = ?
2018-04-21 19:46:52,701 DEBUG [main] (BaseJdbcLogger.java:145) - ==> Parameters: admin(String)
2018-04-21 19:46:52,702 TRACE [main] (BaseJdbcLogger.java:151) - <==    Columns: id, userName, userPassword, userEmail, userInfo, headImg, createTime
2018-04-21 19:46:52,702 TRACE [main] (BaseJdbcLogger.java:151) - <==        Row: 1, admin, 123456, admin@artisan.com, <<BLOB>>, <<BLOB>>, 2018-04-13 21:12:47.0
2018-04-21 19:46:52,703 DEBUG [main] (BaseJdbcLogger.java:145) - <==      Total: 1
2018-04-21 19:46:52,706  INFO [main] (UserMapperTest.java:571) - SysUser [id=1, userName=admin, userPassword=123456, userEmail=admin@artisan.com, userInfo=管理员用户, headImg=[18, 49, 35, 18, 48], createTime=Fri Apr 13 21:12:47 BOT 2018]
2018-04-21 19:46:52,706  INFO [main] (UserMapperTest.java:573) - ======3.什么都不传======
2018-04-21 19:46:52,707 DEBUG [main] (BaseJdbcLogger.java:145) - ==>  Preparing: SELECT a.id, a.user_name userName, a.user_password userPassword, a.user_email userEmail, a.user_info userInfo, a.head_img headImg, a.create_time createTime FROM sys_user a WHERE 1=1 and 1 = 2
2018-04-21 19:46:52,707 DEBUG [main] (BaseJdbcLogger.java:145) - ==> Parameters:
2018-04-21 19:46:52,709 DEBUG [main] (BaseJdbcLogger.java:145) - <==      Total: 0
2018-04-21 19:46:52,709  INFO [main] (UserMapperTest.java:581) -
2018-04-21 19:46:52,712  INFO [main] (UserMapperTest.java:587) - sqlSession close successfully

注意观察每个条件匹配的SQL语句


MyBatis-12MyBatis动态SQL之【choose when otherwise】相关推荐

  1. MyBatis的动态SQL详解

    MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑. MyBatis中用于实现动态SQL的元素主要有:   if choose(when,otherwis ...

  2. mybatis的动态sql的一些记录

    动态sql的作用:传统的使用JDBC的方法,相信大家在组合复杂的的SQL语句的时候,需要去拼接,稍不注意哪怕少了个空格,都会导致错误.Mybatis的动态SQL功能正是为了解决这种问题, 其通过 if ...

  3. MyBatis(三)——动态SQL

    文章目录 1. 简介 2. 搭建环境 2.1 在MySQL中创建blog表 2.2 编写实体类 2.3 编写实体类对应Mapper接口 2.4 编写Mapper接口对应的Mapper.xml文件 2. ...

  4. 9、mybatis中动态sql的使用

    对于初学者,如何进行mybatis的学习呢?我总结了几点,会慢慢的更新出来.首先大家需要了解mybatis是什么.用mybatis来做什么.为什么要用mybatis.有什么优缺点:当知道了为什么的时候 ...

  5. 2022/5/1 Mybatis框架动态SQL

    目录 1丶动态 SQL 2丶if标签 3丶choose.when.otherwise 4丶trim.where.set 5丶foreach 6丶script 7丶bind 8丶多数据库支持 9丶动态 ...

  6. MyBatis 03 动态SQL

    MyBatis 03 动态SQL 文章目录 MyBatis 03 动态SQL 一.学习目标 二.动态SQL if 标签2-1 if 标签2-2 where标签2-1 where 标签2-2 choos ...

  7. Mybatis学习-动态SQL

    Mybatis学习-动态SQL Mybatis学习-动态SQL Mybatis学习-动态SQL 什么是动态SQL 搭建环境 IF 接口 Mapper 测试 trim (where, set) wher ...

  8. 动态SQL之choose、when、otherwise标签

    动态SQL之choose.when.otherwise标签 choose.when.otherwise chose:父标签 when:相当于if...else if,只要有一个条件成立,其它的都不判断 ...

  9. mybatis之动态sql(超详细)

    动态SQL 可以根据具体的参数条件,来对SQL语句进行动态拼接. 比如在以前的开发中,由于不确定查询参数是否存在,许多人会使用类似于where 1 = 1 来作为前缀,然后后面用AND拼接要查询的参数 ...

  10. Mybatis中动态sql小结

    这篇文章讲述的是Mybatis中动态sql小结,如有错误或不当之处,还望各位大神批评指正. 什么是动态sql MyBatis 的强大特性之一便是它的动态 SQL,它极大的简化了我们拼接SQL的操作. ...

最新文章

  1. C++ 函数参数传递:传值,传指针,传引用
  2. 离散化小记,Acwing802. 区间和
  3. WebSphere Application Server中manageprofiles的使用
  4. EfficientNetV2 笔记
  5. 【Matlab】图添加箭头指示
  6. 基于阿里云镜像源使用kubeadm安装k8s单master节点集群(v1.17.3)
  7. [ZJOI2011]营救皮卡丘(费用流 + 最短路)
  8. 2021宣城职业技术学院对口高考成绩查询,2021年宣城职业技术学院高考录取通知书查询 通知书什么时候可以收到...
  9. 晶体管游戏 linux,Industrial Linux
  10. MacOS使用top命令查看进程使用内存
  11. 自学python能干些什么副业-学会Python有哪些可以做的兼职?
  12. matlab数字图像处理灰度变换ppt课件,数字图像处理 灰度变换.ppt
  13. 移动磁盘修复、格式化【微PE】
  14. windows性能监视器常用计数器
  15. 监测-病毒篇(病毒的了解和认识)
  16. 台式计算机常用总线,计算机中常见的总线有哪些
  17. 1894 完美的牛栏
  18. 毕业生怎样尽快把自己打造成国际专家级人物?
  19. python3 爬虫学习:自动给你心上人的微博点赞(一)
  20. 什么是强化学习?(主要的强化学习概念)

热门文章

  1. 最短路径:Dijkstra、BellmanFord以及SPFA算法
  2. Linux下CMake简明教程(五)正规一点的组织结构
  3. python 自然语言处理(二) jieba 分词
  4. 62. Leetcode 34. 在排序数组中查找元素的第一个和最后一个位置 (二分查找-局部有序)
  5. Idea配置spark环境及编写scala代码
  6. MATLAB实战系列(十八)-遗传算法解决TSP(旅行商)问题-算法原理
  7. MATLAB句柄相关函数和代码示例(设置美化图表属性)
  8. Matlab分布式和并行编程
  9. matlab中step_使用MATLAB中bertool进行通信仿真
  10. tf.ConfigProto()函数