Mybatis学习笔记(三)-动态SQL
动态SQL语句,就是在SQL中执行动态构建的SQL语句,根据不同情况执行不同的SQL语句
表属性
ID | NAME | 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这个关键词呢?
那就使用
就是这样
<!--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
显然是错误的
那加了
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或者
<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 是值。