简介

MyBatis是一个对象关系映射(Object Relational Mapping)框架,最初是Apache的一个开源项目iBatis,从iBatis3.x正式更名为MyBatis,是一个基于Java的持久层框架。

  • 支持定制化SQL
  • 避免大部分JDBC代码
  • 通过XML或注解进行映射,将接口和Java中的对象映射成数据库中的记录。
  • 半自动的ORM框架

    持久层框架特点

  • JDBC

    • SQL 夹杂在Java代码中耦合度高,导致硬编码内伤
    • 维护不易且实际开发需求中 SQL 有变化,频繁修改的情况多见
    • 代码冗长,开发效率低
  • Hibernate 和 JPA
    • 操作简便,开发效率高
    • 程序中的长难复杂 SQL 需要绕过框架
    • 内部自动生产的 SQL,不容易做特殊优化
    • 基于全映射的全自动框架,大量字段的 POJO 进行部分映射时比较困难。
    • 反射操作太多,导致数据库性能下降
  • MyBatis

    • 轻量级,性能出色
    • SQL 和 Java 编码分开,功能边界清晰。Java代码专注业务、SQL语句专注数据
    • 开发效率稍逊于HIbernate,但是完全能够接受

      获取参数的两种方式

      ${param}

      ${param}的本质是字符串拼接,将param的值拼接到${param}的位置,不会添加单引号。
      1. <!--User getUserByUsername(String username);-->
      2. <select id="getUserByUsername" resultType="User">
      3. select * from t_user where username = '${username}'
      4. </select>

      #{param}

      {param}使用占位符赋值的方式拼接,当param为字符串或日期类型的字段时,会自动添加单引号。

      1. <!--User getUserByUsername(String username);-->
      2. <select id="getUserByUsername" resultType="User">
      3. select * from t_user where username = #{username}
      4. </select>

      动态表名

      当表名不固定时,例如拆分表,则需要动态确定查询的表名。
      1. <!--List<User> getUserByTable(@Param("tableName") String tableName);-->
      2. <select id="getUserByTable" resultType="User">
      3. select * from ${tableName}
      4. </select>

      缓存

      MyBatis内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制。将经常查询的数据存放在内存中,用户再次去查时就不用从数据库查询,从而提高查询效率,解决部分高并发性能问题。

      一级缓存

      一级缓存是SqlSession级别的,同一个SqlSession查询的数据会被缓存。一级缓存失效的四种情况:
  • 不同的SqlSession对应不同的一级缓存

  • 同一个SqlSession但是查询条件不同
  • 同一个SqlSession两次查询期间执行了任何一次增删改操作
  • 同一个SqlSession两次查询期间手动清空了缓存

    二级缓存

    二级缓存是SqlSessionFactory级别,同一个SqlSessionFactory创建的SqlSession查询的数据会被缓存。二级缓存的开启条件:

  • 核心配置文件设置全局配置属性cacheEnabled=”true”,默认为true,不需要设置

  • 映射文件中设置标签
  • 二级缓存必须在SqlSession关闭或提交之后有效
  • 查询的数据所转换的实体类类型必须实现序列化的接口

    缓存查询顺序

  1. 先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用
  2. 如果二级缓存没有命中,再查询一级缓存
  3. 如果一级缓存也没有命中,则查询数据库
  4. SqlSession关闭之后,一级缓存中的数据会写入二级缓存