为什么使用 where 1=1?
在MyBatis框架中,动态SQL是很棒的一点,为了解决拼接SQL字符串带来的问题,MyBatis存在动态SQL技术,按照特定的条件对满足条件的SQL语句进行拼接。
举例:
<select id="getEmpByIf" resultType="Emp">
select * from t_emp where 1=1
<if test="empName !=null and empName!=''">
emp_name=#{empName}
</if>
<if test="age!=null and age!='' ">
and age=#{age}
</if>
<if test="sex!=null and sex!='' ">
and sex=#{sex}
</if>
<if test="email!=null and email!='' ">
and email=#{email}
</if>
</select>
当我们通过,名字,年龄,性别,邮箱多个条件查询一个员工信息时,我们使用如下的SQL语句:
slesct * from t_emp where id=? and age=? and sex=? and email=?
在mybatis中可以使用if标签对条件进行拼接,test是条件表达式。如果不满足test的表达式,则不会拼接标签的内容,如果我们不满足第一个if标签,满足第二个if标签时,就会发生这样的SQL语句:
select * from t_emp where and age=?
很明显这样的SQL语句是错的,所以我们加上1=1这种恒成立的条件,即使第一个if条件不满足,我们的SQL是这样的:
select * from t_emp where 1=1 and age=?
使用where1=1避免了SQL语句拼接的错误。
替代where1=1
1:使用where标签
<!--where标签-->
<!--List<Emp> getEmpByWhere(Emp emp);-->
<select id="getEmpByWhere" resultType="Emp">
select * from t_emp
<where>
<if test="empName !=null and empName!=''">
emp_name=#{empName}
</if>
<if test="age!=null and age!='' ">
and age=#{age}
</if>
<if test="sex!=null and sex!='' ">
or sex=#{sex}
</if>
<if test="email!=null and email!='' ">
and email=#{email}
</if>
</where>
</select>
当我们的第一个条件不满足时,我们的SQL语句:
select * from t_emp where age=? or sex=? and email=?
where标签会自动去掉内容前多余的or或者and,但是如果我们的and或者or写在内容后:
<!--where标签-->
<!--List<Emp> getEmpByWhere(Emp emp);-->
<select id="getEmpByWhere" resultType="Emp">
select * from t_emp
<where>
<if test="empName !=null and empName!=''">
emp_name=#{empName} and
</if>
<if test="age!=null and age!='' ">
age=#{age} or
</if>
<if test="sex!=null and sex!='' ">
sex=#{sex} and
</if>
<if test="email!=null and email!='' ">
email=#{email}
</if>
</where>
</select>
当只有第一个条件满足时,SQL语句会发生错误:
select * from t_emp where emp_name=? and
2:使用trim标签
为了去掉内容后多余的and或者or,我们使用trim标签
<!--trim标签-->
<!--List<Emp> getEmpByTrim(Emp emp);-->
<select id="getEmpByTrim" resultType="Emp">
select * from t_emp
<trim prefix="where" suffixOverrides="and|or" >
<if test="empName !=null and empName!=''">
emp_name like "%"#{empName} and
</if>
<if test="age!=null and age!=''">
age=#{age} or
</if>
<if test="email!=null and email!=''">
email=#{email}
</if>
</trim>
</select>
当标签内有内容时,会在内容前添加prefix属性的内容,在内容后添加suffix属性的内容。prefixOverrides属性是去掉内容前多余的某些内容,suffixOverrides属性是去掉内容后多余的某些内容。如果trim标签内没有内容,则trim标签失效。
所以只有第一个条件满足时,我们的SQL语句会变成:
select * from t_emp where emp_name=?