SQL语句 where 1=1 和 where 0=1

  • where 1=1
  • where标签
  • where 0=1
  • 总结


where 1=1

先看下mybatis中的sql代码

<select id="" parameterType = "">
	SELECT * FROM users 
	WHERE
		<if test="userName != null ">
			user_name = #{userName}
		</if>
		<if test="userAge != null ">
			AND user_age = #{userAge }
		</if>
		<if test="userSex!= null ">
			AND	user_sex = #{userSex}
		</if>
</select>

我们根据条件查询的时候,一般都会这么写,但是如果这三个查询条件都不成立(或者第一个条件不成立),那么这个sql语句会变成 “SELECT * FROM users WHERE”,这肯定是会报错的,所以针对这种情况,就在 where 后面 加上 1=1 。

这时如果后面的那些条件不成立,那么就会进行全表查询。因为 where 1=1 是为ture的语句,能够被正确执行。它的作用就相当于 "SELECT * FROM users"

<select id="" parameterType = "">
	SELECT * FROM users 
	WHERE 1=1
		<if test="userName != null ">
			AND user_name = #{userName}
		</if>
		<if test="userAge != null ">
			AND user_age = #{userAge }
		</if>
		<if test="userSex!= null ">
			AND	user_sex = #{userSex}
		</if>
</select>

where标签

其实除了上面说的 where 1=1 方式,MyBatis提供了一个简单的处理,这在90%的情况下都会有用。而在不能使用的地方,你可以自定义处理方式来令其正常工作。一处简单的修改就能得到想要的效果:

<select id="" parameterType = "">
	SELECT * FROM users 
	<where>
		<if test="userName != null ">
			AND user_name = #{userName}
		</if>
		<if test="userAge != null ">
			AND user_age = #{userAge }
		</if>
		<if test="userSex!= null ">
			AND	user_sex = #{userSex}
		</if>
	</where>
</select>

where 元素知道只有在一个以上的if条件有值的情况下才去插入“WHERE”子句。而且,若最后的内容是“AND”或“OR”开头的,where 元素也知道如何将他们去除。

如果 where 元素没有按正常套路出牌,我们还是可以通过自定义 trim 元素来定制我们想要的功能。比如,和 where 元素等价的自定义 trim 元素为:

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ...
</trim>

prefixOverrides 属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的)。上述例子会移除所有 prefixOverrides 属性中指定的内容,并且插入 prefix 属性中指定的内容。

where 0=1

由于 where 0=1 这个条件始终是false,所以在查询的时候是不会返回任何数据的。
他虽然不会返回任何数据,但是会返回这个表结构。

SELECT * FROM users WHERE 1=0

这个sql语句不需要考虑表中数据,只取得了表结构,这样因为不需要保存结果集,节省了内存。

我们可以用该语句创建一个新的表(新表结构与查询的表结构一致)

create table new_users as select * from users where 1=0;

总结

其实,where 1=1的应用,不是什么高级的应用,也不是所谓的智能化的构造,仅仅只是为了满足多条件查询页面中不确定的各种因素而采用的一种构造一条正确能运行的动态SQL语句的一种方法。