映射文件中编写的 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 元素
<select id="findCustomerByNameAndJobs" parameterType="com.po.Customer" resultType="com.po.Customer"> select * from t_customer <where> <if test="username!=null and username!=''"> and username like concat('%',#sername, '%') </if> <if test="jobs!=null and jobs!=''"> and jobs= #{jobs} </if> </where> </select>
trim元素
除了使用< where>元素外,还可以通过< trim>元素来定制需要的功能,上述代码还可以修改为如下形式:
<select id="findCustomerByNameAndJobs" parameterType="com.po.Customer" resultType="com.po.Customer"> select * from t_customer <trim prefix="where" prefixOverrides="and"> <if test="username!=null and username!=''"> and username like concat('%',#sername, '%') </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>元素基本是等效的。