MyBatis相关

210 阅读3分钟

MyBatis编程步骤是什么样的?

  1. 通过SqlSessionFactory来获取SqlSession对象
  2. 通过SqlSession对象来执行相应数据库事务
  3. SqlSession提交事务
  4. 关闭SqlSession会话

**请说说MyBatis的工作原理 **

  1. 首先通过XMLConfigBuilder对我们配置的XML文件进行解析并生成Configuration对象,然后生成一个SqlSessionFactory对象
  2. 通过SqlSessionFactory的openSession方法创建Sqlsession对象
  3. 使用SqlSession来完成数据库的交互
    • 通过Configuration对象中的mapperRegister获取对应接口方法并为其生成一个代理对象来执行方法
    • SqlSession是通过执行器Executor来调度StatementHandler运行的,数据库语句处理有以下几步
      1. prepared预编译Sql,获取数据库连接,设置超时等待,最大行数等基本参数
      2. parameterize参数化Sql,将我们输入的参数通过Typehandler转换成jdbcType进行参数设置
      3. query/update执行Sql
    • 通过resultHandler来处理结果集

**MyBatis的功能架构是怎样的 **

  1. 基础支持层: 负责最基础的功能支撑,包括连接管理事务管理配置加载缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的核心处理层提供最基础的支撑。
  2. 核心处理层: 负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
  3. 接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。

框架架构设计

  1. 加载配置:通过配置文件或者注解将SQL的配置信息加载成一个MappedStatement对象(包括sql语句,参数映射配置,结果映射配置)
  2. SQL解析:Mybatis根据调用请求中的‘id’来获取对应的MappedStatement对象,根据传入的参数对Sql语句进行预编译和参数设置
  3. SQL执行:将最终得到的SQL语句交给数据库进行执行
  4. 将数据库返回的结果按照映射配置要求进行转换并返回结果

为什么需要预编译

mybatis执行预编译分如下三步:

  1. 执行预编译语句,获取数据连接,设置超时等待,最大行数
  2. 设置变量
  3. 执行语句

预编译的好处:

  • 防止SQL注入,经过预编译后SQL语句结构已经定了下来,只能输入参数进去无法改变其结构
  • 经过预编译后只用对SQL语句进行一次语义校验和编译操作,节约时间(得开启缓存,在url中指定cachePrepStmts=true )

Mybatis都有哪些Executor执行器?它们之间的区别是什么?

Mybatis mapper.xml怎么对应于方法

生成SqlSession对象前的build()方法中,生成configuration对象时会去解析节点下的节点

它会去解析缓存配置,输入参数设置,结果参数设置等节点

这里将statement对象与namespace+id添加进了mappedStatements这个map容器中,这样sql语句就与接口的方法唯一确定了

mybatis的$存在安全问题,为什么又不得不用?

mybatis中#与$的不同之处在于

在prepareStatement方法中,在进行handler.parameterize方法(预处理)前,参数设置处会由?来充当占位符,这是#

而$在进行handler.parameterize方法前,参数就已经被设置了,这样容易遭到sql注入攻击,降低系统安全。

#与的区别最大在于:#{} 传入值时,sql解析时,参数是带引号的,而{}穿入值,sql解析时,参数是不带引号的

有些场景比如orderBy,in等#{}无法使用比如

SELECT * FROM #{tableName}

输入user后

${}主要用于我们确定值的情况下使用。

Mybatis一二级缓存

Mybatis一级缓存,默认开启,产生的效果仅限于同一SqlSession以及一次会话中。

Mybatis配置二级缓存的前提:pojo类必须实现序列化 二级缓存配置选项

(本文仅用于记录平时个人学习心得,如有误导恳请指教)