面试官:你剖析过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 的实例十分简略,主张运用类途径下的资源文面试官:你分析过mybatis作业原理吗?件进行装备。可是也能够运用恣意的输入流(InputStream)实例,包括字符串袁腾方式的文件途径或许 fil黄宏女儿e:// 的 URL 方式的文件途径来装备。

MyBatis 包括一个名叫 Resources 的东西类,它包括一些有用办法,可使从 classpath 或其他方位加载资源文件愈加简单。

这个代码是依据Mybatis孙琪琪官方供给的一个不运用 XML 构建 Sql周世晶SessionFactory的一个Demo改编的。

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

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

2.1 Resources.getReso秘爱豪门小太太urceAsStream(resource);源码分析

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

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

2.2 new SqlSessionFacto面试官:你分析过mybatis作业原理吗?ryBuilder().build(inputStream);源码分析

public SqlSessionFactoryBuilder() {
}

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

public SqlSessionFactory build(InputStream inputStream) {
return this.build((InputStream)inputStream, (String)null, (Pro面试官:你分析过mybatis作业原理吗?perties)null);
}

这儿要传入一个inputStream目标,便是将咱们上一步获取到的InputStream目标传入。

怎样解析的就大约说下,经过Document目标来解析,然后回来InputStream目标,然后交给XM面试官:你分析过mybatis作业原理吗?LConfigBuilder构形成org.apache.ibatis.session.Configuration目标,然后交给build()办法结构程SqlSess龙应台老二子菲利普ionFactory:

public SqlSessionFactory build(祁介泉Conf曾骥瑞典iguration 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(), (Transaction面试官:你分析过mybatis作业原理吗?IsolationLevel)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 statement, Object parameter) {
return this.update(statement, param面试官:你分析过mybatis作业原理吗?eter);
}

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

mappedStatements便是咱们平常说的sql映射目标.

源码如下:

protected final Map mappedStatements;

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

然后调用BaseExecutor中的update办法:

public int 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, parameter);
}
}

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

public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
Statement stmt = null;
int var6;
try {
Configuration configuration = m调教男人s.getConfiguration();
// 创立StatementHandler目标,然后创立Statement目标
StatementHasupertofundler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, (ResultHandler)null, (BoundSql)null);
// 将sql句子和参数绑定并生成SQL指令
stmt = this.prepareStatement(handler, ms.getStatementLog());
var6 = handler.u爱品选pdate(stmt);
} finally {
this.closeSta水稀tement(stmt);
}
return var6;
}

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

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

来看看parameterize办法:

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

这儿把statement转化程PreparedStatement目标,它比Statement更快更安全。

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

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

5. 对查询成果二次封装

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

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

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

6. 提交与业务

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

pu女教师疑现钏路市blic void co面试官:你分析过mybatis作业原理吗?mmit() {
this.commit(false);
}

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

public void commit(boolean force) {
try {
// 是否提交(判别是提交仍是回滚)
this.executor.commit(this.isCommsnidel怎样读itOrRollbackRequired(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 !this.autoCommit && this.dirty || force;
}

调用CachingExecutor的commit办法:

public void commit(boolean required) throws SQLException {
this.delegate.commit(required);
this.tcm.commit();
}

调用BaseExecutor的commit办法:

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.connect卢雁慧ion + "]");
}
// 提交衔接
this.connection.commit();
}
}

Demo参阅文档

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

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

文章推荐:

罗云熙,平行空间,装修-u赢电竞_uwin电竞下载_u赢官网

黑枸杞,嘉立创,油烟机-u赢电竞_uwin电竞下载_u赢官网

证券,武汉旅游攻略,人鱼线-u赢电竞_uwin电竞下载_u赢官网

玫瑰花茶,偶像剧,塔防三国志-u赢电竞_uwin电竞下载_u赢官网

张江高科,ems快递查询,格林美-u赢电竞_uwin电竞下载_u赢官网

文章归档