文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

MyBatis 超详细讲解动态SQL的实现

2024-04-02 19:55

关注

情景:

     我们在使用JDBC或者其他类似的框架开发进行数据库开发时,通常要根据需求动手组装SQL,不用想都觉得是件很痛苦的事情了,而Mybatis框架提供的对SQL语句动态组装的功能,能很好地解决这个麻烦。

概述:

     动态SQL是MyBatis框架的一个强大特性,MyBatis3可采用功能强大的基于OGNL的表达式来完成动态SQL,它删除了之前版本中需要了解的大多数元素,只使用不到原来一半的元素就能完成所需的工作。

SQL元素:

SQL元素说明
<if>判断语句,用于单条件分支判断
<choose>  (<when>,<otherwise>)相当于Java中的switch...case...default语句,用于多条件分支判断
<where>简化SQL语句中的where的条件判断
<trim>可以灵活地去除多余的关键字
<set>解决动态更新语句
<foreach>循环语句,常用于in语句等列举条件中
<bind>从OGNL表达式中创建一个变量,并将其绑定到上下文,常用于模糊查询的SQL中

<if>:

使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.mapper.BookMapper">
 
    <resultMap id="BookType" type="org.example.po.Book">
        <id property="id" column="id"></id>
        <result property="bookName" column="bookName"></result>
        <result property="price" column="price"></result>
        <result property="publisher" column="publisher"></result>
    </resultMap>
 
    <select id="bookSelectById" parameterType="int" resultMap="BookType">
        select * from t_book
        <where>
            <if test="id!=null and id!=''">
                id=#{id}
            </if>
        </where>
    </select>
 
    <select id="bookSelectByname" parameterType="string" resultMap="BookType">
        select * from t_book
        <where>
            <if test="bookNmae!=null and bookName!=''">
                bookName LIKE concat('%',#{bookName},'%')
            </if>
        </where>
    </select>
 
</mapper>

<choose>:

      有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

因为自己写的是单查询,引用官网代码。

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE'
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

<where>:

     <where>标签相当于 where 1=1 ,主要用来简化SQL语句中的where条件判断,并能智能地处理and和or不必担心多余关键字导致的语法错误。代码参考<if>标签代码。

<trim>:

      这个标签我觉得是最灵活的,trim元素也会自动识别其标签内是否有返回值,若有的话,则会在已包含的内容前加上某些前缀或者后缀(先判断是否有语句包含),用到的属性是

 1、prefix(前缀),suffix(后缀)

还可以把包含内容的首内容或尾内容的符号去掉,用到的属性是

2、prefixOverride(前缀覆盖),suffixOverride(后缀覆盖)

可以说功能很强大,可以利用它来替代where元素,并实现与where元素相同的效果。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.mapper.BookMapper">
 
    <resultMap id="BookType" type="org.example.po.Book">
        <id property="id" column="id"></id>
        <result property="bookName" column="bookName"></result>
        <result property="price" column="price"></result>
        <result property="publisher" column="publisher"></result>
    </resultMap>
 
    <update id="bookUpdate" parameterType="book">
        UPDATE t_book
        <trim prefix="set" suffixOverrides=",">
            <if test="bookName!=null and bookName!=''">bookName=#{bookName},</if>
            <if test="price!=null and price!=''">price=#{price},</if>
            <if test="publisher!=null and publisher!=''">publisher=#{publisher}</if>
            WHERE id=#{id}
        </trim>
    </update>
 
</mapper>

<set>:

      set元素主要用于更新操作,它的主要功能和where元素差不多,主要是包含的语句前输入一个set,若包含的语句以逗号结束,则会自动把括号忽略掉,再配合if元素就可以动态地更新需要修改的字段;若不需要更改字段,则可以不再被更新。

把上面的代码修改一下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.mapper.BookMapper">
 
    <resultMap id="BookType" type="org.example.po.Book">
        <id property="id" column="id"></id>
        <result property="bookName" column="bookName"></result>
        <result property="price" column="price"></result>
        <result property="publisher" column="publisher"></result>
    </resultMap>
 
    <update id="bookUpdate" parameterType="book">
        UPDATE t_book
<!--        <trim prefix="set" suffixOverrides=",">-->
<!--            <if test="bookName!=null and bookName!=''">bookName=#{bookName},</if>-->
<!--            <if test="price!=null and price!=''">price=#{price},</if>-->
<!--            <if test="publisher!=null and publisher!=''">publisher=#{publisher}</if>-->
<!--            WHERE id=#{id}-->
<!--        </trim>-->
        <set>
            <if test="bookName!=null and bookName!=''">bookName=#{bookName},</if>
            <if test="price!=null and price!=''">price=#{price},</if>
            <if test="publisher!=null and publisher!=''">publisher=#{publisher},</if>
        </set>
        WHERE id=#{id}
    </update>
 
 
</mapper>

<foreach>:

foreach元素通常在构建in条件语句时使用,其使用方式如下。

(1).  item: 表示每个元素迭代时的别名。

(2).  index: 指定一个名称,用于表示在迭代过程中每次迭代的位置

(3).  open: 表示该语句以什么开始(in语句以“( ”开始)

(4).  separator: 表示每次进行迭代时以上面符号作为分隔符(in语句以“ ,”作为分隔符)

(5).  close: 表示该语句以什么结束(in语句以“ )”结束)

(注意:  这个open,separator,close基本上就是固定格式了)

(6).  collection: 表示最关键且最容易出错的属性,需格外注意。该属性必须指定,不同情况下该属性的值是不一样的,主要有三种情况:

        1).  若入参为单参数且参数类型是一个list时,collection属性值为list

        2).  若入参为单参数且参数类型是一个数组时,collection属性值为array

        3).  若入参为多参数,需要将其封装为一个Map进行处理

格式:

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  <where>
    <foreach item="item" index="id" collection="list"
        open="ID in (" separator="," close=")" nullable="true">
          #{item}
    </foreach>
  </where>
</select>

<bind>:

bind元素通常用于需要模糊查询的语句中,使用bind元素定义了一个name为pattern_username的变量,value的属性值就是拼接的查询字符串,其中_parameter.getTitle()表示传递进来的参数(也可以直接写成对应的参数变量名,如username)。

<select id="selectBlogsLike" resultType="Blog">
  <bind name="pattern_username" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
</select>

到此这篇关于MyBatis 超详细讲解动态SQL的实现的文章就介绍到这了,更多相关MyBatis 动态SQL内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯