mybatis的sqlsession理解

暖暖      2022-04-09     536

关键词:

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之sqlsessions

使用MyBatis的主要Java接口就是SqlSession。尽管你可以使用这个接口执行命令,获取映射器和管理事务。我们会讨论SqlSession本身更多,但是首先我们还是要了解如何获取一个SqlSession实例。SqlSessions是由SqlSessionFactory实例创建的。SqlSession... 查看详情

09mybatis中sqlsession的使用

参考技术A本文将阐述SqlSession的使用。以上就是mybatis中Sqlsession的使用过程。 查看详情

mybatis之sqlsession介绍

...的工作笔记,好记性不如烂笔头转载自:深入浅出MyBatis-SqlsessionSqlSession的创建Sqlsession对应着一次数据库会话。由于数据库回话不是永久的,因此Sqlsession的生命周期也不应该是永久的,相反,在你每次访问数据库时都需要创建它... 查看详情

深入理解mybatis原理与技术

...1.4MyBatis1.5什么时候用MyBatis第2章MyBatis入门2.2MyBatis构成2.3SqlSession的作用2.4映射器2.4.1使用XML配置方式2.4.2使用注解的方式2.4.3MyBatis映射原理2.5生命周期2.5.1SqlSessionFactoryBuilder2.5.2SqlSessionFa 查看详情

mybatis中sqlsession源码解析

一、sqlsession获取过程1、基础配置  在mybatis框架下进行的数据库操作都需要首先获取sqlsession,在mybatis与spring集成后获取sqlsession需要用到sqlsessionTemplate这个类。首先在spring对sqlsessionTemplate进行配置,使用到的是org.mybatis.spring.Sq... 查看详情

mybatis中的factory工厂与sqlsession

1.SqlSession的使用范围  SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等。通过SqlSessionFactory创建SqlSession,而SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建的。2. SqlSessionFactoryBuilder  SqlSessionFactoryBuilder用... 查看详情

mybatis源码分析——动态代理

...想要知道是如何进行的。相信有上一章的引导大家都知道SqlSession接口的作用。当然默认情况下还是使用DefaultSqlSession类。关于SqlSession接口的用法有很多种。笔者还是比较喜欢用getMapper方法。对于getMapper方法的实现方式。笔者不... 查看详情

mybatis源码分析——动态代理

...想要知道是如何进行的。相信有上一章的引导大家都知道SqlSession接口的作用。当然默认情况下还是使用DefaultSqlSession类。关于SqlSession接口的用法有很多种。笔者还是比较喜欢用getMapper方法。对于getMapper方法的实现方式。笔者不... 查看详情

mybatismybatis缓存

...分为一级缓存和二级缓存,通过下图来理解:一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession2 查看详情

《深入理解mybatis原理7》mybatis的二级缓存的设计原理

...二级缓存的工作模式如上图所示,当开一个会话时,一个SqlSession对象会使用一个Executor对象来完成会话操作,MyBatis的二 查看详情

mybatis源码解析4---sqlsession解析

...加载XML配置文件解析生成全局配置对象Configuration对象,SqlSessionFactoryBuilder类会根据Configuration对象创建一个DefaultSqlSessionFactory对象,而DefaultSqlSessionFactory对象实现了SqlSessionFactory中的创建SqlSession的方法,最终新建了 查看详情

mybatis:sqlsession及其工厂类的作用域和生命周期

SqlSession及其工厂类的作用域和生命周期SqlSession创建流程:  使用SqlSessionFactoryBuilder创建SqlSessionFactory。使用SqlSessionFactory创建SqlSession。SqlSession可以通过SqlMapper.class进行数据库操作,或者直接使用SqlSession的方法输入SqlMapper... 查看详情

mybatis简单使用方式总结

...件与映射文件使用部分:   1.用MyBatis的日志文件建立SqlSessionFactory对象(这是SqlSessionFactory     对象就知道了所有属性的配置和执行Sql的信息)   2.用SqlSessionFaction对象得到一个SqlSession对象   3.通过SqlSession对象对象... 查看详情

mybatis获取sqlsession的工具类(代码片段)

 packagecom.jyk.mybatis.util;importjava.io.IOException;importjava.io.Reader;importjava.sql.Connection;importorg.apache.ibatis.io.Resources;importorg.apache.ibatis.session.SqlSession;importorg.apa 查看详情

mybatis--mybatis相应api(sqlsessionfactorybuildersqlsessionfactory(可以设置自动提交事务)sqlsession)(代码片段)

1.Mybatis相应API1.1SqlSession工厂构建器SqlSessionFactoryBuilder1.2SqlSession工厂对象SqlSessionFactory1.3SqlSession会话对象2.补充:了解SqlSessionFactory工厂类每个基于MyBatis的应用都是以一个SqlSessionFactory的实例为核心的。 SqlSessionFac 查看详情

《深入理解mybatis原理4》mybatis缓存机制的设计与实现

...存是Session会话级别的缓存,位于表示一次数据库会话的SqlSession对象之中,又被称之为本地缓存。 查看详情

mybatis缓存

  一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。  一级缓存的作用... 查看详情

mybatis缓存机制

...mybatis的缓存分为两级:一级缓存、二级缓存一级缓存是SqlSession级别的缓存,缓存的数据只在SqlSession内有效二级缓存是mapper级别的缓存,同一个namespace公用这一个缓存,所以对SqlSession是共享的一级缓存:  mybatis的一级缓存是S... 查看详情