一、什么是动态SQL
MyBatis的动态SQL是基于OGNL的表达式的。它对SQL语句进行灵活的操作,通过表达式判断来实现对SQL的灵活拼接、组装。
二、动态SQL介绍
下面是用于实现动态SQL的主要元素:
- if
- choose(when,otherwise)
- trim
- where
- set
- foreach
在动态SQL中所作的最通用的事情就是包含部分where子句的条件
<sql id="where">
1=1 <!-- 可能出现多个条件 但是不一定都会执行,无法确定是否是第一个查询字段-->
<where>
<if test="userId !=null and userId !=''">
AND A.userId = #{userId,jdbcType=CHAR}
</if>
<if test="userName !=null and userName !=''">
AND A.userName = #{userName,jdbcType=CHAR}
</if>
</where>
</sql>
test里面可以判断字符串、整形、浮点型。如果属性是复合类型,则可以使用A.a的方式去获取符合类型中的属性俩进行比较。
注:1=1
如果没有1=1并且所有的查询条件都不满足那么生成的SQL语句为:
select userName,userAge,userPhone from user_table where
执行这条SQL明显会报错
如果没有1=1且第一个条件不满足生成的SQL语句为:
select userName,userAge,userPhone from user_table where and userName=#{userName,jdbcType=VARCHAR}
执行这条SQL也明显会报错
所以会用到1=1。因为它永远满足,相当于给where加了一层true。所以不管如何生成SQL都是正确的
<sql id="where">
1=1 <!-- 可能出现多个条件 但是不一定都会执行,无法确定是否是第一个查询字段-->
<where>
<choose>
<when test="userId!=null and userId!=""">
userId=#{userId,jdbcType=CHAR}
</when>
<otherwise>
1 = 1;
</otherwise>
</choose>
</where>
</sql>
3.trim元素
trim和where同级,其主要功能是可以在自己包含的内容前或后加上某些前后缀,与之对应的属性是prefix和suffix;也可以把内容的首部或尾部的某些内容覆盖,对应的属性是prefixOverrides和suffixOverrides;
<sql id="where">
<trim prefix="WHERE" prefixoverride="AND |OR">
<if test="userId !=null and userId !=''">
AND A.userId = #{userId,jdbcType=CHAR}
</if>
<if test="userName !=null and userName !=''">
AND A.userName = #{userName,jdbcType=CHAR}
</if>
</trim>
</sql>
假如userId和userNamedou 都不为空的话 ,上面的动态SQL生成的SQL语句为:
select userId,userName,userAge,userPhone from user_table where userId=#{userId,jdbcType=CHAR}
AND userName=#{userName,jdbcType=VARCHAR}
where后不存在and,因为prefixoverride="AND ||OR"代表去掉第一个AND或者OR,
注意:AND后的空格。
可以替换上面1=1的操作
trim元素也可以应用到update,insert标签中,大家可以根据对上面代码的理解试着写一下。
4.set元素
set元素可以被用于动态包含更新的列,不包含不需要更新的,并且会动态的前置set关键字,也可以相除任意无关的逗号。
<update id="updateUser" parameterType="com.mybatis.VO.UserVO">
update user_table
<set>
<if test="userId !=null and userId !=''">
AND A.userId = #{userId,jdbcType=CHAR}
</if>
<if test="userName !=null and userName !=''">
AND A.userName = #{userName,jdbcType=CHAR}
</if>
</set>
where userId=#{id}
</update>
5.foreach元素
foreach的主要用在构建in条件中,他可以迭代一个集合。foreach元素的属性主要有:item,index,collection,open,separator,close。
下面对属性进行简单的介绍:
item:表示集合中每一个元素进行迭代时的别名。
index:指定一个名字,用于表示在迭代过程中每次迭代的位置。
open:表示以什么开始。
separator:每次迭代以什么分割。
close:以什么关闭。
collection:最重要且必须指定的有三种情况:
1.如果传入的是单独参数的List类型时,collection的属性值为list。
2.如果传入的是单独参数的数组时,collection的属性值为array.
3.如果传入多个参数时,我们把多个参数放入map中,单参数也可以放入map中。map中的key就是参数名,所以collection属性值就是传入的List或者array对象在Map里的key。
下面列举每种情况的案例:
1.单参数List类型:
<select id="batchSelect" resultType="UserVO" parameterType="java.util.Map>
select userId,userName,userAge,userPhone from user_table where userId in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
2.单参数数组array类型
<select id="batchSelect" resultType="UserVO" parameterType="java.util.Map>
select userId,userName,userAge,userPhone from user_table where userId in
<foreach collection="array" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
3.多参数Map类型
<select id="batchSelect" resultType="UserVO" parameterType="java.util.Map">
select userId,userName,userAge,userPhone from user_table where userId in
<foreach collection="ids" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
对应的分装成map的部分java代码:
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(2);
ids.add(3);
ids.add(6);
ids.add(7);
ids.add(9);
Map<String, Object> params = new HashMap<String, Object>();
params.put("ids", ids);
耐心之树,结黄金之果。