场景:查询员工要求——携带了哪个字段,查询条件就带上这个字段的值
接口
public interface EmployeeMapperDynamicSQL{
//携带了哪个字段查询条件就带上这个字段的值
public List<Employee> getEmpsByConditionIf(Employee employee);
}
映射文件
使用if 标签
test:判断表达式(使用OGNL语言),test等号右边的数值是从参数中取值进行判断
OGNL:对象图导航语言,这是一种强大的表达式语言,通过它可以非常方便的来操作对象属性。类似于EL,SqEL等。它的使用方法参考官方文档好了。
<select id="getEmpsByConditionIf" resultType="com.mybatis.bean.Employee">
select * from tbl_employee
where
<if test="id!=null">
id=#{id}
</if>
<if test="lastName!=null && lastName!=''">
and last_name like #{lastName}
</if>
<if test="email!=null and email.trim()!=""">
and email=#{email}
</if>
<if test="gender==0 or gender==1">
and gender=#{gender}
</if>
</select>
在XML文档中遇见特殊符号应该去写转义字符
在OGNL中使用lastName!=' '这种判断方式是可行的,如果写成lastName!=" "反而是不对的。
在XML文档中使用&&是不对的,可以使用and,也可以使用转义字符。
OGNL会自动进行字符串与数字的转换判断,默认"0" 是等于 0 的。
测试
@Test
public void testDynamicSql(){
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
try{
EmployeeMapperDynamicSQL mapper =
openSession.getMapper(EmployeeMapperDynamicSQL.class);
Employee employee = new Employee(3, "%e%", null, null);
List<Employee> emps = mapper.getEmpsByConditionIf(employee);
for(Employee emp : emps){
System.out.println(emp);
}
}finally{
}
}
结果如下:因为email和gender都是null,所以sql语句不会待上这两个
测试时如果没带上id但是带了lastName的情况,则会报错。
当查询的时候如果某些条件没带可能sql拼装会有问题的时候解决方案有两种:
1、在where后面加上1=1,然后后面的条件前都加上and;
这样逻辑就对了,程序运行也就不会报错了
2、mybatis使用where标签来将所有的查询条件包括在内,mybatis就会将where标签中拼装的sql中多出来的and或者or去掉。
<select id="getEmpsByConditionIf" resultType="com.mybatis.bean.Employee">
select * from tbl_employee
<where>
<if test="id!=null">
id=#{id}
</if>
<if test="lastName!=null && lastName!=''">
and last_name like #{lastName}
</if>
<if test="email!=null and email.trim()!=""">
and email=#{email}
</if>
<if test="gender==0 or gender==1">
and gender=#{gender}
</if>
</where>
</select>
结果显示多出来的and并没有被拼上
但是这种方法,如果使用的是将and放在每一sql语句后面,则也会出现问题。
<select id="getEmpsByConditionIf" resultType="com.mybatis.bean.Employee">
select * from tbl_employee
<where>
<if test="id!=null">
id=#{id} and
</if>
<if test="lastName!=null && lastName!=''">
last_name like #{lastName} and
</if>
<if test="email!=null and email.trim()!=""">
email=#{email} and
</if>
<if test="gender==0 or gender==1">
gender=#{gender}
</if>
</where>
</select>
测试结果如下:
where标签只会去掉第一个多出来的and或者or,所以如果使用where标签,就不要这样乱写了。