MyBatis动态SQL
MyBatis动态SQL
动态SQL简介
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。
如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
常用的动态SQL标签
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
为什么要用动态SQL
动态SQL可以根据传入的查询条件,灵活的拼接SQL语句
动态SQL用法
if标签
if标签语法
<select...>
SQL语句1
<if test="条件表达式">
SQL语句2
</if>
</select>
条件表达式大于、小于、大于等于、小于等于判断
if条件判断各种使用方式
- 如果参数为数字类型的时候没有特俗需求的情况只需要判断是否为null即可
例如:
<if test="id != null"> </if>
如果有特俗需求,例如判断是否大于某个数的时候才行。只需要加上对应的条件判断即可
例如:
<if test='id != null and id > 28'></if>
mybatis对于这种大于小于等等还有另一种形式
例如:
<if test='id != null and id gt 28'></if>
对应关系:
- 如果参数字符串类型
- 如果不需要过滤空串的情况 仅仅判断null即可
<if test="username != null"></if>
- 如果需要过滤空串,添加空串判断即可 不支持 && 所以这里用 and or || 来做逻辑与或的判断
<if test="username != null and '' != username"></if>
或者
<if test="username != null and '' neq username"></if>
- 如果判断字符串是否已某个特俗字符开头,结尾等。直接调用String的对应方法即可
<!-- 是否以什么开头 -->
<if test="username != null and username.indexOf('ji') == 0"> </if>
<!-- 是否包含某字符 -->
<if test="username != null and username.indexOf('ji') >= 0"> </if>
<!-- 是否以什么结尾 -->
<if test="username != null and username.lastIndexOf('ji') > 0"></if>
- 是否是某个特定字符串,某些业务有此需要。
<if test="username != null and 'hello' == username"></if>
或者
<if test="username != null and 'hello' eq username"></if>
注意:
<if test="username != null and 'hello' == username"></if>
这种形式的写法在参数类型是字符串的时候是没有问题的,但是参数类型为非字符串类型的时候就需要写成
<if test="username != null and 'hello'.toString() == username.toString()"></if>
mybatis对于字符串的相等不相等的判断也是有对应的特俗操作符
if的条件判断test是支持对象自身方法调用的,即使是自己写的方法
例如:里面可以用‘xxxx’.equals(xxxx) 字符串的比较两个字符串方法
xxxx.indexOf('ss') 判断字符串里面是否包含某个字符等等
- 判断list是否为空
if条件判断可以直接调用对象自身的方法进行逻辑判断,所以list判空。可以调用.size()>0或者.isEmpty()
例如:
<if test="userList != null and userList.isEmpty()"></if>
或者
<if test="userList != null and userList.size()>0"></if>
- map参数同同理 取值的话 map.key(map中的key名字)即可
if标签判断数字相等"=="
判断的字段是Integer类型
query类:
public class Query{
/**
* 条件
*/
private Integer a;
}
下面两种都可以:
<select id="countTable" resultType="java.lang.Long">
select count(*) from table_name
<where>
<if test="a == 3">
and A = #{a}
</if>
</where>
</select>
<select id="countTable" resultType="java.lang.Long">
select count(*) from table_name
<where>
<if test="a == '3'.toString()">
and A = #{a}
</if>
</where>
</select>
判断的字段是String类型
- 如果这个字段的值是数字,那么和Integer类型是一样的,3 或者 ‘3’.toString() 都可以,但是 ‘3’ 不行
- 如果这个字段的值不是数字,比如: “y” ,那么就要这样写:‘y’.toString()
query类:
public class Query{
/**
* 条件
*/
private String a;
}
sql:
<select id="countTable" resultType="java.lang.Long">
select count(*) from table_name
<where>
<if test="a == '3'.toString()">
and A = #{a}
</if>
<if test="a != null and a != '3'.toString()">
and B = #{a}
</if>
</where>
</select>
trim标签
trim标签语法
<trim prefix="" suffix="" suffixOverrides="" prefixOverrides=""></trim>
prefix:在trim标签内sql语句加上前缀。
suffix: 在trim标签内sql语句加上后缀。
suffixOverrides:指定去除多余的后缀内容,如:suffixOverrides=",",去除trim标签内sql语句多余的后缀","。
prefixOverrides: 指定去除多余的前缀内容
往购物车表中插入数据的mybatis语句
<insert id="insert" parameterType="com.tortuousroad.groupon.cart.entity.Cart">
insert into cart
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="userId != null">
user_id,
</if>
<if test="dealId != null">
deal_id,
</if>
<if test="dealSkuId != null">
deal_sku_id,
</if>
<if test="count != null">
count,
</if>
<if test="createTime != null">
create_time,
</if>
<if test="updateTime != null">
update_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=BIGINT},
</if>
<if test="userId != null">
#{userId,jdbcType=BIGINT},
</if>
<if test="dealId != null">
#{dealId,jdbcType=BIGINT},
</if>
<if test="dealSkuId != null">
#{dealSkuId,jdbcType=BIGINT},
</if>
<if test="count != null">
#{count,jdbcType=INTEGER},
</if>
<if test="createTime != null">
#{createTime,jdbcType=TIMESTAMP},
</if>
<if test="updateTime != null">
#{updateTime,jdbcType=TIMESTAMP},
</if>
</trim>
</insert>
没有指定suffixOverrides=","
拼接的sql语句为:
insert into cart (id,user_id,deal_id,) values(1,2,1,);
括号中多了个","符号,语法错误。
指定suffixOverrides=","
拼接的sql语句为:
insert into cart (id,user_id,deal_id,) values(1,2,1);
多余的","被去掉了,语法正确。