MyBatis的动态sql
所谓动态sql就是根据用户输入不同动态拼接需要执行的sql语句。
if标签
if标签主要是用来判断用户是否输入了某个符合要求的条件,如果输入了再将该条件拼接到sql语句中,如下示例表示用户可以输入两个查询条件,name和age:
<select id="selectByIf" resultType="student">
SELECT id,name,age,score
FROM t_student
WHERE 1=1
<if test="name != null and name != ''">
AND name LIKE '%' #{name} '%'
</if>
<if test="age>=0">
AND age = #{age}
</if>
</select>
1=1是为了防止在某些情况下sql语句拼接不正确
where标签
可以使用where标签来避免编写上面示例中的“1=1”
注意:在第一个if标签中的sql可以不加and,但是其后面的if标签中必须要加and
<select id="selectByWhere" resultType="student">
SELECT id,name,age,score
FROM t_student
<where>
<if test="name != null and name != ''">
AND name LIKE '%' #{name} '%'
</if>
<if test="age>=0">
AND age = #{age}
</if>
</where>
</select>
trim标签
可以使用trim标签来定制where元素的功能,例如下面内容跟上面的where是等价的,只不过是我们自己设定了元素
- prefix="WHERE"表示在trim前面加上where
- prefixOverrides="AND | OR "表示去除rim开始部分的AND或OR
<trim prefix="WHERE" prefixOverrides="AND | OR ">
<if test="name != null and name != ''">
name LIKE '%' #{name} '%'
</if>
<if test="age>=0">
AND age = #{age}
</if>
</trim>
其中mybatis会根据实际元素是否满足条件来判断添加或删除AND,OR
choose标签
通过choose标签实现下面功能:
若姓名不为空,则按照姓名查询;若姓名为空,则按照年龄查询;若没有查询条件,则没有查询结果。
<select id="selectByChoose" resultType="student">
SELECT id,name,age,score
FROM t_student
<where>
<choose>
<when test="name != null and name != ''">
name LIKE '%' #{name} '%'
</when>
<when test="age>=0">
age = #{age}
</when>
<otherwise>
1 != 1
</otherwise>
</choose>
</where>
</select>
set标签
在做update操作的时候倘若某个实体bean的属性是null时,数据库中对应的字段也会变成null,这样就会出现问题,此时我们可以通过set标签解决
<update id="updateStudent">
UPDATE t_student
<set>
<if test="name != null">name=#{name},</if>
<if test="age >= 0">age=#{age},</if>
<if test="score > 30">score=#{score},</if>
</set>
WHERE id=#{id}
</update>
mybatis会忽略不满足条件的数据且会删除额外的逗号。与该语句等价的trim如下:
- prefix="SET"表示在trim前面加上set
- suffixOverrides=","表示去除trim结尾的逗号
<update id="updateStudent">
UPDATE t_student
<trim prefix="SET" suffixOverrides=",">
<if test="name != null">name=#{name},</if>
<if test="age >= 0">age=#{age},</if>
<if test="score > 30">score=#{score},</if>
</trim>
WHERE id=#{id}
</update>
foreach标签遍历数组
有时候会有这样的操作,用户需要查询Student的id是5,6,10,15的数据,这些数据可能会被放到数组里面作为参数进行传递,以前我们可以在sql语句中使用in来实现,在mybatis中就可以使用foreach标签。
foreach标签的属性:
- collection 表示要遍历的集合类型,这里是数组,即 array。
- open、close、separator 为对遍历内容的 SQL 拼接。
<select id="selectForeachArray" resultType="student">
SELECT id,name,age,score
FROM t_student
<if test="array != null and array.length>0">
WHERE id IN
<foreach collection="array" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</if>
</select>
if标签中的test属性里面,array是固定写法,表示数组
foreach标签遍历基本数据类型的集合
与遍历数组的区别在于这里在if的test属性中使用的是list和list.size,foreach中的collection也是list。
<select id="selectForeachList" resultType="student">
SELECT id,name,age,score
FROM t_student
<if test="list != null and list.size>0">
WHERE id IN
<foreach collection="list" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</if>
</select>
foreach标签遍历自定义数据类型的集合
<select id="selectForeachListStudent" resultType="student">
SELECT id,name,age,score
FROM t_student
<if test="list != null and list.size>0">
WHERE id IN
<foreach collection="list" open="(" close=")" item="stu" separator=",">
#{stu.id}
</foreach>
</if>
</select>
sql标签
sql标签可以用来定义一个可被复用的sql片段,在使用的时候写上include标签就可以将sql标签中的内容引入。当某段sql语句会被多次使用时,可以将这段sql语句放到sql标签中。
<!--定义sql片段-->
<sql id="select">
SELECT id,name,age,score
FROM t_student
</sql>
<select id="selectSQL" resultType="student">
<!--使用sql片段-->
<include refid="select"/>
<if test="list != null and list.size>0">
WHERE id IN
<foreach collection="list" open="(" close=")" item="stu" separator=",">
#{stu.id}
</foreach>
</if>
</select>
注意:如何MyBatis对一些特殊字符(如<、&等)解析出现错误,则可以使用其对应的实体符号,或者使用<![CDATA[xxx]]>(如"<“用”<![CDATA[ < ]]>"代替)
原符号 实体符号
< <
<= <=
> >
>= >=
& &
" "
' '