MyBatis:SqlSessionFactory构建过程
SqlSessionFactory 是 MyBatis 的核心类,从这类名可以看出这是个 SqlSession 工厂类,其最重要的功能就是提供创建 MyBatis 的核心接口 SqlSession,所以需要先创建 SqlSessionFactory,为此需要提供配置文件和相关参数。
MyBatis 采用构造模式去创建 SqlSessionFactory,可以通过 SqlSessionFactoryBuild 去创建。构建分两步。
构建SqlSessionFactory
第一步,通过 org.apache.ibatis.builder.xml.XMLConfigBuilder 解析配置 XML 文件,读出配置参数,并将读取的数据存入 org.apache.ibatis.session.Configuration 类中。
注意:MyBatis 几乎所有的配置都存在这里。
第二步,使用 Configuration 对象去创建 SqlSessionFactory。SqlSessionFactory 是个接口,而不是实现类,MyBatis 提供了一个默认的实现类 org.apache.ibatis.session.defaults.DefaultSqlSessionFactory。
注意:在大部分情况下我们都没必要自己去创建新的 SqlSessionFactory 的实现类。
SqlSessionFactory创建方式是一种 Builder模式。对于复杂的对象而言,直接使用构造方法创建会有些困难,这会导致大量逻辑放在构造方法 ,由于对象的复杂性,在构建的时候更希望一步步有秩序的构建它,从而降低其复杂性。这时候使用一个参数总领全局,例如 Configuration 类,然后分步构建。
MyBatis 提供了创建 SqlSession 的静态工具类 org.apache.ibatis.session.SqlSessionManager,继承了SqlSessionFactory 接口 ,提供了一系列的 newInstance 静态方法用于 创建 SqlSessionFactory 。
构建SqlSessionFactory源码:
1 | public class SqlSessionFactoryBuilder { |
构建 Configuration
构建 SqlSessionFactory 中,Configuration 是最重要的,它的作用如下:
- 读入配置文件,包括基础配置 XML 文件和映射器的 XML 文件。
- 初始化基础配置,比如 MyBatis 别名等,一些重要的类对象,例如,插件,映射器, ObjectFactory 和 typeHandler 对象。
- 提供单例,为后续创建 SessionFactory 服务并提供配置的参数。
- 执行一些重要的对象方法,初始化配置信息。
Configuration 是通过 XMLConfigBuilder 构建的。MyBatis 会读出所有 XML 配置的信息。然后,将这些信息保存到 Configuration 类的单例中。它会做如下初始化。
- properties 全局参数
- settings 设置
- typeAliases 别名
- typeHandler 类型处理器
- ObjectFactory 对象
- Plugin 插件
- environment 环境
- DatabaseIdProvider 数据库标识
- Mapper 映射器
映射器的内部组成
一般而言,一个映射器是由 3 个部分组成:
- MappedStatement,它保存映射器的一个节点(select | insert | delete | update)。包括许多我们配置的 SQL,SQL 的 id,缓存信息,resultMap,parameterMap,resultType,languangeDriver等重要配置内容。
- SqlSource,它是提供 BoundSql对象的地方,它是 MappedStatement 的一个属性。
- BoundSql,它是建立 SQL 和参数的地方。它有 3 个常用的属性: SQL,parameterObject,parameterMappings。
MappedStatement 对象涉及的东西较多,一般都不会修改它,因为容易产生不必要的错误。
SqlSource 是一个接口,它主要作用是根据参数和其他的规则组装 SQL,也比较复杂,一般也不需要修改它。
BoundSql ,对于参数和 SQL 而言,主要的规则反映在 BoundSql 类对象上,在插件中往往需要拿到它进而拿到当前运行的 SQL 和参数以及参数规则,做出适当的修改,来满足我们特殊的需求。
BoundSql 会提供 3 个主要属性: parameterMappings,parameterObject 和 sql。
parameterObject ,为参数本身,可以传递简单对象,POJO,Map,或者 @Param 注解的参数,在插件中常用到。
传递简单对象(包括 int,String,float,double等),MyBatis 会把参数变为 Integer 对象传递,类似的 long,String,float,double也是如此。
传递的是 POJO 或 Map,parameterObject 就是传入的 POJO 或 Map 不变。
也可以传递多个参数,如果没有 @Param 注解,那么 MyBatis 就会把 parameterObject 变为一个 Map<String, Object> 对象,其键值的关系是按顺序来规划的,类似于这样的形式
1
2
3
4
5
6
7
8
9{
"1":p1,
"2":p2,
"3":p3,
....
"param1":p1,
"param2":p2,
"param3":p3
}所以在编写的时候,可以使用
#{param1}
或#{1}
去引用第一个参数。如果使用 @Param 注解,那么 MyBatis 就会把 parameterObject 变为一个 Map<String, Object> 对象,类似于没有 @Param 注解,只是把其数字的键值对应置换为了 @Param 注解的键值。比如注解
@Param("key1") String p1
。1
2
3{
"key1":p1
}parameterMappings,它是一个 List,每一个元素都是 ParameterMapping 的对象。这个对象会描述我们的参数,包括属性,名称,表达式,javaType,jdbcType,typeHandler 等重要信息。一般不需要改变它。
通过它可以实现参数和 SQL 的结合,以便 PreparedStatement 能够通过它找到 parameterObject 对象的属性并设置参数,使得程序准确运行。
sql 属性就是我们书写在映射器里面的一条 SQL,在大多数时候无需修改它,只有在插件的情况下,可以根据需要进行改写,但一定要谨慎行事。
MyBatis:SqlSessionFactory构建过程
http://blog.gxitsky.com/2023/06/05/Mybatis-13-sqlSessionFactory/