1、什么是动态SQL? 动态SQL有什么作用?
传统的使用JDBC的方法,相信大家在组合复杂的的SQL语句的时候,需要去拼接,稍不注意哪怕少了个空格,都会导致错误。Mybatis的动态SQL功能正是为了解决这种问题, 其通过 if, choose, when, otherwise, trim, where, set, foreach标签,可组合成非常灵活的SQL语句,从而提高开发人员的效率。
2、动态sql常用标签
if
动态 SQL 通常要做的事情是有条件地包含 where 子句的一部分。比如:
<select id="findUserLike" resultType="User">
SELECT * FROM user WHERE
<if test="username != null">and username = #{username}</if>
<if test="password != null">and password = #{password}</if>
</select>
where
在if代码中如果查询判断条件比较多,且username为空sql语句就可能出现:select * from user where and password = ? 这种情况sql就会报错,无法执行,而where标签刚好可以解决这一问题会把对应的and关键字去掉(还有or关键字)。
<select id="findUserLike" resultType="User">
SELECT * FROM user
<where>
<if test="username != null">and username = #{username}</if>
<if test="password != null">and password = #{password}</if>
</where>
</select>
trim
和where等价的元素,支持自定义条件。prefixOverrides 属性会忽略通过管道分隔的文本序列(注意此例中的空格也是必要的)。它带来的结果就是所有在 prefixOverrides 属性中指定的内容将被移除,并且插入 prefix 属性中指定的内容
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
<trim prefix="SET" suffixOverrides=",">
...
</trim>
set
set 元素可以被用于动态包含需要更新的列,而舍去其他的。
<update id="updateUser">
update user
<set>
<if test="username != null">username=#{username},</if>
<if test="password != null">password=#{password},</if>
</set>`
where id=#{id}
</update>
choose、when、otherwise
<choose>
<when test="判断条件1">
SQL语句1
</when >
<when test="判断条件2">
SQL语句2
</when >
<when test="判断条件3">
SQL语句3
</when >
<otherwise>
SQL语句4
</otherwise>
</choose>
choose 标签按顺序判断其内部 when 标签中的判断条件是否成立,如果有一个成立,则执行相应的 SQL 语句,choose 执行结束;如果都不成立,则执行 otherwise 中的 SQL 语句。
foreach
动态 SQL 的另外一个常用的必要操作是需要对一个集合进行遍历,通常是在构建 IN 条件语句的时候。比如:
<select id="selectUser" resultType="domain.User">
SELECT *
FROM user P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
foreach元素的属性主要有item,index,collection,open,separator,close。
(1.)item:表示集合中每个元素进行迭代时的别名。
(2.)index:制定一个名称,用于表示在迭代过程中,每次迭代到的位置。
(3.)open:表示该语句以什么开始,既然是in条件语句,所以必然以“(”开始。
(4.)separator:表示在每次进行迭代之间以什么符号作为分隔符,既然是in条件语句,所以必须以“,”,作为分隔符。
(5.)close:表示该语句以什么语句结束,既然是in条件语句,所以必然是以“)”结束。
(6.)collection:最关键并最容易出错的属性,需格外注意,该属性必须指定,不同情况下,该属性的值是不一样的。主要有三种情况:
- 若入参为单参数且参数类型是一个List的时候,collection属性值为list。
- 若入参为单参数且参数类型是一个数组的时候,collection属性值为array(此处传入参数Integer[] rolelds为数组类型,故此处collection属性值设为“array”)。
- 若传入参数为多参数,就需要把他们封装为一个Map进行处理。select中返回的是一个resultMap(id=“userMapByRole”),该resultMap也进行相应的字段映射。最后修改测试类,增加测试方法。
(1.)MyBatis接收的参数类型:基本类型、对象、List、数组、Map。
(2.)无论MyBatis的入参是哪种参数类型,MyBatis都会将参数放在一个Map中,对于单参入参的情况:
(一、)若入参为基本类型:变量名作为key,变量值为value,此时生成的map只有一个元素。
(二、)若入参为对象:对象的属性名作为key,属性值为value。
(三、)若入参为List:默认“list”作为key,该List即为value。
(四、)若入参为数组:默认“array”作为key,该数组即为value。
(五、)若入参为Map:键值不变
常见属性的含义
- prefix:在trim标签内sql语句加上前缀。
- suffix:在trim标签内sql语句加上后缀。
- prefixOverrides:指定去除多余的前缀内容。
- suffixOverrides:指定去除多余的后缀内容。