深入浅出MyBatis技术原理与实战

参考书籍《深入浅出MyBatis技术原理与实战》


MyBatis

基本构成
  • SqlSessionFactoryBuilder(构造器):它会根据配置信息或者代码来生成SqlSessionFactory(工厂接口)

  • SqlSessionFactory:依靠工厂接口来创建SqlSession(回话)

  • SqlSession:是一个既可以发送SQL去执行并返回结果,也可以获取一个Mapper接口

  • SQL Mapper:他是一个由Java接口和XML文件(或者注解)构成,需要给出对应的SQL和映射规则,他负责发送SQL去执行,并返回结果。

这里写图片描述


String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
    inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
    e.printStackTrace();
}
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//建立Sqlsession
sqlSession = sqlSessionFactory.openSession();

SqlSessionFactory

每个MyBatis的应用都是以SqlSessionFactory的实例为中心的。SqlSessionFactory的实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactory是一个工厂接口而不是实现类,他的任务是创建SqlSession。SqlSession类似于JDBC的Connection对象。SqlSessionFactory有两种方式创建,一种是通过XML配置的方式,另一种是代码的方式,一般使用XML配置,因为可以避免硬编码同时也方便配置人员的修改。

SqlSessionFactory的实现类有两个,DefaultSqlSessionFactory和SqlSessionManager。

SqlSession

SqlSession是一个接口类,真正执行的是Executor接口。在MyBatis中,SqlSession接口的实现类有两个,DefaultSqlSession和SqlSessionManager。SqlSession类似于JDBC的Connection对象。

SqlSession的用途主要有两种:

  1. 获取映射器,让映射器通过命名空间和方法名称找到对应的SQL,发送给数据库执行后返回结果。

    sqlSession.selectOne("com.wy.bean.StudentMapper.selectStudentBySname",s);
  2. 直接通过命名信息去执行SQL并返回结果。在SqlSession可以通过update,insert,select等方法,带上SQL的id来操作在XML中配置好的SQL;同时支持事务,通过commit,rollback方法提交或者回滚事务。

        Student s = new Student();
        s.setSname("沪");
        s.setSpwd("666");
        s.setCid(1);
        sqlSession.insert("com.wy.bean.StudentMapper.insertStudent", s);

映射器Mapper

映射器由Java接口和XML文件(或注解)共同组成,作用有:

  1. 定义参数类型

  2. 描述缓存

  3. 描述SQL语句

  4. 定义查询结果和POJO(一个Java对象类)的映射关系

一个映射器有两种实现方式; 一是通过XML文件方式实现(xxxMapper.xml),来生成Mapper。另一种是通过代码实现(一个接口,在方法上使用注解实现特定的SQL语句)。

XML实现
  <!-- 根据名字查找学生 -->
  <!-- 注意:在mybatis-config.xml没有配置类别名的时候需要写上类的全路径  com.wy.bean.Student-->
  <select id="selectStudentBySname" resultType="Student" parameterType="Student">
    select * from student where sname = #{sname}
  </select>
代码实现
@Mapper
public interface GoodsDao {
    @Select("select xxx ...")
    public List<GoodsVo> listGoodsVo();

一个接口怎么就能查询出我们想要的结果呢?其实用到了Java的动态代理去实现。MyBatis会为这个接口生成代理类对象,代理对象会根据“接口全路径+方法名”去匹配,找到对应的XML文件(或注解)去完成相应的SQL并返回我们需要的结果。

生命周期

SqlSessionFactoryBuilder

SqlSessionFactoryBuilder是利用XML或者Java代码获得资源来构建SqlSessionFactory的,通过它可以构建多个SqlSessionFactory。SqlSessionFactoryBuilder的作用就是一个构造器,一旦创建了SqlSessionFactory,它的作用就完结了,失去了存在的意义,因此我们就可以对它进行回收。所以SqlSessionFactoryBuilder的生命周期只存在方法的局部,作用就是创建SqlSessionFactory。

SqlSessionFactory

SqlSessionFactory的作用是创建SqlSession,而SqlSession就是一个会话,相当于JDBC中的Connection对象。每次应用程序访问数据库,我们就要通过SqlSessionFactory创建SqlSession,所以SqlSessionFactory在MyBatis应用的整个生命周期中。如果我们多次创建SqlSessionFactory,则SqlSessionFactory会打开更多的数据库连接,导致连接资源很快就会被耗尽,因此我们采用单例模式,使得每一个数据库只对应一个SqlSessionFactory,管理好数据库资源的分配,避免过多的连接被消耗。

SqlSession

SqlSession是一个会话,相当于JDBC的一个Connection对象,它的生命周期是在请求数据库处理事务的过程中。它存活于一个应用的请求和操作,可以执行多条SQL,保证事务的一致性。它是一个线程不安全的对象,此外,每次创建SqlSession都必须及时关闭它,因为长期存在会使数据库连接池的活动资源减少,影响系统性能。

Mapper(映射器)

Mapper是一个接口,没有任何的实现类,它的作用是发送SQL,然后返回我们需要的结果,或者执行SQL从而修改数据库数据。它就如同JDBC中的一条SQL语句的执行。因此它是在一个SqlSession事务方法之内,是一个方法级别的东西。

这里写图片描述

缓存cache

目前流行的缓存服务器有MongoDB,Redis,Ehcache。缓存是在计算机内存中保存数据,在读取时无需在从磁盘读入,因此具备快速读取和使用的特点。

系统缓存

一级缓存

MyBatis默认缓存只开启一级缓存(一级缓存只是相对于同一个SqlSession而言)。所以在参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用同一个Mapper的方法,往往只执行一次SQL,因为在使用SqlSession第一次查询后,MyBatis会将结果放在缓存中。

二级缓存

因为SqlSession是相互隔离的,如果我们需要不同的SqlSession都具有相同的缓存,因此我们需要配置二级缓存,使得缓存在SqlSessionFactory层面上能够提供给各个SqlSession对象共享。

二级缓存不是默认开启的,因此我们需要进行配置,实现二级缓存MyBatis要求返回POJO(POJO(Plain Ordinary Java Object)简单的Java对象,实际就是普通JavaBeans)必须的可序列化的,因此需要实现Serializable接口。

开启缓存只需要在配置文件增加以下语句即可

<cache/>

缓存默认是使用最近最少使用算法来回收的。还有先进先出,软引用等。

自定义缓存

可以使用Redis缓存。(没用过…)

MyBatis解析和运行原理

涉及的技术,反射,动态代理。因为Mapper是一个接口,因此使用JDK动态代理可以很好的实现。

构建SqlSessionFactory过程

SqlSessionFactory是MyBatis的核心类之一,功能是创建核心接口SqlSession。我们采用构造模式创建SqlSessionFactory,可以通过SqlSessionFactoryBuilder去构建,构建分为两步。

  1. 第一步通过XMLConfigBuilder解析配置的XML文件,读取配置参数,并将读取的数据存入Configuration类中,MyBatis几乎所有 配置都是存在这里。

  2. 第二步,使用Configuration对象创建SqlSessionFactory

构建SqlSessionFactory过程

SqlSessionFactory是MyBatis的核心类之一,功能是创建核心接口SqlSession。我们采用构造模式创建SqlSessionFactory,可以通过SqlSessionFactoryBuilder去构建,构建分为两步。

1. 第一步通过XMLConfigBuilder解析配置的XML文件,读取配置参数,并将读取的数据存入Configuration类中,MyBatis几乎所有 配置都是存在这里。

2. 第二步,使用Configuration对象创建SqlSessionFactory。SqlSessionFactory是一个接口,MyBatis为我们提供了一个默认的SqlSessionFactory实现类,DefaultSqlSessionFactory。SqlSessionManager也是一个实现类。

构建Configuration

在SqlSessionFactory构建中,Configuration是最重要的,作用如下:

  • 读取配置文件,包括基础配置的XML文件和映射器的XML文件

  • 初始化基础配置,比如MyBatis的别名等,一些重要的类对象,比如,插件,映射器等

  • 提供单例,为后面创建SessionFactory服务并提供配置的参数

  • 执行一些重要的对象方法,初始化配置信息

映射器的内部组成

一般而言,一个映射器由三个部分组成

  • MappedStatement,它保存映射器的一个节点(select,insert,update,delete)。包括许多我们配置的SQL,resultMap等配置内容。

  • SqlSource,是一个接口,它是提供BoundSql对象的地方,它是MappedStatement的一个属性。主要作用是根据参数和其他规则组装SQL(比如动态SQL)

  • BoundSql,是建立SQL和参数的地方。它有三个常用的属性,SQL(我们在映射器里面的一条SQL),parameterObject,parameterMapping(它是一个List)。

这里写图片描述

构建SqlSessionFactoy

有了Configuration对象构建SqlSessionFactoy就很简单

sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

MyBatis会根据Configuration的配置读取配置信息,构建SqlSessionFactoy对象。

SqlSession运行过程

SqlSession是一个接口,提供了增删改查的方法。实现它的功能是通过动态代理,让这个接口跑起来。

SqlSession下的四大对象

映射器其实就是一个动态代理对象。Mapper执行的过程是通过Executor,StatementHandler,ParameterHandler和ResultHandler来完成数据库操作和结构返回的。

  • Executor代表执行器,由它来调度StatementHandler,ParameterHandler和ResultHandler等来执行对应的SQL

  • StatementHandler的作用是使用数据库的Statement(PrepareStatement)执行操作,它是四大对象的核心,起到承上启下的作用

  • ParameterHandler用于SQL对参数的处理

  • ResultHandler是进行最后数据集(ResultSet)的封装返回处理的

执行器Executor

执行器Executor是真正执行Java和数据库交互的东西。MyBatis中三种执行器。

  1. SIMPLE,简易执行器,默认的执行器

  2. REUSE,是一种执行器重用预处理语句

  3. BATCH,执行器重用语句和批量更新,它是针对批量专用的执行器

数据库会话器StatementHandler

数据库会话器StatementHandler是专门处理数据库会话的。

参数处理器ParameterHandler

MyBatis通过参数处理器ParameterHandler对预编译语句进行参数设置。作用是完成对预编译参数的设置。

结果处理器ResultHandler

ResultHandler是进行最后数据集(ResultSet)的封装返回处理的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值