栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

一文看懂mybatis底层运行原理解析,java程序设计教程第三版答案百度网盘

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

一文看懂mybatis底层运行原理解析,java程序设计教程第三版答案百度网盘

接口对应的 DataDao.xml:

insert into ${tableName}

(${columns})

values

(${colValues})

首先我们会从mybatis的入口加载的地方来进行解读,先看一段mybatis的插入代码:

public static int mysqlInsert(Map map) throws Exception {

SqlSession session = null;

int index=0;

try {

session = SessionFactory.getSession();

DataDao dataDao = session.getMapper(DataDao.class);

index=dataDao.mysqlInsert(map);

if(index>0){

logger.info("insert success: "+index);

}

session.commit(true);

} catch (Exception e) {

logger.error(“插入异常:”, e);

session.rollback(true);

throw e;

} finally {

session.close();

}

return index;

}

public class SessionFactory {

private static Logger logger = LoggerFactory.getLogger(SessionFactory.class);

private static SqlSessionFactoryBuilder sqlSessionFactoryBuilder;

private static SqlSessionFactory sqlSessionFactory;

//初始化mybatis

static {

String resource = “mybatis-config.xml”;

Reader reader = null;

try {

reader = Resources.getResourceAsReader(resource);

sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();

sqlSessionFactory = sqlSessionFactoryBuilder.build(reader);

} catch (IOException e) {

logger.error(“加载配置文件错误:”,e);

e.printStackTrace();

}catch (Exception e){

logger.error(“加载配置文件错误:”,e);

}

logger.info(“init mybatis”);

}

public static synchronized SqlSession getSession() throws IOException {

SqlSession sqlSession =null;

if(null == sqlSession) {

sqlSession = (null != sqlSessionFactory)?sqlSessionFactory.openSession(): null;

}

return sqlSession;

}

}

代码中可以看到首先会通过  SessionFactory 去获取 SqlSession,里面会有一段static代码,在SessionFactory类加载时会执行mybatis-config.xml 的初始化过程。现在我们直接看重点:

通过SqlSession 的 getMapper获取DataDao数据接口的时候发现有2个实现,追溯到SessionFactory的初始化中会看到下面一段:

所以我们直接进入 DefaultSqlSession getMapper方法中,可以找到 MapperRegistry 中:

看到这里熟悉的动态代理的朋友知道这是一个获取java的动态代理类的写法(ps: 不熟悉动态代理的,可以看这里我的上一篇博客 动态代理白话解析),我们继续往下看:

继续走到下一步:dataDao.mysqlInsert(map); 执行这个方法时会调用 MapperProxy 的 invoke方法:

开源看到除了Object 中的方法不能代理,其他的都会走到 mapperMethod.execute(args):

type 字段会在mapperMethod初始化时赋值,这里我们执行的insert,继续往下走到DefaultSqlSession 的update方法 :

到这里后,接下来我们开始看 Configuration的初始化,它在SqlSessionFactory初始化时构造的

上面2段代码可以看到 Configuration 是通过加载mybatis-config.xml时进行初始化的。

现在我们回到 this.configuration.getMappedStatement(statement); 这段代码:

进去看下我们发现他其实是通过 id 去获取对应的MappedStatement ,通过上文我们可以知道id是MapperMethod的execute方法传进来的commandName,它在MapperMethod 的构造函数中的 setupFields 方法中初始化:

在本文中的值为: DataDao.mysqlInsert。类似这种,也就是接口类.方法名。

现在我们回到主流程中,查看 mappedStatements 的初始化过程,是在上文中初始化Configuration 的this.mapperElement(root.evalNode(“mappers”)); 中  :

这里会解析mapper.xml中的sql节点,本文中的示例是 这一段:

我们继续查看mappedStatements的初始化 :

这里的id我们可以看到就是节点中的namespace.id的值拼接,也就是 DataDao.mysqlInsert

现在我们继续回到主流程,看这段代码:

代码中通过executor执行update方法,现在我们看下 executor 的初始化过程,是在SqlSession初始化的过程中:

在Configuration的构造函数中可以看到这里的 executorType 默认为SIMPLE,cacheEnabled 默认为true.

现在我们继续回到主流程,进到 CachingExecutor 的 update 方法中:

这里会进入到 baseExecutor 的 update方法中

![](https://img-blog.csdnimg.cn/20190604160333640.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGV

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

pdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1JveWFsX2xy,size_16,color_FFFFFF,t_70)

这里会进入到 SimpleExecutor 的doUpdate中:

这里首先初始化了一个 RoutingStatementHandler ,由上文可知 statementType 默认为 PREPARED,所以 其 delegate 属性为 PreparedStatementHandler。我们回到主流程,继续看  this.prepareStatement(handler) :

会走到 baseStatementHandler 的 prepare 方法 :

这里会进入到 PreparedStatementHandler 的 instantiateStatement 方法:

这里的 boundSql 是在 上文中的 mappedStatement 初始化的时候赋值的:

首先是在 parseStatementNode 中初始化 DynamicSqlSource,然后获取 BoundSql,接下来我们看下XMLStatementBuilder的parseDynamicTags方法:

代码中我们可以看到若节点类型既不是文本节点也不是CDATA节点就会调用不同的处理类去处理,我们比较常用的就是查询时使用的 和 节点 ,这里我们执行的是 insert , 所以直接是一个文本节点,下面就是初始化了一个MixedSqlNode 和 configuration 构造了 DynamicSqlSource,然后通过getBoundSql 方法来构造BoundSql:

由上文知:rootSqlNode是MixedSqlNode,这里会执行 MixedSqlNode 的 apply 方法,在本例中会执行 TextSqlNode 的 apply

方法:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/658881.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号