• 动态SQL:if 语句
  • 动态SQL:if+where 语句
  • 动态SQL:if+set 语句
  • 动态SQL:choose(when,otherwise) 语句
  • 动态SQL:trim 语句
  • 动态SQL: SQL 片段
  • 动态SQL: foreach 语句

使用 mybatis 动态SQL,通过 if, choose, when, otherwise, trim, where, set, foreach等标签,可组合成非常灵活的SQL语句,从而在提高 SQL 语句的准确性的同时,也大大提高了开发人员的效率。

数据库的表结构:


1、动态SQL:if 语句


根据 username 和 sex 来查询数据。如果username为空,那么将只根据sex来查询;反之只根据username来查询

首先不使用 动态SQL 来书写

<select id="selectUserByUsernameAndSex"resultType="user" parameterType="com.ys.po.User"><!-- 这里和普通的sql 查询语句差不多,对于只有一个参数,后面的 #{id}表示占位符,里面不一定要写id,写啥都可以,但是不要空着,如果有多个参数则必须写pojo类里面的属性 -->select * from user where username=#{username} and sex=#{sex}
</select>

上面的查询语句,我们可以发现,如果 #{username} 为空,那么查询结果也是空,如何解决这个问题呢?使用 if 来判断

<select id="selectUserByUsernameAndSex" resultType="user" parameterType="com.ys.po.User">select * from user where<if test="username != null">username=#{username}</if><if test="username != null">and sex=#{sex}</if>
</select>

这样写我们可以看到,如果 sex 等于 null,那么查询语句为 select * from user where username=#{username},但是如果usename 为空呢?那么查询语句为 select * from user where and sex=#{sex},这是错误的 SQL 语句,如何解决呢?请看下面的 where 语句


2、动态SQL:if+where 语句


<select id="selectUserByUsernameAndSex" resultType="user" parameterType="com.ys.po.User">select * from user<where><if test="username != null">username=#{username}</if><if test="username != null">and sex=#{sex}</if></where>
</select>

这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。


3、动态SQL:if+set 语句


同理,上面的对于查询 SQL 语句包含 where 关键字,如果在进行更新操作的时候,含有 set 关键词,我们怎么处理呢?

<!-- 根据 id 更新 user 表的数据 -->
<update id="updateUserById" parameterType="com.ys.po.User">update user u<set><if test="username != null and username != ''">u.username = #{username},</if><if test="sex != null and sex != ''">u.sex = #{sex}</if></set>where id=#{id}
</update>

这样写,如果第一个条件 username 为空,那么 sql 语句为:update user u set u.sex=? where id=?

如果第一个条件不为空,那么 sql 语句为:update user u set u.username = ? ,u.sex = ? where id=?


4、动态SQL:choose(when,otherwise) 语句


有时候,我们不想用到所有的查询条件,只想选择其中的一个,查询条件有一个满足即可,使用 choose 标签可以解决此类问题,类似于 Java 的 switch 语句

<select id="selectUserByChoose" resultType="com.ys.po.User" parameterType="com.ys.po.User">select * from user<where><choose><when test="id !='' and id != null">id=#{id}</when><when test="username !='' and username != null">and username=#{username}</when><otherwise>and sex=#{sex}</otherwise></choose></where></select>

也就是说,这里我们有三个条件,id,username,sex,只能选择一个作为查询条件

如果 id 不为空,那么查询语句为:select * from user where  id=?

如果 id 为空,那么看username 是否为空,如果不为空,那么语句为 select * from user where  username=?;

如果 username 为空,那么查询语句为 select * from user where sex=?


5、动态SQL:trim 语句


trim标记是一个格式化的标记,可以完成set或者是where标记的功能

①、用 trim 改写上面第二点的 if+where 语句

<select id="selectUserByUsernameAndSex" resultType="user" parameterType="com.ys.po.User">select * from user<!-- <where><if test="username != null">username=#{username}</if><if test="username != null">and sex=#{sex}</if></where>  --><trim prefix="where" prefixOverrides="and | or"><if test="username != null">and username=#{username}</if><if test="sex != null">and sex=#{sex}</if></trim></select>

prefix:前缀      

prefixoverride:去掉第一个and或者是or

②、用 trim 改写上面第三点的 if+set 语句

<!-- 根据 id 更新 user 表的数据 --><update id="updateUserById" parameterType="com.ys.po.User">update user u<!-- <set><if test="username != null and username != ''">u.username = #{username},</if><if test="sex != null and sex != ''">u.sex = #{sex}</if></set> --><trim prefix="set" suffixOverrides=","><if test="username != null and username != ''">u.username = #{username},</if><if test="sex != null and sex != ''">u.sex = #{sex},</if></trim>where id=#{id}</update>

suffix:后缀  

suffixoverride:去掉最后一个逗号(也可以是其他的标记,就像是上面前缀中的and一样)


6、动态SQL: SQL 片段


有时候可能某个 sql 语句我们用的特别多,为了增加代码的重用性,简化代码,我们需要将这些代码抽取出来,然后使用时直接调用。

比如:假如我们需要经常根据用户名和性别来进行联合查询,那么我们就把这个代码抽取出来,如下:

<!-- 定义 sql 片段 -->
<sql id="selectUserByUserNameAndSexSQL"><if test="username != null and username != ''">AND username = #{username}</if><if test="sex != null and sex != ''">AND sex = #{sex}</if>
</sql>

引用 sql 片段

<select id="selectUserByUsernameAndSex" resultType="user" parameterType="com.ys.po.User">select * from user<trim prefix="where" prefixOverrides="and | or"><!-- 引用 sql 片段,如果refid 指定的不在本文件中,那么需要在前面加上 namespace --><include refid="selectUserByUserNameAndSexSQL"></include><!-- 在这里还可以引用其他的 sql 片段 --></trim>
</select>

注意:①、最好基于 单表来定义 sql 片段,提高片段的可重用性

   ②、在 sql 片段中不要包括 where


7、动态SQL: foreach 语句


需求:我们需要查询 user 表中 id 分别为1,2,3的用户

  sql语句:select * from user where id=1 or id=2 or id=3

       select * from user where id in (1,2,3)

①、建立一个 UserVo 类,里面封装一个 List<Integer> ids 的属性

package com.ys.vo;import java.util.List;public class UserVo {//封装多个用户的idprivate List<Integer> ids;public List<Integer> getIds() {return ids;}public void setIds(List<Integer> ids) {this.ids = ids;}}  

②、我们用 foreach 来改写 select * from user where id=1 or id=2 or id=3

<select id="selectUserByListId" parameterType="com.ys.vo.UserVo" resultType="com.ys.po.User">select * from user<where><!--collection:指定输入对象中的集合属性item:每次遍历生成的对象open:开始遍历时的拼接字符串close:结束时拼接的字符串separator:遍历对象之间需要拼接的字符串select * from user where 1=1 and (id=1 or id=2 or id=3)--><foreach collection="ids" item="id" open="and (" close=")" separator="or">id=#{id}</foreach></where>
</select>

 测试:

//根据id集合查询user表数据
@Test
public void testSelectUserByListId(){String statement = "com.ys.po.userMapper.selectUserByListId";UserVo uv = new UserVo();List<Integer> ids = new ArrayList<>();ids.add(1);ids.add(2);ids.add(3);uv.setIds(ids);List<User> listUser = session.selectList(statement, uv);for(User u : listUser){System.out.println(u);}session.close();
}

③、我们用 foreach 来改写 select * from user where id in (1,2,3)

<select id="selectUserByListId" parameterType="com.ys.vo.UserVo" resultType="com.ys.po.User">select * from user<where><!--collection:指定输入对象中的集合属性item:每次遍历生成的对象open:开始遍历时的拼接字符串close:结束时拼接的字符串separator:遍历对象之间需要拼接的字符串select * from user where 1=1 and id in (1,2,3)--><foreach collection="ids" item="id" open="and id in (" close=") " separator=",">#{id}</foreach></where>
</select>

  

Mybatis的动态sql(五)相关推荐

  1. MyBatis 03 动态SQL

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

  2. MyBatis的动态SQL详解

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

  3. Mybatis解析动态sql原理分析

    前言 废话不多说,直接进入文章. 我们在使用mybatis的时候,会在xml中编写sql语句. 比如这段动态sql代码: <update id="update" parame ...

  4. MyBatis中动态sql实现时间范围比较的查询

    场景 前端传递两个时间参数,开始时间和结束时间,然后从数据库中筛选出某个时间属性在此范围的数据. Mybatis的动态sql的写法. 注: 博客: https://blog.csdn.net/bada ...

  5. MyBatis中动态sql的模糊搜索、foreach实现In集合的用法

    场景 在使用MyBatis的动态sql时,常见的是传递一个ID的数组,查询记录的 ID在这个数组中的记录和模糊搜索这两种场景. 注: 博客: https://blog.csdn.net/badao_l ...

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

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

  7. MyBatis(三)——动态SQL

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

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

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

  9. 利用MyBatis的动态SQL特性抽象统一SQL查询接口

    1. SQL查询的统一抽象 MyBatis制动动态SQL的构造,利用动态SQL和自定义的参数Bean抽象,可以将绝大部分SQL查询抽象为一个统一接口,查询参数使用一个自定义bean继承Map,使用映射 ...

  10. java day55【 Mybatis 连接池与事务深入 、 Mybatis 的动态 SQL 语句、 Mybatis 多表查询之一对多 、 Mybatis 多表查询之多对多】...

    第1章 Mybatis 连接池与事务深入 1.1 Mybatis 的连接池技术 1.1.1 Mybatis 连接池的分类 1.1.2 Mybatis 中数据源的配置 1.1.3 Mybatis 中 D ...

最新文章

  1. Web Developer中文版下载
  2. 华为:HarmonyOS 即将开源!
  3. linux下一款好用的命令行浏览器
  4. 【商业落地篇】Gartner第四范式全球首发AutoML系列白皮书(限时免费下载)
  5. JeeSite 4.0 (1.0)开发环境部署运行
  6. html+dom+深入,DOM 深入学习 - 1
  7. layui搭建的php后台,使用layui框架搭建后台布局
  8. 如何将php里面的首行缩进_word首行缩进排版的三个技巧
  9. 【经验之谈】碰到了放养式的研究生导师,在读研期间该怎么做?
  10. j$(function() j$(document).ready 区别
  11. 整合SSH框架实现简单登录
  12. Excel函数实战技巧精粹(五)LEN和LENB等函数之常用用法
  13. 读书笔记|《金字塔原理》第三章
  14. 初中信息技术考试:Python试题及答案
  15. 自己动手写2D物理引擎-初级篇(1)
  16. 锤子手机(smartisan t1)如何查看mac地址
  17. CSP多USBkey操作获取信息
  18. Windows操作系统免费下载地址(itellyou)
  19. Web服务器、应用服务器、数据库服务器之间的关系
  20. 第11章实验1:学生成绩管理系统V4.0(C语言)

热门文章

  1. 软件工程——进展记录
  2. ADO.NET知识点
  3. 文本框中只能输入小于等于100的正整数
  4. 谈MicroMessageTest的开始创建
  5. java.io.Serializable 序列化问题【原】
  6. [笔记]kubernetes 无法启动问题
  7. 生成 linq to sharepoint 对象模型sharepoint 母板页
  8. mysql别人的框架_MySQL逻辑架构
  9. centos上升级node_在centos7安装nodejs并升级nodejs到最新版本
  10. 十二星座PSD分层海报,治愈心灵,谁见谁爱!