MyBatis之关于动态SQL解读

 更新时间:2023年06月28日 14:38:36   作者:不是很菜的菜  
这篇文章主要介绍了MyBatis之关于动态SQL解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

MyBatis动态SQL

MyBatis 动态SQL优点

MyBatis 的强大特性之一便是它的动态 SQL。

如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦,拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。

利用动态 SQL 这一特性可以彻底摆脱这种痛苦。

1、if

动态 SQL 通常要做的事情是有条件地包含 where 子句的一部分,例如

<select id="getByDept"  resultType="City">
        select * from provice
        <where>
               <if test="pid!=null">
                    pid=#{pid} 
                </if>
        </where>
    </select>

当满足if中的条件是就会把if中条件也加入进sql语句中,否则不会。

例如当pid不能与null时,就会查找provice表中pid为传入的值的数据,但是当pid=null时,就会查找provice表中的所有数据。

2、choose (when, otherwise) 

有些时候你并不想用到所有条件,但是有时候你又想用到这个条件,这个时候我们就可以用到choose(when,otherwise),这类似于java中的switch-case。

<select id="findStudentByChoose" resultType="City">
        SELECT * from city where 1=1
        <choose>
            <when test="cname!=null and cname!=''">
                and cname like concat(concat('%',#{cname}),'%')
            </when>
            <when test="pid!=0">
                and pid=#{pid}
            </when>
            <otherwise>
				<!-- 这里可以写,也可以不写代码-->
            </otherwise>
        </choose>
    </select>

这里提供了两种选择方式,你可以选择根据cname来查找,也可以选择根据pid来查找,但只要满足一个条件,其他条件则自动选择不满足,这样也可以避免无意义的查找。

(上面的1=1也可以不写,但是需要加入其他的东西,下面会提到)

3、trim(where)

前面例子已经合宜地解决了动态 SQL 问题,但是看下面的例子

<select id="getByDept"  resultType="City">
        select * from provice where
               <if test="pid!=null">
                    pid=#{pid} and
                </if>
                <if test="cname!=null and cname!=''">
                    and pname like concat(concat('%',#{cname}),'%')
               </if>
    </select>

当没有一个条件满足时,这会变成

select * from provice where

这样的sql语句并不正确,另外当第一个条件不满足,第二个条件满足时则会变成

select * from provice where
and pname like concat(concat('%',#{cname}),'%')

这个查询也会失败。

这个问题不能简单的用条件句式来解决,这个时候我们就可以选择使用trim(where)

<select id="getByDept"  resultType="City">
        select * from provice where
            <trim suffix="" suffixOverrides="and">
               <if test="pid!=null">
                    pid=#{pid} and
                </if>
                <if test="cname!=null and cname!=''">
                    and pname like concat(concat('%',#{cname}),'%')
               </if>
            </trim>
    </select>

where 元素知道只有在一个以上的if条件有值的情况下才去插入"WHERE"子句。

而且,若最后的内容是"AND"或"OR"开头的,where 元素也知道如何将他们去除。

如果 where 元素没有按正常套路出牌,我们还是可以通过自定义 trim 元素来定制我们想要的功能。

4、foreach

动态 SQL 的另外一个常用的必要操作是需要对一个集合进行遍历,通常是在构建 IN 条件语句的时候。

注意 你可以将一个 List 实例或者数组作为参数对象传给 MyBatis,当你这么做的时候,MyBatis 会自动将它包装在一个 Map 中并以名称为键。

List 实例将会以"list"作为键,而数组实例的键将是"array"。

例如:

<!--根据数组来找-->
    <select id="findStudentByArray" resultType="City">
        SELECT * from city where pid in 
        <foreach collection="array" item="pid" open="(" separator="," close=")">
            #{pid}
        </foreach>
    </select>
    <!--根据列表来找-->
    <select id="findStudentByList" resultType="City">
        select * from city WHERE pid in
        <foreach collection="list" item="pid" open="(" separator="," close=")">
            #{pid}
        </foreach>
    </select>
    <!--根据map来找-->
    <select id="findStudentByMap" resultType="City">
        SELECT * from city where cname like concat(concat('%',#{cname}),'%') and pid in
        				<!--这里的name则根据前面传入的key值来确定-->
        <foreach collection="name" item="map" open="(" separator="," close=")">
            #{map}
        </foreach>
    </select>

5、bind

bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。

例如

<select id="bind" resultType="Provice">
  <bind name="pro" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM porvice
  WHERE pid LIKE #{pro}
</select>

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • JDK1.8中的ConcurrentHashMap使用及场景分析

    JDK1.8中的ConcurrentHashMap使用及场景分析

    这篇文章主要介绍了JDK1.8中的ConcurrentHashMap使用及场景分析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • Java反射机制的讲解

    Java反射机制的讲解

    今天小编就为大家分享一篇关于Java反射机制的讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-04-04
  • struts2 中文乱码的解决办法分享

    struts2 中文乱码的解决办法分享

    这篇文章主要介绍了struts2 中文乱码的解决办法,需要的朋友可以参考下
    2014-02-02
  • SpringBoot集成ENC对配置文件进行加密的流程步骤

    SpringBoot集成ENC对配置文件进行加密的流程步骤

    Spring Boot Encoder,即Spring Boot加密模块,它提供了一种简单的方式来集成安全编码功能到Spring Boot应用程序中,它是Spring Security框架的一部分,旨在帮助开发者轻松地处理数据加密,本文给大家介绍了SpringBoot集成ENC对配置文件进行加密的流程步骤
    2024-12-12
  • Spring Boot实现配置文件的自动加载和刷新功能

    Spring Boot实现配置文件的自动加载和刷新功能

    这篇文章我们介绍了Spring Boot如何实现配置文件的自动加载和刷新,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-05-05
  • Java日常练习题,每天进步一点点(41)

    Java日常练习题,每天进步一点点(41)

    下面小编就为大家带来一篇Java基础的几道练习题(分享)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望可以帮到你
    2021-07-07
  • springboot跨域CORS处理代码解析

    springboot跨域CORS处理代码解析

    这篇文章主要介绍了springboot跨域CORS处理代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • java使用stream判断两个list元素的属性并输出方式

    java使用stream判断两个list元素的属性并输出方式

    这篇文章主要介绍了java使用stream判断两个list元素的属性并输出方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • IDEA类存在但找不到的解决办法

    IDEA类存在但找不到的解决办法

    本文主要介绍了IDEA类存在但找不到的解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • java中TESTful架构原理分析

    java中TESTful架构原理分析

    这篇文章主要介绍了对java架构中TESTful架构原理进行了详细的原理分析,有需要的朋友可以借鉴参考下,希望可以有所帮助,祝大家多多进步,早日升职加薪
    2021-09-09

最新评论