Fork me on GitHub

MyBatis 之 SqlSessionManager 源码分析

MyBatis 的 4 个基本构成:

SqlSessionFactoryBuilder(构造器):

  根据配置信息或者代码来生成 SqlSessionFactory(工厂接口)

SqlSessionFactory:

  依靠工厂来生成 SqlSession(会话),每个 MyBatis 的应用都是以 SqlSessionFactory 的实例为中心的。SqlSessionFactory 通过 SqlSessionFactoryBuilder 获得。MyBatis 提供了两个 SqlSessionFactory 的实现类,DefaultSqlSessionFactory 和 SqlSessionManager,Mybatis 使用的是前者,不过本篇的主角是 SqlSessionManager

SqlSession:

  是一个既可以发送 SQL 去执行并返回结果,也可以获取 Mapper 的接口。SqlSession 类似于一个 JDBC 的 Connection 对象。

SQL Mapper:

  它是 MyBatis 新设计的组件,它是由一个 Java 接口和 XML 文件(或注解)构成的,需要给出对应的 SQL 和映射规则。它负责发送 SQL 去执行,并返回结果

SqlSessionManager 分析:

实现 SqlSessionFactory、SqlSession 两个接口

SqlSessionFactory 接口中方法包括

  • openSession()
  • ...

SqlSession 接口中方法包括,对数据的各种操作:

  • selectOne()
  • selectList()
  • update()
  • insert()
  • ...

类属性:

  • SqlSessionFactory SqlSessionFactory:用于在 openSession 方法中创建 SqlSession
  • SqlSession sqlSessionProxy:用于与 mapper 交互,注意其属性名带有 Proxy,所以它是通过反射创建的
  • ThreadLocal<SqlSession>:用于用户自己控制 SqlSession 时使用,通过 SqlSessionFactory 工厂创建

构造方法:

私有构造方法:

    入参为 SqlSessionFactory,其中 sqlSessionProxy 通过 JDK 提供的动态代理实现,
    Proxy.newProxyInstance() 入参说明:

    • loader:定义代理类的类加载器
    • interfaces:代理类要实现的接口列表
    • h:指派方法调用的调用处理程序

    Proxy.newProxyInstance() 返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序

newInstance 方法:

构建模式,通过该方法来调用构造方法,来初始化 sqlSessionFactory 和 sqlSessionProxy

startManagedSession 方法:

初始化 localSqlSession 属性,通过 sqlSessionFactory.openSession()获得 SqlSession,再将其 set 到 localSqlSession 中

openSession 方法:

该方法来自 SqlSessionFactory 接口的方法列表,通过 sqlSessionFactory.openSession()来获得 SqlSession,openSession 由 DefaultSqlSessionFactory 实现

余下的方法都是 SqlSession 接口的方法实现:

由 sqlSessionProxy 这个 SqlSession 代理对象来执行

内部类 SqlSessionInterceptor:

实现 InvocationHandler 接口,当执行 SqlSession 接口的方式实现时,就会进入这个代理方法中。
可以看到 SqlSession 通过 openSession 方法获得,此处的 sqlSession 实例便是 SqlSession 的代理对象 SqlSessionProxy,之后执行 commit 操作,注意这里使用了 try catch 块,在 finally 中执行 SqlSession 的 close 方法,这使得开发者不必再在代码中去手动 close

参考资料

[1] mybatis 3.4.2 DefaultSqlSessionFactory的优化版SqlSessionManager

[2] MyBatis中SqlSessionManager设计疑问

[3] mybatis源码分析(3)——SqlSessionManager类

posted @ 2017-07-25 14:56  郑斌blog  阅读(1616)  评论(0编辑  收藏  举报