MyBatis 令人喜欢的一大特性就是动态 SQL。在使用 JDBC 的过程中, 根据条件进行 SQL 的拼接是很麻烦且很容易出错的。MyBatis 动态 SQL 的出现, 解决了这个麻烦。

MyBatis通过 OGNL 来进行动态 SQL 的使用的。目前, 动态 SQL 支持以下几种标签:

1 数据准备

为了后面的演示, 创建了一个 Maven 项目 mybatis-dynamic, 创建了对应的数据库和表

DROP TABLE IF EXISTS `student`;CREATE TABLE `student` ( `student_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '编号', `name` varchar(20) DEFAULT NULL COMMENT '姓名', `phone` varchar(20) DEFAULT NULL COMMENT '电话', `email` varchar(50) DEFAULT NULL COMMENT '邮箱', `sex` tinyint(4) DEFAULT NULL COMMENT '性别', `locked` tinyint(4) DEFAULT NULL COMMENT '状态(0:正常,1:锁定)', `gmt_created` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '存入数据库的时间', `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改的时间', `delete` int(11) DEFAULT NULL, PRIMARY KEY (`student_id`)) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='学生表';

对应的项目结构

2 if 标签

if 标签是我们最常使用的。在查询、删除、更新的时候很可能会使用到。必须结合 test 属性联合使用。

2.1 在 WHERE 条件中使用 if 标签

这是常见的一种现象, 我们在进行按条件查询的时候, 可能会有多种情况。

2.1.1 查询条件

根据输入的学生信息进行条件检索

  • 当只输入用户名时, 使用用户名进行模糊检索;
  • 当只输入性别时, 使用性别进行完全匹配
  • 当用户名和性别都存在时, 用这两个条件进行查询匹配查询

2.1.2 动态 SQL

接口函数

 /** * 根据输入的学生信息进行条件检索 * 1. 当只输入用户名时, 使用用户名进行模糊检索; * 2. 当只输入邮箱时, 使用性别进行完全匹配 * 3. 当用户名和性别都存在时, 用这两个条件进行查询匹配的用 * @param student * @return */ List selectByStudentSelective(Student student);

对应的动态 SQL

  select  from student where 1=1  and name like concat('%', #{name}, '%')  and sex=#{sex} 

在此 SQL 语句中, where 1=1 是多条件拼接时的小技巧, 后面的条件查询就可以都用 and 了。

同时, 我们添加了 if 标签来处理动态 SQL

  and name like concat('%', #{name}, '%')  and sex=#{sex} 

此 if 标签的 test 属性值是一个符合 OGNL 的表达式, 表达式可以是 true 或 false。如果表达式返回的是数值, 则0为 false, 非 0 为 true;

2.1.3 测试

 @Test public void selectByStudent() { SqlSession sqlSession = null; sqlSession = sqlSessionFactory.openSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); Student search = new Student(); search.setName("明"); System.out.println("只有名字时的查询"); List studentsByName = studentMapper.selectByStudentSelective(search); for (int i = 0; i < studentsByName.size(); i++) { System.out.println(ToStringBuilder.reflectionToString(studentsByName.get(i), ToStringStyle.MULTI_LINE_STYLE)); } search.setName(null); search.setSex((byte) 1); System.out.println("只有性别时的查询"); List studentsBySex = studentMapper.selectByStudentSelective(search); for (int i = 0; i < studentsBySex.size(); i++) { System.out.println(ToStringBuilder.reflectionToString(studentsBySex.get(i), ToStringStyle.MULTI_LINE_STYLE)); } System.out.println("姓名和性别同时存在的查询"); search.setName("明"); List studentsByNameAndSex = studentMapper.selectByStudentSelective(search); for (int i = 0; i < studentsByNameAndSex.size(); i++) { System.out.println(ToStringBuilder.reflectionToString(studentsByNameAndSex.get(i), ToStringStyle.MULTI_LINE_STYLE)); } sqlSession.commit(); sqlSession.close(); }

只有名字时的查询, 发送的语句和结果

查询的条件只发送了

where 1=1 and name like concat('%', ?, '%') 

只有性别时的查询, 发送的语句和结果

查询的条件只发送了

where 1=1 and sex=? 

姓名和性别同时存在的查询, 发送的语句和结果

查询条件

where 1=1 and name like concat('%', ?, '%') and sex=? 

2.2 在 UPDATE 更新列中使用 if 标签

有时候我们不希望更新所有的字段, 只更新有变化的字段。

2.2.1 更新条件

只更新有变化的字段, 空值不更新。

2.2.1 动态 SQL

接口方法

 /** * 更新非空属性 */ int updateByPrimaryKeySelective(Student record);

对应的 SQL

  update student  `name` = #{name,jdbcType=VARCHAR},  phone = #{phone,jdbcType=VARCHAR},  email = #{email,jdbcType=VARCHAR},  sex = #{sex,jdbcType=TINYINT},  locked = #{locked,jdbcType=TINYINT},  gmt_created = #{gmtCreated,jdbcType=TIMESTAMP},  gmt_modified = #{gmtModified,jdbcType=TIMESTAMP},  where student_id = #{studentId,jdbcType=INTEGER}

2.2.3 测试

 @Test public void updateByStudentSelective() { SqlSession sqlSession = null; sqlSession = sqlSessionFactory.openSession(); StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class); Student student = new Student(); student.setStudentId(1); student.setName("明明"); student.setPhone("13838438888"); System.out.println(studentMapper.updateByPrimaryKeySelective(student)); sqlSession.commit(); sqlSession.close(); }

结果如下

2.3 在 INSERT 动态插入中使用 if 标签

我们插入数据库中的一条记录, 不是每一个字段都有值的, 而是动态变化的。在这时候使用 if 标签, 可帮我们解决这个问题。

2.3.1 插入条件

只有非空属性才插入。

2.3.2 动态SQL

接口方法

 /** * 非空字段才进行插入 */ int insertSelective(Student record);

对应的SQL

 insert into student 

mybatis注解动态sql_超全MyBatis动态SQL详解相关推荐

  1. 上手Redis系列(六):超全Geospatial特殊类型详解(地理位置)

    学习Redis之前,我还是觉得我务必跟你说一声,也是在我文章之中说的很多的一句话,我想也会适用于学习Redis,那就是在接触文章里的Reids命令时,不用试图去记这些命令 ,用到时去看API帮助文档即 ...

  2. 【超全】一文详解机器学习特征工程(附代码)

    特征工程是使用专业背景知识和技巧处理数据,使得特征值(自变量)能在机器学习算法上发挥更好的作用的过程.python的sklearn库,对于特征工程的处理提供了强大的接口. 在本文中,我将详细介绍特征工 ...

  3. Mybatis注解开发(超详细)

    Mybatis注解开发 mybatis的常用注解 使用 Mybatis 注解实现基本 CRUD 项目目录结构 编写实体类 使用注解方式开发持久层接口 编写 SqlMapConfig.xml 配置文件 ...

  4. python3d动态图-Python图像处理之gif动态图的解析与合成操作详解

    本文实例讲述了Python图像处理之gif动态图的解析与合成操作.分享给大家供大家参考,具体如下: gif动态图是在现在已经司空见惯,朋友圈里也经常是一言不合就斗图.这里,就介绍下如何使用python ...

  5. c++定义一个动态全局变量_静态链接与动态链接的宏观概述及微观详解

    静态链接与动态链接的宏观概述及微观详解 第一部分 宏观概述 1. 静态链接 静态链接就是在程序运行前,链接器通过对象文件中包含的重定位表,完成所有重定位操作,并最终形成一个在运行时不需要再次进行依赖库 ...

  6. python调用shell脚本的参数_使用python执行shell脚本 并动态传参 及subprocess的使用详解

    最近工作需求中 有遇到这个情况 在web端获取配置文件内容 及 往shell 脚本中动态传入参数 执行shell脚本这个有多种方法 最后还是选择了subprocess这个python标准库 subpr ...

  7. iptable 详解_最全的iptables防火墙详解.pdf

    最全的iptables防火墙详解 iptables / iptables / iippttaabblleess官方网站:hhttttpp::nneettffiilltteerr..oorrgg// • ...

  8. centos7中ps显示的内容_值得收藏,史上最全Linux ps命令详解

    原标题:值得收藏,史上最全Linux ps命令详解 一.程序员的疑惑 大概在十多年前,我当时还是一个产品经理.由于一些工作的原因,需要向运维工程师学习一些linux常用命令. 当使用linux ps这 ...

  9. 猛兽之地服务器维护,猛兽之地Roguelands全材料获取途径详解

    以下就是小编为大家带来的猛兽之地Roguelands全材料获取途径详解: 蘑菇镇主要产出: 发光蘑菇 屎壳螂 少量怪兽抓 古老废墟主要产出: 甲壳碎片 辛辣种子 星空岩 折磨大陆主要产出: 星之果 少 ...

最新文章

  1. 使用C++ ostringstream来格式化字符串输出
  2. Hibernate annotation多对多配置
  3. Attachment multiple read API - performance with regular expression
  4. 玩转 Rockchip 的开发板,这些信息你要知道
  5. c#中的long类型示例_C#中带示例的无符号字节数组
  6. java作业 景区门票
  7. 第一章 在VS2008下如何配置好CG环境
  8. python实践gcForest模型对鸢尾花数据集iris进行分类
  9. ubuntu安装 ssh server
  10. Delphi 德尔菲法
  11. 面试:MRO问题 (理解笔记)
  12. 灵魂 我·将·归·来·开·放
  13. Cortex-A7 MPCore 架构
  14. 元气骑士卡无限服务器,元气骑士养剑葫怎么卡无限飞剑bug方法介绍
  15. 前端调取.net core webapi 报错:“...CORS policy: Response to preflight request ...“的问题成因和解决办法。
  16. ctr 平滑_ctr平滑
  17. SpringBoot+Vue+Element-UI实现人事管理系统
  18. Unity | 总结:OCR文字识别、公式识别
  19. AUTOSAR实验七 PWM和呼吸灯
  20. USB标准协议下载地址

热门文章

  1. 安卓5.0以上设备最简单激活XPOSED框架的步骤
  2. 盒马鲜生颠覆传统生鲜市场的胜算几何?
  3. 解决网络请求的依赖关系
  4. ES2017异步函数现已正式可用
  5. AIX 上安装SSH
  6. ×××服务器是指什么?我怎样控制自己的电脑端口的开启和关闭?
  7. 一行js代码识别Selenium+Webdriver及其应对方案 1
  8. 编程之性能优化知多少
  9. 为何要领域驱动设计?
  10. Spring ListFactoryBean实例