MyBatis教程大全


 MyBatis SQL 映射

     MyBatis select 标签

     MyBatis 多数据库支持

     MyBatis selectKey 标签作用

     MyBatis @SelectKey注解用法介绍

     MyBatis @SelectKey注解用法详细介绍

     MyBatis keyProperty 属性介绍

     MyBatis insert、update 和 delete 元素

     MyBatis sql 元素

 MyBatis SQL 参数映射

     MyBatis SQL 参数映射

 MyBatis 动态SQL

     MyBatis 动态SQL与数据准备

     MyBatis if 标签

     MyBatis if else 用法

     MyBatis choose、when、otherwise 标签

     MyBatis where 标签

     MyBatis set 标签

     MyBatis foreach 标签

     MyBatis bind 标签

     MyBatis trim 标签

 MyBatis SQL 结果映射

 MyBatis SQL 结果之关系映射

 MyBatis 使用介绍

     MyBatis typeAliases 类型别名

     MyBatis typeHandlers 类型处理器

     MyBatis Transaction 事务接口

     MyBatis transactionManager 事务管理

     SqlSessionFactory 介绍

     MyBatis 核心对象 SqlSession

     MyBatis 初始化 创建 Session 实例

     MyBatis ObjectFactory 对象工厂

     MyBatis缓存机制:一级缓存和二级缓存

     MyBatis 常用注解

 MyBatis 配置文件

     MyBatis 配置文件

 MyBatis 映射

     MyBatis 映射简介

     MyBatis ResultMap 映射

     MyBatis 自动映射

     MyBatis 高级映射

     MyBatis 集合映射

     MyBatis 关联映射

     MyBatis 一对一关联映射

     MyBatis 一对多关联映射

     MyBatis 多对多关联映射

     MyBatis 一对一(注解形式)

     MyBatis 一对多(注解形式)

     MyBatis 多对多(注解形式)

     MyBatis resultMap 元素

 MyBatis 面试题库

     #{}和${}的区别是什么?

     数据库链接中断如何处理?

     数据库插入重复如何处理?

     事务执行过程中宕机的应对处理方式

     Java客户端中的一个Connection问题

MyBatis where 标签

MyBatis where 标签

前面几个例子已经很好地解决了动态SQL问题。现在回到之前的if示例,这次我们将state="ACTIVE"也设置成动态的条件,看看会发生什么。

<select id="selectEmployeeByIdLike" resultType="cn.mybatis.domain.Emplyee">
SELECT * FROM tb_employee WHERE
    <if test="state != null ">
      state= #{state}
    </if>
    <if test="id != null ">
      and id = #{id}
    </if>
</select>

如果传入state参数,则执行正常。如果没有传入参数,则会执行sql语句:

SELECT * EROM tb_employee WHERE

如果只是传入id,则会执行sql语句:

SELECT * FROM tb_ employee WHERE and id = ?

也就是说,如果没有传入state参数,会导致执行失败。这个问题不能简单地用条件语句来解决。MyBatis有一个简单的处理方法,只要简单地修改就能得到想要的效果:

<select id="selectEmployeeLike" resultType="cn.mybatis.domain.Employee">
SELECT * EROM tb_employee
    <where>
      <if test="state != null ">
        state = #{state}
      </if>
      <if test="id != null ">
        and id = #{id}
      </if>
      <if test="loginname != null and password != null">
        and loginname = #{loginname} and password = #{password}
      </if>
    </where>
</select>

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

List<Employee> selectEmployeeLike (HashMap<string,object> params) ;

public void testSelectEmployeeLike(SqlSession session)
{
    EmployeeMapper em = session.getMapper(EmployeeMapper.class);
    HashMap<string, Object> params = new HashMap<string, Object>();
    // 设置id,loginname和password属性
    params.put("id", 1);
    params.put("loginname", "jack");
    params.put("password", "123456");
    List<Employee> list = em.selectEmployeelike(params);
    list.forEach(employee -> System.out.printIn(employee));
}

测试selectEmployeeLike方法,控制台显示如下:

DEBUG [main]==> Preparing: SELECT * FROM tb_employee WHERE id = ? and loginname= ? and password = ?
DEBUG [main]==> Parameters: 1(Integer),jack(String),123456(string)
DEBUG [main]==> Total: 1
Employee [id=1,paasword=12345,name=杰克,sex=男,age=26]
loginnamejack,
phone=13902019999,sal=9800.0,state-ACTIVE]

可以看到,当没有传入 state 参数时,MyBatis 自动过滤掉 id 前面的 and 关键字。

MyBatis where 标签的局限性

where 标签只能去除第一个条件中出现的前置 and 关键字。像以下情况,where 就无能为力了:

<select id="selectEmployeeLike" resultType="cn.mybatis.domain.Employee">
SELECT * EROM tb_employee
    <where>
      <if test="state != null ">
        state = #{state} and
      </if>
      <if test="id != null ">
        id = #{id} and
      </if>
      <if test="loginname != null and password != null">
        loginname = #{loginname} and password = #{password}
      </if>
    </where>
</select>

where 标签无法去除掉后面的 and 关键字,此时 SQL 语句出现语法错误。要想解决以上 where 标签无法处理的问题,可以考虑使用 trim 标签