这篇主要分析SqlSessionFactory的构建过程,以及mybatis mapper文件的解析
先来看SqlSessionFactory的创建过程
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
org.apache.ibatis.session.SqlSessionFactoryBuilder#build(java.io.Reader,java.lang.String,java.util.Properties)
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
//委托XMLConfigBuilder来解析xml文件,并构建
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
return build(parser.parse());
} catch (Exception e) {
//这里是捕获异常,包装成自己的异常并抛出的idiom?,最后还要reset ErrorContext
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
可以看到SqlSessionFactoryBuilder委托XMLConfigBuilder来解析xml文件,下面我们跟进去查看解析过程
//构造函数,转换成XPathParser再去调用构造函数
public XMLConfigBuilder(Reader reader, String environment, Properties props) {
//构造一个需要验证,XMLMapperEntityResolver的XPathParser
this(new XPathParser(reader, true, props, new XMLMapperEntityResolver()), environment, props);
}
最终调用的构造方法是:
//上面6个构造函数最后都合流到这个函数,传入XPathParser
private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
//首先调用父类初始化Configuration
super(new Configuration());
//错误上下文设置成SQL Mapper Configuration(XML文件配置),以便后面出错了报错用吧
ErrorContext.instance().resource("SQL Mapper Configuration");
//将Properties全部设置到Configuration里面去
this.configuration.setVariables(props);
this.parsed = false;
this.environment = environment;
this.parser = parser;
}
创建一个Configuration对象,
然后会调用父类的构造org.apache.ibatis.builder.BaseBuilder#BaseBuilder
//需要配置,类型别名注册,类型处理器注册3个东西
protected final Configuration configuration;
protected final TypeAliasRegistry typeAliasRegistry;
protected final TypeHandlerRegistry typeHandlerRegistry;
public BaseBuilder(Configuration configuration) {
this.configuration = configuration;
this.typeAliasRegistry = this.configuration.getTypeAliasRegistry();
this.typeHandlerRegistry = this.configuration.getTypeHandlerRegistry();
}
//映射的语句,存在Map里
protected final Map<String, MappedStatement> mappedStatements = new StrictMap<MappedStatement>("Mapped Statements collection");
//缓存,存在Map里
protected final Map<String, Cache> caches = new StrictMap<Cache>("Caches collection");
这是Configuration对象的成员变量,mapper中配置的sql解析出来之后会存在mappedStatements 中
org.apache.ibatis.builder.xml.XMLConfigBuilder#parse
//解析配置
public Configuration parse() {
//如果已经解析过了,报错
if (parsed) {
throw new BuilderException("Each XMLConfigBuilder can only be used once.");
}
parsed = true;
// <?xml version="1.0" encoding="UTF-8" ?>
// <!DOCTYPE configuration PUBLIC "-//mybat