动态Sql是MyBatis的核心部分,能够对Sql语句进行非常灵活的操作,通过表达式对条件进行判断,对Sql语句进行灵活的操作、组装。
If判断
以下是mapper文件
<?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="mapper.UserMapper">
<!-- UserVo是查询所使用的包装类-->
<select id="findUserList" parameterType="UserQuqryVo" resultType="User">
select * from USER
<where>
<!-- User是包装类中的属性 -->
<if test="User!=null">
<!-- #{User.age}取出年龄
${User.username}取出名称-->
<if test="User.username!=null and User.username!=''">
and user.username like '%${User.username}%'
</if>
</if>
</where>
</select>
<!-- 查找用户总数 -->
<select id="findUserCount" parameterType="UserQueryVo" resultType="int">
SELECT count(*) from USER
<where>
<if test="user!=null">
<if test="user.username!=null and user.username != '' ">
AND user.username LIKE '%${userCustom.username}%'
</if>
</if>
</where>
</select>
</mapper>
这里要重点提一下$ 和 #的区别
以 $是对花括号里的值不加任何修饰的使用,如
select * from user where id = ${user.id}
此时如果 id为1,那么Sql语句就会变为
select * from user where id = 1
但是如果这里使用了#占位符,那么就会变成字符串
select * from user where id = "1"
这在排序中十分重要,比如前端页面传进来一个排序的参数,那么这里使用 #的话,将会无法成功排序
order by "desc" 而部署 order by desc
话说回来,#可以防止SQL注入,所以能使用#的地方,就不要使用$
Sql片段
将上面文件中的SQL片段抽取出来,形成一个SQL片段,以下是mapper文件
<?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="mapper.UserMapper">
<sql id="query_user">
<if test="User!=null">
<!-- #{User.age}取出年龄
${User.username}取出名称-->
<if test="User.username!=null and User.username!=''">
and user.username like '%${User.username}%'
</if>
</if>
</sql>
<!-- UserVo是查询所使用的包装类-->
<select id="findUserList" parameterType="UserQuqryVo" resultType="User">
select * from USER
<where>
<!--如果指定的片段不在本文件中,需要加前缀namespace-->
<include refid="query_user"/>
<!-- 这里还可以放置sql片段 -->
</where>
</select>
<!-- 查找用户总数 -->
<select id="findUserCount" parameterType="UserQueryVo" resultType="int">
SELECT count(*) from USER
<where>
<if test="user!=null">
<if test="user.username!=null and user.username != '' ">
AND user.username LIKE '%${userCustom.username}%'
</if>
</if>
</where>
</select>
</mapper>
Foreach标签
向SQL语句中传入数组,List或者Map时,需要使用标签
select * from user where id = ? or id = ?
select * from user where id in (?,?)
<if test="ids!=null">
<!-- 使用 foreach遍历传入ids
collection:指定输入 对象中集合属性
item:每个遍历生成对象中
open:开始遍历时拼接的串
close:结束遍历时拼接的串
separator:遍历的两个对象中需要拼接的串
-->
<!-- 使用实现下边的sql拼接:
AND (id=1 OR id=10 OR id=16)
-->
<foreach collection="ids" item="user_id" open="AND (" close=")" separator="or">
<!-- 每个遍历需要拼接的串 -->
id=#{user_id}
</foreach>
<!-- 实现 “ and id IN(1,10,16)”拼接 -->
<!-- <foreach collection="ids" item="user_id" open="and id IN(" close=")" separator=",">
每个遍历需要拼接的串
#{user_id}
</foreach> -->
</if>