Mybaits加载执行该xml配置

class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean

spring 在初始化 sqlsessionbean的时候通过createBean调用了在SqlSessionFactoryBean中实现了接口InitializingBean的afterPropertiesSet()方法在该方法中调用了buildSqlSessionFactory()开始创建SqlSessionFactory

buildSqlSessionFactory()方法完成以下功能

一:

a)    创建configuration

b)    typeAliasesPackage

c)    typeAliases TYPE_ALIASES将类型存放到此map里面同b

d)    plugins configuration添加插件

e)    typeHandlersPackage

f)    typeHandlers

g)    xmlConfigBuilder.parse()将所有的配置从xml中读取并放入到对应的变量里面

h)    mapperLocations

二:xmlMapperBuilder.parse()——> configurationElement

a)    parameterMapElement(context.evalNodes("/mapper/parameterMap"));将mapper.xml中的prameterMap节点的数据添加到configuration.parameterMaps中

b)    resultMapElements(context.evalNodes("/mapper/resultMap"));将mapper.xml中的resultMap节点的数据添加到configuration.incompleteResultMaps中

c)    sqlElement(context.evalNodes("/mapper/sql"));

d)    buildStatementFromContext(select|insert|update|delete);buildStatementFromContext:从mapper 中获取sql语句,执行类型(增删改查),parseStatementNode中addMappedStatement创建每个mapper对应的方法创建MappedStatement并添加到 configuration.mappedStatements.put(com.qb.mysql.dao.TRoleDao.getUserRoleByRid, MappedStatement)

最后返回了一个 DefaultSqlSessionFactory(config)

在调用SqlSessionTemplate进行dao层操作时,其会将工作委托给sqlSessionProxy属性进行,而sqlSessionProxy在进行相关method调用时,用到了JDK动态代理机制,首先SqlSessionUtils.getSqlSession获取sqlSession

 private class SqlSessionInterceptor implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//返回一个DefaultSqlsession
SqlSession sqlSession = getSqlSession(
SqlSessionTemplate.this.sqlSessionFactory,
SqlSessionTemplate.this.executorType,
SqlSessionTemplate.this.exceptionTranslator);
try {
//调用该类的MapperProxy的invoke方法
Object result = method.invoke(sqlSession, args);
if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
// force commit even on non-dirty sessions because some databases require
// a commit/rollback before calling close()
sqlSession.commit(true);
}
return result;
} catch (Throwable t) {
Throwable unwrapped = unwrapThrowable(t);
if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
// release the connection to avoid a deadlock if the translator is no loaded. See issue #22
closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
sqlSession = null;
Throwable translated = SqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException) unwrapped);
if (translated != null) {
unwrapped = translated;
}
}
throw unwrapped;
} finally {
if (sqlSession != null) {
closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
}
}
}
}
在getSqlSession方法中创建事务,创建Executor,默认创建SimpleExecutor;InterceptorChain添加拦截器 InterceptorChain.pluginAll()

SqlSessionTemplate ->SqlSessionInterceptor->SqlSessionUtils. getSqlSession()->(defaultsqlsessionfactory)sessionFactory.openSession()->openSessionFromDataSource()

MapperProxy的invoke方法的方法
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
}
final MapperMethod mapperMethod = cachedMapperMethod(method);
//执行execute
return mapperMethod.execute(sqlSession, args);
}
//根据sql类型选择对应的方法
public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
if (SqlCommandType.INSERT == command.getType()) {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.insert(command.getName(), param));
} else if (SqlCommandType.UPDATE == command.getType()) {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.update(command.getName(), param));
} else if (SqlCommandType.DELETE == command.getType()) {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.delete(command.getName(), param));
} else if (SqlCommandType.SELECT == command.getType()) {
if (method.returnsVoid() && method.hasResultHandler()) {
executeWithResultHandler(sqlSession, args);
result = null;
} else if (method.returnsMany()) {
result = executeForMany(sqlSession, args);
} else if (method.returnsMap()) {
result = executeForMap(sqlSession, args);
} else {
Object param = method.convertArgsToSqlCommandParam(args);
result = sqlSession.selectOne(command.getName(), param);
}
} else {
throw new BindingException("Unknown execution method for: " + command.getName());
}
if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
throw new BindingException("Mapper method '" + command.getName()
+ " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
}
return result;
}

SqlSessionTemplate 执行了创建sqlsession,openSqlsession,执行sql,closeSqlsession

Mybatis的SqlSession理解(二)的更多相关文章

  1. Mybatis的SqlSession理解(一)

    SqlSession是Mybatis最重要的构建之一,可以认为Mybatis一系列的配置目的是生成类似JDBC生成的Connection对象的statement对象,这样才能与数据库开启“沟通”,通过 ...

  2. Mybatis源码解析(二) —— 加载 Configuration

    Mybatis源码解析(二) -- 加载 Configuration    正如上文所看到的 Configuration 对象保存了所有Mybatis的配置信息,也就是说mybatis-config. ...

  3. Java数据持久层框架 MyBatis之背景知识二

    对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...

  4. MyBatis基础入门《二》Select查询

    MyBatis基础入门<二>Select查询 使用MySQL数据库,创建表: SET NAMES utf8mb4; ; -- ---------------------------- -- ...

  5. mybatis 学习笔记(二):mybatis SQL注入问题

    mybatis 学习笔记(二):mybatis SQL注入问题 SQL 注入攻击 首先了解下概念,什么叫SQL 注入: SQL注入攻击,简称SQL攻击或注入攻击,是发生于应用程序之数据库层的安全漏洞. ...

  6. (转)MyBatis框架的学习(二)——MyBatis架构与入门

    http://blog.csdn.net/yerenyuan_pku/article/details/71699515 MyBatis框架的架构 MyBatis框架的架构如下图: 下面作简要概述: S ...

  7. 用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建二:配置MyBatis 并测试(2 配置spring-dao和测试)

    用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建二:配置MyBatis 并测试(1 搭建目录环境和依赖) 四:在\resources\spring 下面 ...

  8. 用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建二:配置MyBatis 并测试(1 构建目录环境和依赖)

    引言:在用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建一   的基础上 继续进行项目搭建 该部分的主要目的是测通MyBatis 及Spring-dao ...

  9. Springboot & Mybatis 构建restful 服务二

    Springboot & Mybatis 构建restful 服务二 1 前置条件 成功执行完Springboot & Mybatis 构建restful 服务一 2 restful ...

随机推荐

  1. 怎样从外网访问内网Jboss?

    本地安装了一个Jboss,只能在局域网内访问,怎样从外网也能访问到本地的Jboss呢?本文将介绍具体的实现步骤. 准备工作 安装并启动Jboss 默认安装的Jboss端口是8080. 实现步骤 下载并 ...

  2. Maven项目启动报错:org.springframework.web.filter.CharacterEncodingFilter cannot be cast to javax.servlet.Filter

    看网上说法tomcat启动时会把lib目录下的jar包加载进内存,而项目里也有相同的jar包就会导致jar包冲突 解决办法: 把pom依赖里相应的jar包添加<scope>标签 <d ...

  3. 在win10下安装eclipse

    1.在官网下载jdk.目前最新版本为jdk8. http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-21331 ...

  4. ssh-keygen 命令

    功能 生成.管理和转换认证密钥,包括 RSA 和 DSA 两种密钥,密钥类型可以用 -t 选项指定.如果没有指定则默认生成用于SSH-2的RSA密钥,系统管理员还可以用它产生主机密钥. 通常,这个程序 ...

  5. C#实现根据地图上的两点坐标,计算直线距离

    根据地图上的两点坐标,计算直线距离,在网上找到javascript的写法,用C#实现一下 /// <summary> /// 根据地图上的两点坐标,计算直线距离 /// </summ ...

  6. CAN通信工作原理个人心得

    CAN总线结构示意图: 说明: 1:CAN收发器(示意图中的单元)根据两总线CAN_H和CAN_L的电位差来判断总线电平: 2:实际中CAN_H与CAN_L由双绞线组成: 3:数据传递终端的电阻器,是 ...

  7. 流程控制if,while,for

    if语句 什么是if语句 判断一个条件如果成立则做...不成立则做....为何要有if语句 让计算机能够像人一样具有判断的能力 如何用if语句 语法1: if 条件1: code1 code2 cod ...

  8. Super-palindrome 【可能是暴力】

    Super-palindrome 时间限制: 1 Sec  内存限制: 128 MB 提交: 486  解决: 166 [提交] [状态] [命题人:admin] 题目描述 You are given ...

  9. 在vim中 安装php的xdebug和 vdebug插件, 在vim中进行调试php代码

    在vim中 安装php的xdebug和 vdebug插件, 在vim中进行调试php代码 参考: http://www.cnblogs.com/qiantuwuliang/archive/2011/0 ...

  10. SpringBoot 消息转换器 HttpMessageConverter

    1.简介: Spring在处理请求时,由合适的消息转换器将请求报文绑定为方法中的形参对象,在这里,同一个对象就有可能出现多种不同的消息形式,比如json和xml.同样,当响应请求时,方法的返回值也同样 ...