聊聊Mybatis的SqlSession会话

举报
周杰伦本人 发表于 2022/08/30 20:26:12 2022/08/30
【摘要】 聊聊Mybatis的SqlSession会话SqlSessionFactory接口是用来创建SQLSession的,它是一个接口,默认实现类是DefaultSqlSessionFactory,DefaultSqlSessionFactory中创建SqlSession有两种方式: 通过连接信息创建SqlSession一种是调用openSessionFromConnection()来获取Sql...

聊聊Mybatis的SqlSession会话

SqlSessionFactory接口是用来创建SQLSession的,它是一个接口,默认实现类是DefaultSqlSessionFactory,DefaultSqlSessionFactory中创建SqlSession有两种方式:

通过连接信息创建SqlSession

一种是调用openSessionFromConnection()来获取SqlSession,也就是通过Connection来创建SqlSession,关键代码

      final Environment environment = configuration.getEnvironment();
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      final Transaction tx = transactionFactory.newTransaction(connection);
      final Executor executor = configuration.newExecutor(tx, execType);
      return new DefaultSqlSession(configuration, executor, autoCommit);
  1. 获取Environment对象
  2. 通过Environment对象获取TransactionFactory对象
  3. 通过事务工厂创建事务对象,传入参数是Connection对象
  4. 传入事务对象参数创建出Executor对象
  5. 创建DefaultSqlSession对象来创建SqlSession

通过数据源创建SqlSession

另一种方法是openSessionFromDataSource()方法,也就是通过数据源来获取SqlSession,关键代码:

      final Environment environment = configuration.getEnvironment();
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
      final Executor executor = configuration.newExecutor(tx, execType);
      return new DefaultSqlSession(configuration, executor, autoCommit);

整体和第一种一样,只是第三步创建事务对象时候,传入参数是DataSource对象

SqlSession接口是一个重要的接口,它提供增删改查的的执行接口和事务管理的接口,默认实现类是DefaultSqlSession,DefaultSqlSession有个Executor成员变量,通过这个执行器进行事务的管理和sql的执行,这里用到了策略模式,Executor就是策略类,它的子类就是具体的策略类,DefaultSqlSession根据不同的策略选择不同Executor来进行事务管理和sql执行,DefaultSqlSession的增删改查的所有方法都是通过Executor实例来进行执行的

SqlSessionManager

SqlSessionManager实现了SqlSessionFactory接口和SqlSession接口,它既可以创建SQLSession,又能对数据库操作,它是SqlSessionFactory的装饰类,SqlSessionManager可以通过openSession()调用sqlSessionFactory创建SqlSession

@Override
  public SqlSession openSession() {
    return sqlSessionFactory.openSession();
  }

SqlSessionManager有个ThreadLocal成员变量:ThreadLocal<SqlSession> localSqlSession = new ThreadLocal<>();

通过ThreadLocal可以调用startManagedSession()实现当前线程和SqlSession的绑定:

public void startManagedSession() {
    this.localSqlSession.set(openSession());
  }

完成绑定后是怎么使用的呢,我们看到SqlSessionManager的构造方法中SqlSession实例的创建是通过动态代理来创建的:

this.sqlSessionProxy = (SqlSession) Proxy.newProxyInstance(
        SqlSessionFactory.class.getClassLoader(),
        new Class[]{SqlSession.class},
        new SqlSessionInterceptor());

SqlSessionInterceptor实现InvocationHandler接口进行拦截,首先从SqlSessionManager的localSqlSession从获取SqlSession,如果不为空就直接执行具体方法,否则为调用openSession()方法得到SqlSession,然后执行具体方法,通过源码我们可以看到SqlSessionManager的增删改查方法都是通过代理类sqlSessionProxy来调用的具体方法

总结

本篇文章讲了SqlSession接口和它的默认实现类DefaultSqlSession,它有个Executor实例作为成员变量,增删改查需要Executor实例来执行sql,SqlSessionFactory是创建SqlSession的接口,默认实现类是DefaultSqlSessionFactory,它可以通过DataSource实例或Connection得到事务实例从而创建SqlSession实例,SqlSessionManager实现了SqlSession接口和SqlSessionFactory接口,增删改查使用代理类执行,SqlSession使用ThreadLocal来存储,避免一个线程重复创建SqlSession

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。