5

聊聊Mybatis的SqlSession

 2 years ago
source link: https://blog.51cto.com/u_15460453/5615436
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

聊聊Mybatis的SqlSession

精选 原创

周杰伦本人 2022-08-24 11:41:51 ©著作权

文章标签 sql 增删改查 java 文章分类 Java 编程语言 yyds干货盘点 阅读数200

Table of Contents

聊聊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

  • 收藏
  • 评论
  • 分享
  • 举报

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK