//
根据id, lastNname, age, sex多条件查询员工信息
public List<Emp> getEmpListByMoreCondition(Emp emp);
2、在 EmployeeMapper.xml 中配置 SQL 语句
public List<Emp> getEmpListByMoreCondition(Emp emp);
多条件查询:若页面中没有设置此条件,SQL语句中一定不能有该条件
<
select
id
="getEmpListByMoreCondition1"
resultType
="Emp"
>
select eid,ename,age,sex,did from emp
where
id = #{id}
and last_name = #{lastName}
and age = #{age}
and sex = #{sex}
</
select
>
在这里可以看到,使用的是 SQL 拼接的方式,来进行多条件查询的。
二、使用 if 标签实现多条件查询
1、在 EmployeeMapperDynamicSQL 接口中声明方法
public List<Employee> getEmpsByConditionIf(Employee employee);
2、在
EmployeeMapperDynamicSQL.xml 中进行配置
1、查询员工:要求携带了哪个字段查询条件就带上这个字段的值
public List<Employee> getEmpsByConditionIf(Employee employee);
test:判断表达式(OGNL)表达式
OGNL 表达式参照官方文档或PPT
c:if test
从参数中取值进行判断
遇见特殊符号应该去写转义字符:
" : "
& : &
OGNL 会进行字符串和与数字的转换判断
<
select
id
="getEmpsByConditionIf"
resultType
="Employee"
>
select * from tbl_employee
where
<
if
test
="id!=null"
>
id=#{id}
<
if
test
="lastName!=null and lastName!=''"
>
and last_name like #{lastName}
<
if
test
="email!=null and email.trim()!="""
>
and email = #{email}
<
if
test
="gender==0 or gender==1"
>
and gender = #{gender}
</
select
>
<if> 标签的作用:通过 test 表达式,用于拼接 SQL,如果 test 为 true,将其中的 SQL 进行拼接,否则不进行拼接。
3、细节问题1
当我们把 gender 字段改为"男、女"的字符格式时,然后重新修改 xml 中的配置:
<select id="getEmpsByConditionIf" resultType="Employee">
select * from tbl_employee
<where>
<if test="id!=null">
id=#{id}
<if test="lastName!=null and lastName!=''">
and last_name like #{lastName}
<if test="email!=null and email.trim()!=""">
and email = #{email}
<if test="gender == '男' or gender == '女'">
and gender = #{gender}
</where>
</select>
测试信息:
@Test
public void testIf() throws IOException {
//1、获取 sqlSessionFactory
SqlSessionFactory sqlSessionFactory = getsqlSessionFactory();
//2、获取 sqlSession 实例,能直接执行已经映射的 SQL 语句
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
EmployeeMapperDynamicSQL mapper = sqlSession.getMapper(EmployeeMapperDynamicSQL.class);
//select * from tbl_employee where id=? and last_name like ? and email = ?
Employee employee = new Employee(null, "%o%", "男","tom@126.com");
List<Employee> emps = mapper.getEmpsByConditionIf(employee);
emps.forEach(System.out::println);
} finally {
sqlSession.close();
运行结果:
我们发现,这时并不能正常执行。
重新修改配置文件:
<select id="getEmpsByConditionIf" resultType="Employee">
select * from tbl_employee
<where>
<if test="id!=null">
id=#{id}
<if test="lastName!=null and lastName!=''">
and last_name like #{lastName}
<if test="email!=null and email.trim()!=""">
and email = #{email}
<if test='gender == "男" or gender == "女"'>
and gender = #{gender}
</where>
</select>
修改了映射文件,重新运行。
运行成功。
(1)if 标签中判断字符串变量是否是字符串的时候,发现并不管用;
(2)如果把变量的值用双引号引起来,外面使用 单引号,这时就成功了;
(3)只能解释为 MyBatis 会把 '男' 解析为字符,而需要的是字符串,java 是强类型语言,字符串和字符不能直接比较,所以需要使用双引号。
4、细节问题2
对于上面的拼接条件,如果使用了多条件拼接查询,当有多个匹配条件时,可以使用 and 来连接。
但是如果第一个条件如果不进行拼接,就会出现 where 后面多出一个 and 的情况。
例如上面的情况,如果 id 为 null,就不会进行拼接该 SQL 片段,而是直接拼接第二个条件,这时就会出现一个 and 字段
select * from tbl_employee where and last_name = ? and email = ? and gender = ?
这时 SQL 的执行就会出现问题。
5、解决方案一
在 where 后面添加一个恒成立的情况,如果第一个条件不匹配,也不会不执行。
<select id="getEmpsByConditionIf" resultType="Employee">
select * from tbl_employee
where 1=1
<if test="id!=null">
and id=#{id}
<if test="lastName!=null and lastName!=''">
and last_name like #{lastName}
<if test="email!=null and email.trim()!=""">
and email = #{email}
<if test="gender==0 or gender==1">
and gender = #{gender}
</select>
执行的 SQL 语句:
select * from tbl_employee where 1=1 and last_name = ? and email = ? and gender = ?
常用的恒等式有:
6、解决方案二
使用下面的 where 标签
三、使用 where 条件
使用 where 标签优化多查询查询(方案二)
<where> 标签的作用:添加where关键字,同时去掉多余的and
修改上面 xml 中的配置
<select id="getEmpsByConditionIf" resultType="Employee">
select * from tbl_employee
<where>
<if test="id!=null">
id=#{id}
<if test="lastName!=null and lastName!=''">
and last_name like #{lastName}
<if test="email!=null and email.trim()!=""">
and email = #{email}
<if test="gender==0 or gender==1">
and gender = #{gender}
</where>
</select>
这时如果 id 还是 null,而不用再在 where 后面加恒等式,也可以执行成功。where 标签会把多余的 and 去掉。
执行的 SQL 语句:
select * from tbl_employee WHERE last_name like ? and email = ?
(1)if 标签和 where 标签不一定必须同时使用,按实际需要进行使用;
(2)if 标签用于完成简单的判断;
(3)where 用于解决 SQL 语句中 where 关键字以及条件中第一个 and 或者 or 的问题;
(4)mybatis就会将where标签中拼装的sql,多出来的and或者or去掉,where只会去掉第一个多出来的and或者or。
查询的时候如果某些字段没带可能 SQL 拼装会有问题。
(1)给 where 后面加上1=1,以后的条件都是 and xxx;
(2)mybatis 使用where标签来将所有的查询条件包括在内,mybatis 就会将where标签中拼装的SQL,多出来的and或者or去掉;
(3)where 只会去掉第一个多出来的and或者or;