1. 程式人生 > >mybatis源碼閱讀-SqlSessionFactory(三)

mybatis源碼閱讀-SqlSessionFactory(三)

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(三)