//




    
根据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 从参数中取值进行判断 遇见特殊符号应该去写转义字符: " : &quot; & : &amp; 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()!=&quot;&quot;" > 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()!=&quot;&quot;">
                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()!=&quot;&quot;">
                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()!=&quot;&quot;">
                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()!=&quot;&quot;">
                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;