动态SQL语句,也就意味着SQL语句不在是一成不变的而是具有多样性.

if

  if的用法还是跟平常差不多的(不过没有else if也没有else)

<update id="modify" parameterType="User">
UPDATE `smbms_user`
<trim prefix="set" suffixOverrides="," suffix="where id=#{id}">
<if test="userCode!=null">`userCode` = #{userCode} , </if>
<if test="userName!=null">`userName` = #{userName} , </if>
<if test="userPassword!=null">`userPassword` = #{userPassword} , </if>
<if test="gender!=null">`gender` = #{gender} , </if>
<if test="birthday!=null">`birthday` = #{birthday} ,</if>
<if test="phone!=null">`phone` = #{phone} , </if>
<if test="address!=null">`address` = #{address} , </if>
<if test="userRole!=null">`userRole` = #{userRole} , </if>
<if test="createdBy!=null">`createdBy` = #{createdBy} , </if>
<if test="creationDate!=null">`creationDate` = #{creationDate} , </if>
<if test="modifyBy!=null">`modifyBy` = #{modifyBy}</if>
</trim>
</update>

如上面的代码,如果是空的字段则不执行更新操作

choose(when,otherwise)

  choose就相当于Java中的switch,when相当于case,otherwise相当于default

<select id="getBill" resultType="Bill">
SELECT * FROM smbms_bill b JOIN smbms_provider p ON b.providerId=p.id
WHERE 1=1
<choose>
<!-- 条件为false则继续执行下面的when,反之亦然如此 -->
<when test="id!=null">
AND b.providerId=#{id}
</when>
<!-- 条件为true则不会执行otherwise,反之亦然如此 -->
<when test="proName!=null">
AND p.proName LIKE CONCAT('%',#{proName},'%')
</when>
<!-- 当都不满足时执行默认值 -->
<otherwise>
AND p.proContact LIKE CONCAT('%张%')
</otherwise>
</choose>
</select>

where

此标签可以忽略条件中多余的and和or如下

SELECT * FROM smbms_bill b JOIN smbms_provider p  ON b.providerId=p.id
<where>
<if test="id!=null">
AND b.providerId=#{id}
</if>
<if test="proName!=null">
AND p.proName LIKE CONCAT('%',#{proName},'%')
</if>
</where>

假设id为1 proName为北京 两个if都满足条件时就会拼凑成这样

SELECT * FROM smbms_bill b JOIN smbms_provider p  ON b.providerId=p.id WHERE b.providerId=1 AND p.proName LIKE CONCAT('%北京%')

其实解决这种情况不用where也是可以的,只需在前面加上一个为真的条件即可

SELECT * FROM smbms_bill b JOIN smbms_provider p  ON b.providerId=p.id
where 1=1
<if test="id!=null">
AND b.providerId=#{id}
</if>
<if test="proName!=null">
AND p.proName LIKE CONCAT('%',#{proName},'%')
</if>

效果也是一样的

set

此标签可以忽略多余的逗号

UPDATE `smbms_user`
<set>
<if test="userPassword!=null">
`userPassword` = #{userPassword},
</if>
</set>
WHERE `id` = #{id} ;

trim

此标签属性如下

  1. prefix:通过自动识别是否有返回值,在trim包含的内容上加上前缀
  2. suffix:在trim包含的内容上加上后缀
  3. prefixoverrides:对trim包含内容的首部进行指定内容的忽略
  4. suffixoverrides;对于trim包含内容的尾部进行指定内容的忽略

栗子1

<!-- 添加内容前面加上 where 并且忽略 and或者or -->
<trim prefix="where" prefixOverrides="and|or">
<if test="userRole!=null">
and userRole=#{userRole}
</if>
<if test="userName!=null and userName!=''">
and u.userName like CONCAT('%',#{userName},'%')
</if>
order by creationDate DESC limit #(from),#(pageSize)
</trim>

栗子2

UPDATE `smbms_user`
<!-- 在内容前加上 set 并且忽略内容最后的逗号 且在内容后面加上查询条件 -->
<trim prefix="set" suffixOverrides="," suffix="where id=#{id}">
<if test="userCode!=null">`userCode` = #{userCode} , </if>
<if test="userName!=null">`userName` = #{userName} , </if>
</trim>

foreach

此标签的属性如下

  1. item表示集合中每一个元素进行迭代时的别名
  2. index:指定一个名字,用于表示每次迭代的位置.好比for循环中自定义的 i
  3. open表示该语句以什么开始,在in条件语句中以"("开始
  4. separator表示在每次进行迭代之间以什么符号作为分隔 符,在in条件语句中以逗号进行分隔
  5. close表示以什么结束。在in条件语句中以")"结尾
  6. 在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,主要有以下3种情况:
    1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
    2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
    3. 如果传入的参数是多个的时候,我们一般把它们封装成一个Map了,此时属性值为map其中的一个key

栗子1

当入参为list时

<select id="getUSerByRoleId_foreach_list" resultMap="userMapByRole">
select * from smbms_user where userRole in
<!-- 因为此处用了in,因此以 "("开头 ,")"结尾 ,","分隔 -->
<foreach collection="list" item="roleList" open="(" separator="," close=")">
#{roleList}
</foreach>
</select>

栗子2

当入参为数组时

<select id="getUserByRoleId_foreach_array" resultMap="userMapByRole">
select * from smbms_user where userRole in
<!-- 因为此处用了in,因此以 "("开头 ,")"结尾 ,用","分隔 -->
<foreach collection="array" item="roleIds" open="(" separator="," close=")">
#{roleIds}
</foreach>
</select>

栗子3

当为map时

<select id="getProvider"  resultMap="providerresult">
SELECT * FROM smbms_bill b JOIN smbms_provider p ON b.providerId=p.id
where b.providerId in
<!-- 因为此处用了in,因此以 "("开头 ,")"结尾 ,","分隔 此时的collection的值是map其中的一个key-->
<foreach collection="#{bibli}" item="pros" open="(" separator="," close=")">
<!-- 获取对象当中的属性 -->
#{pros.providerId}
</foreach>
</select>

小结

  • if+set:动态完成更新操作
  • if+where:动态完成多条件查询
  • if+trim:完成多条件查询(代替where)或者更新操作(代替set)
  • choose(when,otherwise):动态完成多条件查询(多选一)
  • foreach:主要用于in条件查询中,迭代集合,最关键的部分为collection属性,根据不同的入参类型,该属性值则不同
    1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
    2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
    3. 如果传入的参数是多个的时候,我们一般把它们封装成一个Map了,此时属性值为map其中的一个key

mybatis中实现动态SQL的更多相关文章

  1. 【mybatis深度历险系列】mybatis中的动态sql

    最近一直做项目,博文很长时间没有更新了,今天抽空,学习了一下mybatis,并且总结一下.在前面的博文中,小编主要简单的介绍了mybatis中的输入和输出映射,并且通过demo简单的介绍了输入映射和输 ...

  2. mybatis中的动态SQL

    在实际开发中,数据库的查询很难一蹴而就,我们往往要根据各种不同的场景拼接出不同的SQL语句,这无疑是一项复杂的工作,我们在使用mybatis时,mybatis给我们提供了动态SQL,可以让我们根据具体 ...

  3. 6.Mybatis中的动态Sql和Sql片段(Mybatis的一个核心)

    动态Sql是Mybatis的核心,就是对我们的sql语句进行灵活的操作,他可以通过表达式,对sql语句进行判断,然后对其进行灵活的拼接和组装.可以简单的说成Mybatis中可以动态去的判断需不需要某些 ...

  4. mybatis中的动态SQL语句

    有时候,静态的SQL语句并不能满足应用程序的需求.我们可以根据一些条件,来动态地构建 SQL语句. 例如,在Web应用程序中,有可能有一些搜索界面,需要输入一个或多个选项,然后根据这些已选择的条件去执 ...

  5. mybatis中的动态SQL(IF Chooes When Where Set ForEach SQL片段)

    mapper: public interface BlogMapper { List<Blog> getBlogByIF(Map map); } IF <select id=&quo ...

  6. 阶段3 1.Mybatis_08.动态SQL_01.mybatis中的动态sql语句-if标签

    创建新的工程 复制到新建的项目里面 pom.xml依赖部分复制过来 dao中整理代码 只保留四个查询 映射文件也只保留四个查询方法 增加一个根据条件查询的方法. 由于用了别名,所以parpameter ...

  7. mybatis 详解------动态SQL

    mybatis 详解------动态SQL   目录 1.动态SQL:if 语句 2.动态SQL:if+where 语句 3.动态SQL:if+set 语句 4.动态SQL:choose(when,o ...

  8. Mybatis映射文件动态SQL语句-01

    因为在很多业务逻辑复杂的项目中,往往不是简单的sql语句就能查询出来自己想要的数据,所有mybatis引入了动态sql语句, UserMapper.xml <?xml version=" ...

  9. 使用CASE表达式替代SQL Server中的动态SQL

    原文:使用CASE表达式替代SQL Server中的动态SQL 翻译自: http://www.mssqltips.com/sqlservertip/1455/using-the-case-expre ...

随机推荐

  1. pat1049. Counting Ones (30)

    1049. Counting Ones (30) 时间限制 10 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue The task ...

  2. Java中的==和equals区别

    概述: A.==可用于基本类型和引用类型:当用于基本类型时候,是比较值是否相同:当用于引用类型的时候,是比较对象是否相同. B.对于String a = “a”; Integer b = 1;这种类型 ...

  3. Windows安全认证是如何进行的?[Kerberos篇]

    最近一段时间都在折腾安全(Security)方面的东西,比如Windows认证.非对称加密.数字证书.数字签名.TLS/SSL.WS-Security等.如果时间允许,我很乐意写一系列的文章与广大网友 ...

  4. SpringMVC05 return (Json)

    这里要主要的是js文件要引入,文中不做解释 1.导入包 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xs ...

  5. 八个cmd 命令

    一,ping 它是用来检查网络是否通畅或者网络连接速度的命令.作为一个生活在网络上的管理员或者黑客来说,ping命令是第一个必须掌握的DOS命令,它所利用的原理是这样的:网络上的机器都有唯一确定的IP ...

  6. flask--数据库连接--URL

    使用URL制定数据库 数据库引擎 URL MySQL mysql://username:password@hostname/database Postgres postgresql://usernam ...

  7. 北航oo作业第四单元小结

    1.总结本单元两次作业的架构设计 在我动手开始总结我的设计之前,我看了其他同学已经提交在班级群里的博客,不禁汗颜,我是真的偷懒.其他同学大多使用了新建一个类,用以储存每一个UMLelemet元素的具体 ...

  8. Vue2.0搭建脚手架(vue-cli)

    一.安装node.js 进入官网下载node.js 二.安装 cnpm 1.说明:npm(node package manager)是nodejs的包管理器,用于node插件管理(包括安装.卸载.管理 ...

  9. Android各大手机系统打开权限管理页面

    最近项目上比较忙,终于有空闲时间写写东西了. 相信做过Android的都知道,现在的手机系统五花八门,当我们去请求用户的权限的时候,总是会弹出是否允许的对话框. 而且用户一旦不小心点了拒绝,下次就不再 ...

  10. c#中反射技术在Unity中的运用

    反射技术给类赋值的好处就是可以简化代码,封装的好处就显而易见了.最直接的用途就是用在在显示配置文件的时候,个人习惯性做法是做一个VO来存储需要的数据,其代码如下: internal class Bas ...