mybatis源碼閱讀-SqlSessionFactory(三)
阿新 • • 發佈:2018-07-07
session env code update 建造者 building ssl tin delete
我們的一個mybatis程序
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//返回的DefaultSqlSessionFactory的實例 SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder .build(ClassLoader.getSystemResourceAsStream("mybatis.xml")); SqlSession sqlSession= sqlSessionFactory.openSession();
SqlSessionFactory是Mybatis的一個核心類負責創建SqlSession
SqlSessionFactory是由SqlSessionFactoryBuilder的build方法創建
public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { SqlSessionFactory var5; try { XMLConfigBuilder parser= new XMLConfigBuilder(inputStream, environment, properties); var5 = this.build(parser.parse()); } catch (Exception var14) { throw ExceptionFactory.wrapException("Error building SqlSession.", var14); } finally { ErrorContext.instance().reset();try { inputStream.close(); } catch (IOException var13) { ; } } return var5; }
內部調用了XMLConfigBuilder parser 看名字 我們可以看出來他是負責解析mybatis.
public Configuration parse() { if (this.parsed) { throw new BuilderException("Each XMLConfigBuilder can only be used once."); } else { this.parsed = true; this.parseConfiguration(this.parser.evalNode("/configuration")); return this.configuration; } }
this.parser.evalNode("/configuration")獲得根節點
private void parseConfiguration(XNode root) { try { Properties settings = this.settingsAsPropertiess(root.evalNode("settings")); this.propertiesElement(root.evalNode("properties")); this.loadCustomVfs(settings); this.typeAliasesElement(root.evalNode("typeAliases")); this.pluginElement(root.evalNode("plugins")); this.objectFactoryElement(root.evalNode("objectFactory")); this.objectWrapperFactoryElement(root.evalNode("objectWrapperFactory")); this.reflectionFactoryElement(root.evalNode("reflectionFactory")); this.settingsElement(settings); this.environmentsElement(root.evalNode("environments")); this.databaseIdProviderElement(root.evalNode("databaseIdProvider")); this.typeHandlerElement(root.evalNode("typeHandlers")); this.mapperElement(root.evalNode("mappers")); } catch (Exception var3) { throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + var3, var3); } }
settings|typeHandlers|mappers|properties
逐個解析最終封裝到Configuration 對象裏面
public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); }
最終將解析好的數據都封裝到configuration裏面 初始化DefaultSqlSessionFactory (建造者模式)
Configuration屬性
TypeAliasRegistry
我們定義的別名
<typeAliases> <!-- 批量別名定義,指定包名,mybatis自動掃描包中的po類,自動定義別名,別名是類名(首字母大寫或小寫都可以,一般用小寫) --> <package name="com.liqiang.entity" /> <package name="com.liqiang.vo" /> </typeAliases>
點開這個類的構造函數可以發現默認註冊了很多基本類型的別名,這就是為什麽我們int double不用指定全名稱的原因
public TypeAliasRegistry() { this.registerAlias("string", String.class); this.registerAlias("byte", Byte.class); this.registerAlias("long", Long.class); this.registerAlias("short", Short.class); this.registerAlias("int", Integer.class); this.registerAlias("integer", Integer.class); this.registerAlias("double", Double.class); this.registerAlias("float", Float.class); this.registerAlias("boolean", Boolean.class);
......
}
TypeHandlerRegistry
public TypeHandlerRegistry() { this.register((Class)Boolean.class, (TypeHandler)(new BooleanTypeHandler())); this.register((Class)Boolean.TYPE, (TypeHandler)(new BooleanTypeHandler())); this.register((JdbcType)JdbcType.BOOLEAN, (TypeHandler)(new BooleanTypeHandler())); this.register((JdbcType)JdbcType.BIT, (TypeHandler)(new BooleanTypeHandler()));
..... }
註冊我們自定義的TypeHandler,可以看到默認實現了很多,所以我們對於常見的類型不需要再定義typeHandle
mappedStatements
Map<String, MappedStatement> mappedStatements
mybatis會將所有select|update|insert|delete標簽解析為MappedStatement對象的形式保存起來
內部主要屬性:
ParameterMap 一對多ParametersMapping 保存參數的映射關系
ResultMap 一對多 ResultMapping 保存返回結果的映射關系
我們可以發現剛開始mybatis會將xml裏面的每個標簽通過configuration封裝起來通過他初始化SqlSessionFactory
mybatis源碼閱讀-SqlSessionFactory(三)