Mybatis八股文

103 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1. 说说Mybatis的三层

MyBatis主要分为三层:接口层,数据处理层与基础层

接口层是通过提供的API作为数据库进行增/删/改/查,都是MyBatis的API。提供主要用的两个接口:

  • SqlSessionFactory:它是通过configration构造的接口对象,然后通过该接口对象构造SqlSession对象。
  • SqlSession:作用是提供加载映射文件中的mapperstatement对象。并提供增删改查的方法

数据处理层是SQL预处理、SQL执行、结果映射。

  • SQL预处理:是对代码里的变量进行绑定,以及动态SQL生成
  • SQL执行:是把生成好的SQL,通过JDBC驱动,传到对应的DB里执行,而且要负责网络通信的部分
  • 结果映射:是把数据库返回的结果从关系型数据转换成Java对象数据。

基础层包括日志、事务管理、缓存、连接池、动态代理、配置解析。

  • 日志:是做框架里面的日志输出以及SQL语句输出
  • 事务管理:是对 JDBC事务、数据库事物做管理;
  • 缓存:能够把结果集缓存在JVM的内存。优点是比较快,缺点是会占用堆内存。实际上一般使用Redis这样的中间件来做分布式缓存
  • 连接池:能够加速查询,提高性能
  • 动态代理:在用MyBatis编程时,核心是通过接口执行数据库查询。而Mapper接口本身是没有实现的,通过注解或者XML配置SQL语句,动态代理会在运行时生成代理,当调用Mapper接口时,转换成实际的SQL语句
  • 配置解析:因为MyBatis里面有存在大量配置,需要配置新模块,读取XML配置,并把它映射为配置属性。

2. Mybatis的映射过程

加载sql语句,获取表中数据然后将数据返回给结果集,从结果集中获取数据(取出每个字段),通过构造器给对象赋值

3. Mybatis的事务管理类型

  • 原生JDBC,对应的事务相关操作都由mybatis内置的JdbcTransaction来完成,
  • MANAGED,对事务的管理是一个空实现,将事务管理交给外部容器,例如交给Spring来实现,

无论是哪种方式,都是使用jdk利用数据库的Connection来提供管理事务的能力,都是一层一层的封装进行委派最终由Connection的具体数据库驱动来进行实现的

4. Mybatis的数据源

POOLED:采用传统的javax.sql.DataSource规范中的连接池,对连接进行了缓存

UNPOOLED:采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用池的思想

JNDI:采用服务器提供的JNDI技术实现,来获取DataSource对象,通过JNDI上下文中取值

5. 连接池思想

创建一个Conncection代价是巨大的,因为创建了一个连接,在底层就与数据库建立了通信连接,

  • TCP 建立连接 三次握手
  • MySql 认证的 三次握手
  • SQL 的执行
  • MySql 的关闭
  • TCP 的 四次握手 关闭连接

网络IO较多,数据库的负载较高、应用频繁的创建连接和关闭连接,导致临时对象较多,GC频繁,所以说是非常消耗资源的操作,从用户的角度来讲,导致响应时间较长以及QPS较低 ,而为数据库建立一个“连接池”,预先创建一定数量的连接,当需要连接时,只需从中取出一个,使用完毕之后再放回,避免了连接随意建立和关闭造成的系统开销。

6. 连接池原理

服务器启动时会建立一定数量的池连接,并一直维持不少于此数目的池连接。
客户端程序需要连接时,池驱动程序会返回一个未使用的池连接并将其表记为忙。
如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量由具体的配置参数决定。
当使用的池连接调用完成后,池驱动程序将此连接表记为空闲,其他调用就可以使用这个连接。

7. Mybatis是怎么将mapper与xml联系起来的

当加载映射文件时,会将每个sql标签加载成不同的MapperStatement对象。MapperStatement对象的id = namespace(接口的全限定名) + mapper的方法名,在MyBatis中,每一个< select>、< insert>、< update>、< delete>标签都会被解析为一个MapperStatement对象