MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。
MyBatis中用于实现动态SQL的元素主要有:if,choose(when,otherwise),where,trim,set,foreach
if:if就是简单的条件判断,利用if语句我们可以实现某些简单的条件选择,条件成立的加上对应的sql语句,不成立则不加
<select id="selectStudentIf" resultType="student">
select * from student where 1=1
<if test="id != 0">
and id = #{id}
</if>
<if test="name != null">
and name = #{name}
</if>
<if test="phone != null">
and phone = #{phone}
</if>
</select>
choose:choose元素的作用就相当于JAVA中的switch语句,基本上跟JSTL中的choose的作用和用法是一样的,通常都是与when和otherwise搭配的,只在其中选择一个条件
<select id="selectStudentChoose" resultType="student">
select * from student where
<choose>
<when test="id != 0">
id = #{id}
</when>
<when test="name != null">
name = #{name}
</when>
<when test="phone != null">
phone = #{phone}
</when>
<otherwise>
2 = 1
</otherwise>
</choose>
</select>
where:where元素的作用是会在写入where元素的地方输出一个where,如果输出后是and开头的,MyBatis会把第一个and忽略,当然如果是or开头的,MyBatis也会把它忽略;此外,在where元素中你不需要考虑空格的问题,MyBatis会智能的帮你加上
<select id="selectStudentWhere" resultType="student">
select * from student
<where>
<if test="id != 0">
id = #{id}
</if>
<if test="name != null">
and name = #{name}
</if>
<if test="phone != null">
and phone = #{phone}
</if>
</where>
</select>
trim:trim元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefix和suffix;可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是prefixOverrides和suffixOverrides;正因为trim有这样的功能,所以我们也可以非常简单的利用trim来代替where元素的功能
<select id="selectStudentTrim" resultType="student">
select * from student
<trim prefix="where" prefixOverrides="or|and">
<if test="id != 0">
id = #{id}
</if>
<if test="name != null">
and name = #{name}
</if>
<if test="phone != null">
or phone = #{phone}
</if>
</trim>
</select>
set:set元素主要是用在更新操作的时候,主要是在包含的语句前输出一个set,然后如果包含的语句是以逗号结束的话将会把该逗号忽略,如果set包含的内容为空的话则会出错。
<update id="updateStudent" parameterType="student">
update student
<set>
<if test="name != null">
name = #{name},
</if>
<if test="phone != null">
phone = #{phone}
</if>
</set>
where id= #{id}
</update>
<update id="updateStudent" parameterType="student">
update student
<trim prefix="set" suffixOverrides=",">
<if test="name != null">
name = #{name},
</if>
<if test="phone != null">
phone = #{phone}
</if>
</trim>
where id= #{id}
</update>
foreach: foreach可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有item,index,collection,open,separator,close。
item表示集合中每一个元素进行迭代时的别名,
index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,
open表示该语句以什么开始,
separator表示在每次进行迭代之间以什么符号作为分隔符,
close表示以什么结束,
collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下3种情况:
如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key
第一种情况:此时参数为一个list
接口中的方法:
public int insertStudents(List<Student> students);
<insert id="insertStudents" parameterType="list">
insert into student values
<foreach collection="list" item="s" separator=",">
(default,#{s.name},#{s.phone})
</foreach>
</insert>
public List<Student> selectStudentForeach(List<Integer> ids);
<select id="selectStudentForeachList" resultType="student">
select * from student where id in
<foreach collection="list" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
第二种情况:
public List<Student> selectStudentForeachArray(Integer[] ids);
<select id="selectStudentForeachArray" resultType="student">
select * from student where id in
<foreach collection="array" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
第三种情况:
public List<Student> selectStudentForeachMap(Map<String,Object> map);
<select id="selectStudentForeachMap" resultType="student">
select * from student where name like "%"#{name}"%" and id in
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
sql:预先定义一个sql语句,使用时直接引用,可以使用一部分,也可以全部使用,一个定义好的sql语句可以在多处使用
定义sql语句:
<sql id="select_all">
select * from student
</sql>
<sql id="where_equal">
<where>
<if test="id != 0">
id = #{id}
</if>
<if test="name != null">
or name = #{name}
</if>
<if test="phone != null">
or phone = #{phone}
</if>
</where>
</sql>
使用sql语句:
<select id="selectPage" resultType="student">
<include refid="select_all"/>
limit #{start},#{size}
</select>
<select id="selectStudentWhere" resultType="student">
<include refid="select_all"/>
<include refid="where_equal"/>
</select>
<delete id="deleteStudentWhere" resultType="student">
delete from student
<include refid="where_equal"/>
</delete>