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