<where>、<trim>元素
在前两个小节的案例中,映射文件中编写的SQL后面都加入了“where 1=1”的条件,那么到底为什么要这么写呢?如果将where后“1=1”的条件去掉,那么MyBatis所拼接出来的SQL将会如下所示:
select * from t_customer **where and** username like concat('%',?, '%')
上面SQL中,where后直接跟的是and,这在运行时肯定会报SQL语法错误,而加入了条件“1=1”后,既保证了where后面的条件成立,又避免了where后面第一个词是and或者or之类的关键词。那么在MyBatis中,有没有什么办法不用加入“1=1”这样的条件,也能使拼接后的SQL成立呢?
针对这种情况,MyBatis提供了<where>元素来处理这样的问题。
以前面小节的案例为例,将映射文件中的“where 1=1”条件删除,并使用<where>元素替换后的代码如下所示。
<!-- <where>元素-->
<select id="findCustomerByNameAndJobs"
parameterType="com.itheima.po.Customer"
resultType="com.itheima.po.Customer">
select * from t_customer
<where>
<if test="username !=null and username !=''">
and username like concat('%',#{username}, '%')
</if>
<if test="jobs !=null and jobs !=''">
and jobs= #{jobs}
</if>
</where>
</select>
上述配置代码中,使用<where>元素对“where 1=1”条件进行了替换,<where>元素会自动判断组合条件下拼装的SQL语句,只有<where>元素内的条件成立时,才会在拼接SQL中加入where关键字,否则将不会添加;即使where之后的内容有多余的“AND”或“OR”,<where>元素也会自动将他们去除。
除了使用<where>元素外,还可以通过<trim>元素来定制需要的功能,上述代码还可以修改为如下形式:
<!-- <trim>元素-->
<select id="findCustomerByNameAndJobs"
parameterType="com.itheima.po.Customer"
resultType="com.itheima.po.Customer">
select * from t_customer
<trim prefix="where" prefixOverrides="and">
<if test="username !=null and username !=''">
and username like concat('%',#{username}, '%')
</if>
<if test="jobs !=null and jobs !=''">
and jobs= #{jobs}
</if>
</trim>
</select>
上述配置代码中,同样使用<trim>元素对“where 1=1”条件进行了替换,<trim>元素的作用是去除一些特殊的字符串,它的prefix属性代表的是语句的前缀(这里使用where来连接后面的SQL片段),而prefixOverrides属性代表的是需要去除的哪些特殊字符串(这里定义了要去除SQL中的and),上面的写法和使用<where>元素基本是等效的。