Mybatis原理

  1. 简介
    Mybatis是一款非常优秀的半自动化持久层框架,主要着力点在于 POJO 与 SQL 之间的映射关系。然后通过映射配置文件,将SQL所需的参数,以及返回的结果字段映射到指定 POJO 。

  2. Mybatis技术原理

Mybatis的工作内容主要包括以下两个部分:

加载配置,构建SqlSessionFactory。
使用SqlSessionFactory构建SqlSession,由SqlSession完成跟数据库的交互操作。

    构建SqlSessionFactory的流程如下图所示, 首先把平台所有的Mybatis相关配置信息加载到一个Configuration对象中,再把这个Configuration对象作为构建参数,完成SqlSessionFactory对象的创建。Mybatis的常用配置来源包括 sql文件、Mybatis配置文件、以及java编码配置, 但这些配置来源都是非必须的。无论是哪种配置来源,Mybatis最终的目的就是为了构建一个Configuration对象,只要以满足这个目的为前提,任何配置来源都可以找到相应的替换方式。Configuration对象包含的配置非常复杂,但我们需要重点关注的配置项并不多,一般采用默认配置即可,在开发中需要更改或新增默认配置时,可以参考xml的配置方式:http://www.mybatis.org/mybatis-3/zh/configuration.html

在实际项目中,一般不会直接采用xml的配置方式,但通过上面的配置文档,可以系统了解总共有哪些配置项,再按对应的替换方式进行配置即可。比如Springboot整合Mybatis的项目,直接在application.properties中也可以对Mybatis大部分的参数进行配置。
在这里插入图片描述

    了解Configuration对象是Mybatis开发中排查问题非常重要的一环。 这里自定义两个对比词汇: 1) 运行环境    2)外观环境(或逻辑环境)。其中,Configuration对象可称为Mybatis的 运行环境 , 而 sql文件、Mybatis配置文件 这些被 称为 Mybatis的外观环境(或逻辑环境)。 在大多数情况下,查看外观环境是我们排查问题的首选,因为便于观察和判断,所以排查问题也相对迅速。然而,只理解外观环境是不够的,举几个例子:

    1. A同事发现 运行项目时某个配置文件找不到, 但是查看项目发现该配置文件是有的,多次重启项目还是无法解决这个问题;

    2. B同事发现 运行项目时 某个类缺失, 在pom文件中查找依赖,发现已经引入对应的jar包,jar包中也存在相应的类,多次检查后还是未发现问题;

    3. C同事在开发时发现 页面数据跟数据库的数据对不上,怀疑连错了库,于是反复检查 config.properties的数据库配置,startup的jar包是否引入,最后还是无奈求助。

    

    上述例子在日常开发中屡见不鲜,究其原因,还是习惯于对外观环境进行排查,而忽略对运行环境的查看。同样的,如果不了解Configuration对象,  在Mybatis的开发过程中,我们同样只能依赖于外观环境,在特定环境下排查问题将会非常艰难。



    在完成SqlSessionFactory的构建后,接下来只要构建SqlSession,就可进行跟数据库交互了。Mybatis构建SqlSession并进行数据库交互的流程如下:

在这里插入图片描述

    由于SqlSession是非线程安全的,上述的Mybatis原生流程,每次调用时都需要手工创建SqlSession,获得Mapper并调用,开发时十分不方便。在项目中更常用的是下述的Mybatis-Spring式的调用流程:

在这里插入图片描述

    这种方式与Mybatis原生的流程相比,区别在于项目启动时即创建Mapper代理对象, 使用的SqlSession也同样是代理对象,在真正进行数据库交互时创建一个新的SqlSession对象,来代替当前对象执行目标方法即可。在项目中此方式实用了许多,使用时直接注入Mapper并调用Mapper的方法即可。

    SqlSession执行数据库交互的流程如下:

在这里插入图片描述

    上述执行流程中, SqlSession调用Executor执行数据库交互, Executor控制着 预编译、参数设置、结果处理 等流程, 而StatementHandler则为每个流程提供功能支持,对于其中的参数设置和结果处理,StatementHandler分别委托给了ResultSetHandler和ParameterHandler 进行处理。Executor、StatementHandler、ResultSetHandler、ParameterHandler 这四个对象主导了Mybatis执行数据库交互的流程,为Mybatis的四大核心对象,Mybatis允许我们对这四个对象的方法进行拦截、通过动态代理技术增强功能,这便是Mybatis的插件技术,对应的拦截器又被称作插件。

    讨论点:  如何利用插件技术制作常用的分页插件,  分页插件应该拦截哪个对象?
  1. Mybatis使用技巧
    3.1 自定义类型处理器
    在Configuration对象创建时,默认会注册一系列类型处理器:
    在这里插入图片描述
    虽然大量常用的类型都能够通过这些处理器进行处理, 但仍有一部分情况需要我们自定义类型处理器,比如json字段需要转为java中的对象,java中的Calendar类型支持,枚举值转换等。支持Calendar类型的自定义类型处理器如下所示:

在这里插入图片描述

    类型处理器可通过指定包名进行集中注册:

    mybatis:

            typeHandlersPackage: com.hikvision.ctm01punishment.web.modules.typehandlers

3.2 执行器的选择
Mybatis并列的执行器有以下三种(CachingExecutor跟其他三种可联合使用,不算并列):

    SIMPLE 为普通的执行器;

    REUSE 执行器会重用预处理语句(prepared statements);

    BATCH 执行器将重用语句并执行批量更新。

    以上为三种处理器官方的定义,默认情况下, Mybatis的执行器使用SIMPLE。单看上面的定义肯定有些模糊, 接下来依次进行说明:

    首先,SIMPLE执行器在接到数据库交互请求后,无论是查询还是修改都是以下步骤:

    1. 控制StatementHandler准备预处理语句;
    2. 控制StatementHandler设置请求参数;
    3. 调用StatementHandler的select/update方法;

    相应的,BATCH 执行器在接到查询请求时,同样使用以上步骤,而在接到更新请求时,会把预处理语句缓存起来,并且调用StatementHandler的batch方法,把预处理语句加入到批量更新列表,待事务完成时统一提交。而REUSE 执行器不管是查询还是更新, 都会把已创建的预处理语句缓存起来,遇到相同sql则取出来复用。
   有了上述理论基础后,我们再来讨论以上处理器分别在何时能发挥最大的作用。这里就涉及到处理器的生命周期,按工作流程中的介绍,处理器由SqlSession进行调用,而Executor作为SqlSession的成员变量,其生命周期与SqlSession一致,即事务中复用Executor, 非事务环境下每次交互新建 Executor。了解这点之后,对执行器的选择可归纳为以下几点:
    1.在同一个事务中有大量的相同更新时,如在事务中往同一张表中插入大量数据,应使用BATCH 执行器(如果数据量太多需分批调用事务方法、防止内存溢出)。
    2.同一个事务中 有大量相同查询语句(参数不同,如果参数相同时一级缓存会返回之前的查询对象), 或者大量相同更新语句,但是不想批量提交的,应使用REUSE 执行器;
    3.项目中无上述两种情况时,可以考虑使用默认的 SIMPLE执行器。

    在springboot项目中,可通过以下方式指定执行器:
    mybatis:
            executor-type: batch
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值