Mybatis基础回顾

用了很久的Mybatis,但是一直没有全面去学过,这次补一下基础吧

Mybatis

当使用Mybatis时,首先用字节流通过Resource将配置文件读入,然后通过SqlSessionFactoryBuilder().build方法创建SqlSessionFactory,然后再通过sqlSessionFactory.openSession()方法创建一个sqlSession。Mybatis通过xml文件映射到各实体类的Mapper接口,Mapper接口中配置了每个类对数据库所需进行的sql语句映射。
经历了Mybatis初始化 –>创建SqlSession –>运行SQL语句 返回结果三个过程

mybatis缓存概念

当我们使用Mybatis进行数据库的操作时候,MyBatis会开启一个会话时,然后创建一个新的SqlSession对象,SqlSession对象中会有一个新的Executor对象,Executor对象中持有一个新的PerpetualCache对象;当会话结束时,SqlSession对象及其内部的Executor对象还有PerpetualCache对象也一并释放掉。

一级缓存:(HashMap来实现,并没有对HashMap的容量和大小进行限制,key为hashCode+sqlId+Sql语句。value为从查询出来映射生成的java对象)

对SqlSession的操作mybatis内部都是通过Executor来执行的,Executor在执行数据库查询的时候总是先查看缓存中是否存在,若不存在则查询数据库。

SqlSession是对外接口,Executor是内部执行器

二级缓存:

二级缓存的范围更大,根据namespace划分的,多个SqlSession可以共享一个UserMapper的二级缓存区域。

每一个namespacemapper有一个二级缓存区域。也就是说如果两个mappernamespace相同,那么这两个mapper执行sql查询到的数据将存储在一个二级缓存区域中。

mybatis的二级缓存是通过CacheExecutor实现的。CacheExecutor其实是Executor的代理对象。所有的查询操作,在CacheExecutor中都会先匹配缓存中是否存在,不存在则查询数据库。二级缓存是可以跨SqlSession的

MyBatis查询数据的顺序是:

二级缓存 ———> 一级缓存——> 数据库

要使用Mybatis的二级缓存,需要对Mybatis进行配置,配置分三步

  • Mybatis全局配置中启用二级缓存配置

    1
    <setting name="cacheEnabled" value="true"/>
  • 在对应的Mapper.xml中配置cache节点

    1
    2
    3
    4
    5
    <mapper namespace="userMapper">
    <cache />
    <result ... />
    <select ... />
    </mapper>
  • 在对应的select查询节点中添加useCache=true

    1
    2
    3
    <select id="findUserById" parameterType="int" resultMap="user" useCache="true">
    select * from users where id=#{id};
    </select>
  • 实体类要实现序列化接口

    1
    2
    3
    4
    public class User implements Serializable{
    //属性......
    //getter and setter......
    }

区别

一级缓存是sqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(HashMap),用于存储缓存数据。不同的sqlSession之间的缓存区域(HashMap)是互不影响的。

二级缓存是mapper级别的缓存,多个sqlSession去操作同一个Mapper的sql语句,多个SqlSession可以公用二级缓存,二级缓存是跨sqlSession的。

MyBatis和Hibernate各有什么优缺点?

Hibernate的优点是它是一个完全的ORM框架,使用Hibernate可以做到不用手写SQL,而且无须关心使用何种数据库,可移植性较好,当需要更变数据库时需要做的修改很少甚至为0。其缺点是需要根据数据库的设计在实体进行又一次的配置,且帮程序员做了太多事,如果需要进行调优的话需要对Hibernate有比较深的了解。
MyBatis的优缺点差不多和Hibernate相反,我们需要手写SQL语句和配置结果集和实体类的映射,即使是简单的单表操作也需要写SQL(可以通过拦截器来实现CommonMapper,或者可以使用生成器来生成代码),因此MyBatis要进行SQL调优也简单直接。其次是MyBatis二级缓存功能较弱,是针对namespace的。

动态SQL

MyBatis系列之动态SQL语句

MyBatis中的OGNL教程

TypeHandler

TypeHandler可以让数据库字段类型和Java类做一个映射,就好像默认text类可以转成String,但是可以用TypeHandler来转成Java自定义类型

http://www.jianshu.com/p/17313a00a102