一、Mybatis介绍

mybatis是一个持久层的框架,是对JDBC操作数据库的封装,使开发者只需要关注业务本身,不需要花费精力去处理加载驱动、创建数据库连接对象、创建statement语句对象、参数设置、结果集处理等一系列繁杂的过程代码。

mybatis通过xml或注解进行配置,将java对象与sql语句中的参数自动映射生成最终执行的sql语句,并将sql语句执行结果自动映射成java对象,返回给业务层(service)应用。

如果面试时被问到请你说一下你对mybatis的理解,你就可以从下面的几个方面简单说一下。

二、Mybatis框架的工作原理

1)读取 MyBatis 配置文件:mybatis-config.xml 为 MyBatis 的全局配置文件,配置了 MyBatis 的运行环境等信息,例如数据库连接信息。
2)加载映射文件。映射文件即 SQL 映射文件,该文件中配置了操作数据库的 SQL 语句,需要在 MyBatis 配置文件 mybatis-config.xml 中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。
3)构造会话工厂:通过 MyBatis 的环境等配置信息构建会话工厂 SqlSessionFactory。
4)创建会话对象:由会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL 语句的所有方法。
5)Executor 执行器:MyBatis 底层定义了一个 Executor 接口来操作数据库,它将根据 SqlSession 传递的参数动态地生成需要执行的 SQL 语句,同时负责查询缓存的维护。
6)MappedStatement 对象:在 Executor 接口的执行方法中有一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等信息。
7)输入参数映射:输入参数类型可以是 Map、List 等集合类型,也可以是基本数据类型和 POJO 类型。输入参数映射过程类似于 JDBC 对 preparedStatement 对象设置参数的过程。
8)输出结果映射:输出结果类型可以是 Map、 List 等集合类型,也可以是基本数据类型和 POJO 类型。输出结果映射过程类似于 JDBC 对结果集的解析过程。

 三、Mybatis的核心组件

1、核心组件
1)SqlSessionFactoryBuilder(构造器):它会根据配置或者代码来生成 SqlSessionFactory,采用的是分步构建的 Builder 模式。
2)SqlSessionFactory(工厂接口):依靠它来生成 SqlSession,使用的是工厂模式。SqlSessionFactory 唯一的作用就是生产 MyBatis 的核心接口对象 SqlSession,所以它的责任是唯一的
3)SqlSession(会话):一个既可以发送 SQL 执行返回结果,也可以获取 Mapper 的接口。在现有的技术中,一般我们会让其在业务逻辑代码中“消失”,而使用的是 MyBatis 提供的 SQL Mapper 接口编程技术,它能提高代码的可读性和可维护性。
4)SQL Mapper(映射器):MyBatis 新设计存在的组件,它由一个 Java 接口和 XML 文件(或注解)构成,需要给出对应的 SQL 和映射规则。它负责发送 SQL 去执行,并返回结果。

2、核心组件的作用域
1)SqlSessionFactoryBuilder 的作用在于创建 SqlSessionFactory,创建成功后,SqlSessionFactoryBuilder 就失去了作用,所以它只能存在于创建 SqlSessionFactory 的方法中,而不要让其长期存在。因此       SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。
2)SqlSessionFactory 可以被认为是一个数据库连接池,它的作用是创建 SqlSession 接口对象。因为 MyBatis 的本质就是 Java 对数据库的操作,所以 SqlSessionFactory 的生命周期存在于整个 MyBatis 的应  用之中,所以一旦创建了 SqlSessionFactory,就要长期保存它,直至不再使用 MyBatis 应用,所以可以认为 SqlSessionFactory 的生命周期就等同于 MyBatis 的应用周期。
由于 SqlSessionFactory 是一个对数据库的连接池,所以它占据着数据库的连接资源。如果创建多个 SqlSessionFactory,那么就存在多个数据库连接池,这样不利于对数据库资源的控制,也会导致数据库连 接资源被消耗光,出现系统宕机等情况,所以尽量避免发生这样的情况。因此在一般的应用中我们往往希望 SqlSessionFactory 作为一个单例,让它在应用中被共享。所以说 SqlSessionFactory 的最佳作用域是 应用作用域。
3)SqlSession 就相当于一个数据库连接(Connection 对象),你可以在一个事务里面执行多条 SQL,然后通过它的 commit、rollback 等方法,提交或者回滚事务。所以它应该存活在一个业务请求中,处理完 整个请求后,应该关闭这条连接,让它归还给 SqlSessionFactory,否则数据库资源就很快被耗费精光,系统就会瘫痪,所以用 try...catch...finally... 语句来保证其正确关闭。所以 SqlSession 的最佳的作用域是请求或方法作用域。
4)Mapper 是一个接口,它由 SqlSession 所创建,所以它的最大生命周期至多和 SqlSession 保持一致,尽管它很好用,但是由于 SqlSession 的关闭,它的数据库连接资源也会消失,所以它的生命周期应该小于等于 SqlSession 的生命周期。Mapper 代表的是一个请求中的业务处理,所以它应该在一个请求中,一旦处理完了相关的业务,就应该废弃它。

 3、使用 XML 构建 SqlSessionFactory
在 MyBatis 中的 XML 分为两类,一类是基础配置文件,通常只有一个,主要是配置一些最基本的上下文参数和运行环境(数据源库连接等);另一类是映射文件,它可以配置映射关系、SQL、参数等信息。
创建过程:
首先读取 mybatis-config.xml,然后通过 SqlSessionFactoryBuilder 的 Builder 方法去创建 SqlSessionFactory。整个过程比较简单,而里面的步骤还是比较烦琐的,只是 MyBatis 采用了 Builder 模式为开发者隐藏了这些细节。这样一个 SqlSessionFactory 就被创建出来了。

SqlSession有2个实现类,分别是
DefaultSqlSession 和 SqlSessionManager。
DefaultSqlSession 是单线程使用的,而 SqlSessionManager 在多线程环境下使用。SqlSession 的作用类似于一个 JDBC 中的 Connection 对象,代表着一个连接资源的启用。具体而言,它的作用有 3 个:
○ 获取 Mapper 接口。
○ 发送 SQL 给数据库。
○ 控制数据库事务。
先来掌握它的创建方法,有了 SqlSessionFactory 创建的 SqlSession 就十分简单了,如下所示。
SqlSession sqlSession = SqlSessionFactory.openSession();

四、Mybatis的缓存机制

mybatis提供了缓存机制减轻数据库压力,提高数据库性能
mybatis的缓存分为两级:一级缓存、二级缓存
一级缓存是SqlSession级别的缓存,缓存的数据只在SqlSession内有效
二级缓存是mapper级别的缓存,同一个namespace公用这一个缓存,所以对SqlSession是共享的

一级缓存的具体流程:
1.第一次执行select完毕会将查到的数据写入SqlSession内的HashMap中缓存起来
2.第二次执行select会从缓存中查数据,如果select相同切传参数一样,那么就能从缓存中返回数据,不用去数据库了,从而提高了效率
注意事项:
1.如果SqlSession执行了DML操作(insert、update、delete),并commit了,那么mybatis就会清空当前SqlSession缓存中的所有缓存数据,这样可以保证缓存中的存的数据永远和数据库中一致,避免出现脏读
2.当一个SqlSession结束后那么他里面的一级缓存也就不存在了,mybatis默认是开启一级缓存,不需要配置
3.mybatis的缓存是基于[namespace:sql语句:参数]来进行缓存的,意思就是,SqlSession的HashMap存储缓存数据时,是使用[namespace:sql:参数]作为key,查询返回的语句作为value保存的。
一级缓存小结:
○ MyBatis一级缓存的生命周期和SqlSession一致。
○ MyBatis一级缓存内部设计简单,只是一个没有容量限定的HashMap,在缓存的功能性上有所欠缺。
○ MyBatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据。所以分布式环境下,建议设定缓存级别为Statement。因为在查询方法执行的最后,会判断一级缓存级别是否是STATEMENT级别,如果是的话,就清空缓存。如此一来,便相当于不使用一级缓存。

二级缓存的具体流程:
1.当一个sqlseesion执行了一次select后,在关闭此session的时候,会将查询结果缓存到二级缓存
2.当另一个sqlsession执行select时,首先会在他自己的二级缓存中找(前提是二级缓存开启),如果没找到,就回去一级缓存中找,找到了就返回,就不用去数据库了,从而减少了数据库压力提高了性能
注意事项与一级缓存一致

二级缓存小结:
○ MyBatis的二级缓存相对于一级缓存来说,实现了SqlSession之间缓存数据的共享,同时粒度更加的细,能够到namespace级别,通过Cache接口实现类不同的组合,对Cache的可控性也更强。
○ MyBatis在多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用二级缓存的条件比较苛刻。
○ 在分布式环境下,由于默认的MyBatis Cache实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将MyBatis的Cache接口实现,有一定的开发成本,直接使用Redis,Memcached等分布式缓存可能成本更低,安全性也更高。
意思就是,在分布式环境下面,一般不会使用myBatis缓存,因为如果要安全使用,这样开发成本更高,直接使用Redis会更好。

当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。

五、Mybatis的事务管理分为两种方式

1)使用JDBC的事务管理机制,就是利用java.sql.Connection对象完成对事物的提交。
2)使用Managed的事务管理机制,这种机制MyBatis自身不会去实现事务管理,而是让程序的容器来实现对事务的管理。

java框架-Mybatis的更多相关文章

  1. java框架---->mybatis的使用(一)

    这里我们记录一些mybatis的一些常用知识和项目中遇到的问题总结.快乐人生的三个必要元素是,有要做的事.热爱的事及盼望的事. mybatis的一些知识 一.mybatis插入返回主键值 插入的jav ...

  2. Java框架-MyBatis三剑客之MyBatis Generator(mybatis-generator MBG插件)详解

    生成器设计思路: 连接数据库 -> 获取表结构 -> 生成文件 1 下载与安装 官网文档入口 最方便的 maven 插件使用方式 贴至pom 文件 2 新建配置文件 填充配置信息(官网示例 ...

  3. 详解Java的MyBatis框架中SQL语句映射部分的编写

    这篇文章主要介绍了Java的MyBatis框架中SQL语句映射部分的编写,文中分为resultMap和增删查改实现两个部分来讲解,需要的朋友可以参考下 1.resultMap SQL 映射XML 文件 ...

  4. 【JAVA框架】Hibernate 与Mybatis 区别

    Hibernate Mybatis 简介 区别 与联系 欢迎提出见解及转载. 1 简单简介     1.1    Hibernate 框架          Hibernate是一个开放源代码的对象关 ...

  5. 转 分享我在阿里工作十年接触过Java框架设计模式

    转 原文: 分享我在阿里工作十年接触过Java框架设计模式 一.前言 说起来设计模式,大家应该都耳熟能详,设计模式代表了软件设计的最佳实践,是经过不断总结提炼出来的代码设计经验的分类总结,这些模式或者 ...

  6. 杂项-Java:MyBatis

    ylbtech-杂项-Java:MyBatis 1.返回顶部 1. MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundatio ...

  7. Java自学路线图之Java框架自学

    Java自学路线图的框架分为两个阶段,第一阶段的Java框架包含六个内容:MyBatis,Spring,SpringMVC,Maven高级,Git,Dubbo. 在Java自学过程中掌握框架的使用,对 ...

  8. 程序员必须掌握的Java 框架,小白学会之后15k不是问题

    Spring 的核心特性是什么?Spring 优点? Spring 的核心是控制反转(IoC)和面向切面(AOP) Spring 优点: 程序员必须掌握的Java 框架,学会之后50k不是问题 (1) ...

  9. 一个C#开发编写Java框架的心路历程

    前言 这一篇絮絮叨叨,逻辑不太清晰的编写Java框架的的一个过程,主要描述我作为一个java初学者,在编写Java框架时的一些心得感悟. 因为我是C#的开发者,所以,在编写Java框架时,或多或少会带 ...

随机推荐

  1. Docker最全教程——从理论到实战(二十)

    前言 各种编程语言均有其优势和生态,有兴趣的朋友完全可以涉猎多门语言.在平常的工作之中,也可以尝试选择相对适合的编程语言来完成相关的工作. 在团队技术文档站搭建这块,笔者尝试了许多框架,最终还是选择了 ...

  2. JS 获取验证码 倒计时

    setInterval 一个定时器搞定 <style> button{ background: #45BCF9; color: #fff; padding: 4px 10px; borde ...

  3. Spring5源码阅读环境搭建-gradle构建编译

      前沿:Spring系列生态十分丰富,涉及到各个方面.但是作为Spring生态的核心基础Spring,是最重要的环节,需要理解Spring的设计原理,我们需要解读源码.   在构建Spring源码阅 ...

  4. 2019-08-17 纪中NOIP模拟B组

    T1 [JZOJ3503] 粉刷 题目描述 鸡腿想到了一个很高(sha)明(bi)的问题,墙可以看作一个N*M的矩阵,有一些格子是有污点的.现在鸡腿可以竖着刷一次,覆盖连续的最多C列,或者横着刷一次, ...

  5. msfconsole启动失败并报错`not_after=': bignum too big to convert into `long'的解决方法

    1.启动msfconsole失败并报如下错误: /usr/share/metasploit-framework/lib/msf/core/payload/android.rb:86:in `not_a ...

  6. Go键盘输入与打印输出

    输出 格式化打印占位符 符号 说明 %v 默认格式 %T 打印类型 %t 布尔类型 %s 字符串 %f 浮点数 %d 十进制的整数 %b 二进制的整数 %o 八进制 %x 十六进制0-9 a-f %X ...

  7. 部署prerender服务器

    // 安装 git sudo apt-get install git sudo apt-get install curl // 请先确认服务器是否安装了curl 如果已经安装跳过即可 // 安装 no ...

  8. [一本通学习笔记] AC自动机

    AC自动机可以看作是在Trie树上建立了fail指针,在这里可以看作fail链.如果u的fail链指向v,那么v的对应串一定是u对应串在所给定字符串集合的后缀集合中的最长的后缀. 我们考虑一下如何实现 ...

  9. manifold learning

    MDS, multidimensional scaling, 线性降维方法, 目的就是使得降维之后的点两两之间的距离尽量不变(也就是和在原是空间中对应的两个点之间的距离要差不多).只是 MDS 是针对 ...

  10. 2017-12-08 违法数据筛选.sql

    SELECT R. ID, R.LKBH, R.CDBH, R.FXBH, R.ZJBH, R.SBBH, R.CPHM, R.CPYSBH, R.CPYS, R.CSYSBH, R.CSYS, R. ...