Mybatis学习笔记-动态SQL

Posted NathenJames

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis学习笔记-动态SQL相关的知识,希望对你有一定的参考价值。

Mybatis学习笔记(三)-动态SQL

动态SQL语句,就是在SQL中执行动态构建的SQL语句,根据不同情况执行不同的SQL语句

表属性

ID NAME EMAIL AGE

第一的接口方法

public interface StudentDAO {
    //测试动态sql
    List<StudentModle>STUDENT_MODLE_LIST(StudentModle studentModle);
    List<StudentModle>STUDENT_MODLE_LIST_choise(StudentModle studentModle);
    void UpdateStudentinfo_SET(StudentModle studentModle);
    void UpdateStudentinfo_SET_trim(StudentModle studentModle);
    }

一.SQL语句块

sql语句块可以减少重复出现的SQL语句,用在各种SQL标签内

比如我懒得重复写name,age这个两个单词我就可以这样

id就代表了这个SQL语句,就只是语句块里的单词

<!--作为SQL片段-->
    <sql id="SelectStudentinfoSQL">
        name,age
     </sql>

如何使用看下面

<include refid="SelectStudentinfoSQL"></include>

二.IF和WHERE

  • IF:用于判断标签内的条件
  • WHERE:用于处理多个IF条件内是否还有成立的条件使其添加WHERE和去除多余关键词,还可以根据子句中有没有返回的句子自动添加where

说着抽象,具体如下

这段用于处理传回来的数据中name和age是否为空的,如果test条件成立则执行语句块里的 name=#{name}或者OR age=#{age}

<!--IF WHERE-->
    <select id="STUDENT_MODLE_LIST" resultType="MyFirstMybatisApplication.Bean.StudentModle">
        select <include refid="SelectStudentinfoSQL"/> from student
 				WHERE
       
            <if test="name!=null">
                name=#{name}
            </if>
            <if test="age!=null">
                OR  age=#{age}
            </if>
        
    </select>

1.如果name!=null和age!=null成立那么,执行的SQL应该为

select  name,age from student WHERE name=\'xxx\' OR age=\'xxx\'

2.如果name!=null不成立呢?但是age!=null成立,执行的SQL应该为

select  name,age from student WHERE OR age=\'xxx\'

那么显然是不成立的,这个语句是错误的,那么如何处理掉OR这个关键词呢?

那就使用标签,把where关键词替换掉(坑)

就是这样

<!--IF WHERE-->
    <select id="STUDENT_MODLE_LIST" resultType="MyFirstMybatisApplication.Bean.StudentModle">
        select <include refid="SelectStudentinfoSQL"/> from student
        <where>
            <if test="name!=null">
                name=#{name}
            </if>
            <if test="age!=null">
                OR  age=#{age}
            </if>
        </where>
    </select>

那么Mybaits就会处理好多余的关键词,无论关键词在前面还是后面

3.如果两个条件都不成立呢?

Mybaits处理了where的有无,如果不加那么就为

select name,age from student where

显然是错误的

那加了执行的SQL为,

select  name,age from student

三,CHOOSE,when,otherwise

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

  • WHEN

    在when中写test条件,可以整多个when标签

  • OTHERWISE

    填写如果任意一个条件不成立而执行的语句

注意:可以加上 也可以不加,就那么回事儿

<select id="STUDENT_MODLE_LIST_choise" resultType="MyFirstMybatisApplication.Bean.StudentModle">
    select <include refid="SelectStudentinfoSQL"/> from student
        <where>
        <choose>
            <when test="name!=null">
                name=#{name}
            </when>
            <otherwise>
                age=#{age}
            </otherwise>
        </choose>
    </where>
</select>

四,SET

专门处理Update操作的

set 元素可以用于动态包含需要更新的列

<update id="UpdateStudentinfo_SET" parameterType="MyFirstMybatisApplication.Bean.StudentModle">
    update student
    <set>
        <if test="name!=null"> name=#{name}</if>
        <if test="age!=null">,age=#{age}</if>
    </set>
    where id=#{id}
</update>

用来处理每个字段后面的逗号,如果name不成立那么语句就会变为

 update student set ,age=#{age}  where id=#{id}

肯定是不行的,set会自动处理掉

五,TRIM

TRIM提供比上面更为强大得功能它可以自定义处理得 字符,它有四个属性

	给sql语句拼接的前缀
prefix CDATA #IMPLIED
	去除sql语句前面的关键字或者字符,该关键字或者字符由prefixOverrides属性指定
prefixOverrides CDATA #IMPLIED
	给sql语句拼接的后缀
suffix CDATA #IMPLIED
	去除sql语句后面的关键字或者字符,该关键字或者字符由suffixOverrides属性指定
suffixOverrides CDATA #IMPLIED

例如:我执行了更新,但是我没有使用set或者标签,我在trim的prefix加上了set,Mybaits会自动的为我们在字句前面加上setu也就是trim的位置

<update id="UpdateStudentinfo_SET_trim" parameterType="MyFirstMybatisApplication.Bean.StudentModle">
    update student
    <trim prefix="set" suffixOverrides=",">
        <if test="name!=null"> name=#{name},</if>
        <if test="age!=null">age=#{age},</if>
    </trim>
    where id=#{id}
</update>

那么我如果age!=null成立了,语句变为

update student set age=#{age},

这肯定不对,那我在trim指定uffixOverrides=","去除了最后的逗号,那sql就正确了

六,foreach

动态 SQL 的另一个常见使用场景是对集合进行遍历

它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符

来自官方文档的例子

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  WHERE ID in
  <foreach item="item" index="index" collection="list"
      open="(" separator="," close=")">
        #{item}
  </foreach>
</select>
  • collection:指定传入的数据类型
  • item 的值是本次迭代获取到的元素
  • index 是当前迭代的序号

注意:当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。

以上是关于Mybatis学习笔记-动态SQL的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis-05-笔记

mybatis学习(39):动态sql片段

Mybatis学习笔记-动态SQL

学习笔记——Mybatis动态SQL

MyBatis学习笔记 —— 动态SQL

mybatis动态SQL操作之插入学习笔记