面试官:你剖析过mybatis作业原理吗?

今日头条 · 2019-03-27
作者:皮皮哥 
大众号:Java知音


Mybatis作业原理也是面试的一大考点,有必要要对其十分明晰,这样才干怼回去。本文建立在Spring+SpringMVC+Mybatis整汤盈盈老公合的项目之上。

我将其作业原理分为六个部分:

  1. 读取中心装备文件并回来InputStream流目标。
  2. 依据InputStream流目标解分出Configuration目标,然后创立SqlSessionFactory工厂目标
  3. 依据一系列特点从SqlSessionFactory工厂中创立SqlSession
  4. 从SqlSession中调用Executor履行数据库操作&&生成详细SQL指令
  5. 对履行成果进行二次封装
  6. 提交与业务

先给咱们看看我的实体类:

1. 读取中心装备文件

1.1 装备文件mybatis-config.xml

当然,还有许多能够在XML 文件中进行装备,上面的示例指出的则是最要害的部分。要留意 XML 头部的声明,用来验证 XML 文档正确性。environment 元素体中包括了业务管理和衔接池的装备。mappers 元素则是包括一组 mapper 映射器(这些 mapper 的 XML 文件包括了 SQL 代码和映射界说信息)。

1.2 BookMapper.xml



PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">



insert into book (name,number) values (#{name},#{number})


便是一个一般的mapper.xml文件。

1.3 Main办法

从 XML 文件中构建 SqlSessionFactory 的实例十分简略,主张运用类途径下的资源文件进行装备。可是也能够运用恣意的输入流(InputStream)实例,包括字符串方式的文件途径或许 file:// 的 URL 方式的文件途径来装备。

MyBatis 包括一个名叫 Resources 的东西类,它包括一些有用办法,可使从 cla面试官:你分析过mybatis作业原理吗?sspath 或其他方位加载资源文件愈加简单。

这个代码是依据Mybatis官方供给的一个不运用 XML 构建 SqlSessionFactory的一个Demo改编的。

留意:是官方给的一个不运用 XML 构建 SqlSessionFactory的比如,那么咱们就从这个比如中查找进口来分析。

2. 依据装备文件生成SqlSessionFactory工厂目标

2.1 Resources.getResourceAsStream(re中星微大厦source);源码分析

Resources是mybatis供给的一个加载资源文件的东西类。

值的留意的是,它回来了一个InputStream目标。

2.2 new SqlSessionFactoryBuilder().build(inputStream);源码分析

public SqlSessionFactoryBuilder() {
}

所以new SqlSessionFactoryBuilder()仅仅创立一个目标实例,而没有目标回来(缔造者形式),目标的回来交给build()办法。

public SqlSessionFactory build(InputStream inputStream) {
return this.build((InputStream)inputStream, (String)null, (Properties)null);
}

这儿要传入一个inputStream目标,便是将咱们上一步获取到的面试官:你分析过mybatis作业原理吗?InputStream目标传入。

如解东霞何解析的就大约说下,经过Document目标来解析,然后回来InputStream目标,然后交给XMLConfigBuilder构形成org.apache.ibatis.session.Configuration目标,然后交给build()办法结构程S面试官:你分析过mybatis作业原理吗?qlSessionFactory:

public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
public DefaultSqlSessionFactory(Configuration configuration) {
this.configuration =迪克牛仔女儿 configuration;
}

3. 创立SqlSession

SqlSession 彻底包括了面向数据库履行 SQL 指令所需的一切办法。你能够经过 SqlSession 实例来直接履行已映射的 SQL 句子。

public SqlSession openSession() {
return this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), (TransactionIsolationLevel)null, false);
}

调用自身的openSessionFromDataSource办法:

  1. getDefaultExecutorType()默许是SIMPLE。
  2. 留意TX等级是 Null, autoCommit是false。

构建过程:

Environment>>TransactionFactory+autoCommit+tx-level>>Transaction+ExecType>>Executor+Configuration+autoCommit>>SqlSession

其间,Environment是Configuration中的特点。

4. 调用Executor履行数据库操作&&生成详细SQL指令

在拿到SqlSession对伟人卡里和姚明合照象后,咱们调用它的insert办法。

public int insert(String state洛克王国白居易ment, Object parameter) {
return this.update(statement, param五华县横陂中学eter);
}

它调用了自身的update(statement, parameter)办法:

ma古董梦ppedStatements便是咱们平常说的sql映射目标.

源码如下:

protected final Map mappedStatements;

可见它是一个Map调集,在咱们加载xml装备的时分,mapping.xml的namespace和id信息就会寄存为mappedStatements的key,对应的,sql句子便是对应的value.

然后调用BaseExecutor中的update办法:

public i总裁的3嫁娇妻nt update(MappedStatement ms, Object parameter) throws SQLException {
ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());
if (this.closed) {
throw new ExecutorException("Executor was closed.");
} else {
this.clearLocalCache();
// 真实做履行操作的办法
return this.doUpdate(ms, pec精英社arameter);
}
}

doUpdate才是真实做履行操作的办法:

public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
Statement stmt = null;
int var6;
try {
Configur五等汉ation configu面试官:你分析过mybatis作业原理吗?ration = ms.getConfiguration();
// 创立StatementHandler目标,然后创立Statement目标
StatementHandler handler = configuration.newStatementHandler(this, 面试官:你分析过mybatis作业原理吗?ms, parameter, RowBounds.DEFAULT, (ResultHandler)null, (BoundSql)null);
// 将sql句子和参数绑定并生成SQL指令
stmt = this.prepareStatement(handler, ms.getStatementLog());
面试官:你分析过mybatis作业原理吗?var6 = handler.update(stmt);
} finally {
this.closeStatement(stmt);
}
return var6;
}

先来看看prepareStatement办法,看看mybatis是如何将sql拼接组成的:

private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
Connection connection = this.getConnection(statementLog);
/scc鹏鹏/ 预备Statement
Statement stmt = handler.prepare(connection);
// 设置SQL查询中的参数值
handler.parameterize(stmt);
return stmt;
}

来看看param欧阳凤eterize办法:

public void parameterize(Statement statement) throws SQLException {
this.parameterHandler.setParameters((PreparedStatement)statement);
}

这儿把statement转化程PreparedStatement目标,它比Statem面试官:你分析过mybatis作业原理吗?ent更快更安全。

这都是咱们在JDBC中熟用的目标,就不做介绍了,所以也能看出来Mybatis是对JDBC的封装。

从ParameterMapping中读取参数值和类污污污型,然后设置到SQL句子中:

5. 对查询成果二次封装

在doUpdate办法中,解析生成完新的SQL后,然后履行var6 = handler.update(stmt);咱们来看看它的源码。

由于咱们是刺进操作,回来的是一个int类型的值,所以这儿mybatis给咱们直接回来int。

假如是query操作,回来的是一个ResultSet,mybatis将查询成果包装程ResultSetWrapper类型,然后一步步对应java类型赋值等…有爱好的能够自己去看看。

6. 提交与业务

最终,来看看commit()办法的源码。

public void co四川飞普科技有限公司mmit() {
this.commit(false);
}

调用其目标自身的commit()办法:

public void commit(boolean force) {
try {
// 是否提交(判别是提交仍是回滚)
this.executor.commit(this.isCommitOrRollbackRequired(force));
this.dirty = false;
} catch (Exception var6) {
throw ExceptionFactory.wrapException("Error committing transaction. Cause: " + var6, var6);
} finally {
ErrorContext.颛孙永刚instance().reset();
}
}

假如dirty是false,则进行回滚;假如是true,则正常提交。

private boolean isCommitOrRollbackRequired(boolean force) {
return !thi九趣英语s.autoCommit && this.dirty || force;
}

调用CachingExecutor的commit办法:

public void commit(b罗德西亚背脊犬oolean required) throws SQLException {
this.delegate.commit(required);
this.tcm.commit();
}

调用BaseExecutor的co张付川mmit办法:

public void commit(boolean required) throws SQLException {
if (this.closed) {
throw new ExecutorException("Cannot commit, transaction is already closed");
} else {
this.clearLocalCache();
this.flushStatements();
if (required) {
this.transaction.commit();
}
}
}

最终调用JDBCTransaction的commit办法:

public void commit() throws SQLException {
if (this.connection != null && !this.connection.getAutoCommit()) {
if (log.isDebugEnabled()) {
log.debug("Committing JDBC Connection [" + this.connection + "]");
}
// 提交衔接
this.connection.commit();
}
}

Demo参阅文档

http://www.mybatis.org/mybatis-3/zh/getting-started.html

34张架构史上最全技术知识图谱

文章推荐:

雷神笔记本,怀化又知名了!最适合养老的20座城市,怀化居然排榜首,抚顺天气预报

敢死队,青训 | 立久远,久久为功!沙叶青训夏日走训班敞开报名,全民

美竹铃,5分钱跑1km,起价格仅5.99万,比亚迪最廉价的纯电动车来了!,风景图片

一击男,19款捷豹XFL来袭,内饰奢华感十足,动力还发生了很大改动,奥硝唑

爱的代价,2019上海车展重磅新车&高性能新车抢先看,rapper

文章归档