Skip to content
Nico edited this page Oct 15, 2018 · 2 revisions

Ourbatis是一个基于模板起步的Mybatis辅助工具,在整个生命周期中,模板解析占据着非常重要的地位。Ourbatis使用独立的、超轻量级的XML解析来完成这项工作!可以说,模板解析就是Ourbatis的核心,在整个项目中承上启下,而Ourbatis由启动到服务还需要一些上下文的操作步骤。

Ourbatis的做法是通过一个模板配合实体类渲染出与之对应的XML,然后Build到Mybatis之中来达到通用的效果,所以整个过程是完全无侵入切不损耗性能的。

Ourbatis的启动依赖于Mybatis的SqlSessionFactory初始化完毕,对于Mybatis来讲,一个SqlSessionFactory就意味着一个数据源,也就意味着需要对数据库操作,那么至少就需要一个SqlSessionFactory,当获取到一个sql会话工厂对象之后,我们才可以开始Ourbatis的工作,而Spring提供有一个@ConditionalOnBean的注解可以帮助我们很好的去实现这个等待,我在org.nico.ourbatis.autoconfigure.OurbatisAutoConfiguration类中使用了它:

@Configuration
@ConditionalOnBean({SqlSessionFactory.class})
@EnableConfigurationProperties(OurbatisProperties.class)
public class OurbatisAutoConfiguration {...}

在获取到SqlSessionFactory之后,Ourbatis会获取自己的配置参数并做一些初始化的工作,必填参数:

ourbatis.domain-locations=org.nico.ourbatis.domain

通过domain-locations的设定,Ourbatis可以找到要渲染的实体类,而紧跟着上一步之后的操作就是将domain-locations下的实体类全部映射为模板中需要替换占位符的数据信息。

org.nico.ourbatis.mapping.MapperMapping这个类的作用是将实体类转化为模板元数据,在这个过程,Ourbatis可以对指定的数据做统一的格式包装,如下:

  • 由类名映射表名
  • 由类字段名映射表字段名
  • 由类名映射Mapper接口类名
  • 由类字段类型映射表字段类型

在经过Mapper映射后的元数据将会被存放在org.nico.ourbatis.entity.Table载体中,不难看出,一个实体类就对应一个Table载体,也就意味着一个实体类映射着一张表。

接下来,Ourbatis将会依照ourbatis.xml模板渲染所有的Table,在ourbatis.xml中,有着独立的标签和与之对应的解析失配器:

  • ourbatis:foreach 遍历集合
  • ourbatis:ref 文件指针,可以引入外部文件内容到该标签位置

Ourbatis在使用独立的XML解析过程中,会对其中的特殊标签进行自定义的处理,将结果重新渲染到整个文本上,从而生成一个新的xml文本,也就是我们需要的目标实体类的Mapper接口操作xml文件内容,Ourbatis会暂时将之存储在一个Map容器中,待到所有的Table都被模板渲染之后,再触发下一步操作。

最终,Ourbatis会将所有的渲染之后的文本使用Mybatis重新Build一遍,这种原理类似于Mybatis的热加载,Mybatis可以使用这种方式进行动态SQL替换,核心代码段:

ByteArrayInputStream mapperStream = new ByteArrayInputStream(mapper.getBytes());
XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperStream, this.configuration,
			mapperStream.toString(), this.configuration.getSqlFragments());
xmlMapperBuilder.parse();

parse方法的执行,将会触发Mybatis对xml文本的重新解析和Loading,Mapper接口代理方法也将会被自动注入实现。

至此,从初始化到完成Build,Ourbatis的整个生命周期执行完毕,之后的操作将会与Ourbatis无关,可见Ourbaits毫无侵入性,且对性能也毫无影响,之后在服务启动的时候稍微活跃一段时间。

Clone this wiki locally