Mybatis之typeAliases配置

 

mybatis中我们经常配置,别名来简化我们的配置文件书写,其中配置别名的方式我们常用的一个是直接配置,另一个是配置package来让mybatis进行扫描。

我们来看一下mybatis对这个标签的解析代码。mybatisXMLConfigBuilder类中的parseConfiguration方法,集合了对各种配置属性的解析,其中有一句

this.typeAliasesElement(root.evalNode("typeAliases"));
就是对typeAliases的解析,我们来看一下具体方法
private void typeAliasesElement(XNode parent) {
    if (parent != null) {
        Iterator i$ = parent.getChildren().iterator();

        while(i$.hasNext()) {
            XNode child = (XNode)i$.next();
            String alias;
            if ("package".equals(child.getName())) {
                alias = child.getStringAttribute("name");
                this.configuration.getTypeAliasRegistry().registerAliases(alias);
            } else {
                alias = child.getStringAttribute("alias");
                String type = child.getStringAttribute("type");

                try {
                    Class<?> clazz = Resources.classForName(type);
                    if (alias == null) {
                        this.typeAliasRegistry.registerAlias(clazz);
                    } else {
                        this.typeAliasRegistry.registerAlias(alias, clazz);
                    }
                } catch (ClassNotFoundException var7) {
                    throw new BuilderException("Error registering typeAlias for '" + alias + "'. Cause: " + var7, var7);
                }
            }
        }
    }
}
其实我们在刚进去 typeAliasesElement 方法的时候就发现XMLConfigBuildertypeAliasRegistry属性中就已经有一些值了,其实这些值是系统为我们定义的别名,这些别名是在哪儿初始化的呢?

我们知道,在调用SqlSessionFactoryBuilderbuild构造SqlSessionFactory的时候,在解析配置文件的时候,有调用XMLConfigBuilder的构造方法

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;
}

这些系统定义的别名就是在这个构造方法中初始化的,我们进去看看

public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {
    this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);
}
其中调用了另一个构造方法
private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
    super(new Configuration());
    ErrorContext.instance().resource("SQL Mapper Configuration");
    this.configuration.setVariables(props);
    this.parsed = false;
    this.environment = environment;
    this.parser = parser;
}

看这个构造函数的第一行代码super(new Configuraction)先看Configuration的构造

public Configuration() {
    this.safeRowBoundsEnabled = false;
    this.safeResultHandlerEnabled = true;
    this.mapUnderscoreToCamelCase = false;
    this.aggressiveLazyLoading = true;
    this.multipleResultSetsEnabled = true;
    this.useGeneratedKeys = false;
    this.useColumnLabel = true;
    this.cacheEnabled = true;
    this.callSettersOnNulls = false;
    this.localCacheScope = LocalCacheScope.SESSION;
    this.jdbcTypeForNull = JdbcType.OTHER;
    this.lazyLoadTriggerMethods = new HashSet(Arrays.asList("equals", "clone", "hashCode", "toString"));
    this.defaultExecutorType = ExecutorType.SIMPLE;
    this.autoMappingBehavior = AutoMappingBehavior.PARTIAL;
    this.variables = new Properties();
    this.objectFactory = new DefaultObjectFactory();
    this.objectWrapperFactory = new DefaultObjectWrapperFactory();
    this.mapperRegistry = new MapperRegistry(this);
    this.lazyLoadingEnabled = false;
    this.interceptorChain = new InterceptorChain();
    this.typeHandlerRegistry = new TypeHandlerRegistry();
    this.typeAliasRegistry = new TypeAliasRegistry();
    this.languageRegistry = new LanguageDriverRegistry();
    this.mappedStatements = new Configuration.StrictMap("Mapped Statements collection");
    this.caches = new Configuration.StrictMap("Caches collection");
    this.resultMaps = new Configuration.StrictMap("Result Maps collection");
    this.parameterMaps = new Configuration.StrictMap("Parameter Maps collection");
    this.keyGenerators = new Configuration.StrictMap("Key Generators collection");
    this.loadedResources = new HashSet();
    this.sqlFragments = new Configuration.StrictMap("XML fragments parsed from previous mappers");
    this.incompleteStatements = new LinkedList();
    this.incompleteCacheRefs = new LinkedList();
    this.incompleteResultMaps = new LinkedList();
    this.incompleteMethods = new LinkedList();
    this.cacheRefMap = new HashMap();
    this.typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
    this.typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);
    this.typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class);
    this.typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class);
    this.typeAliasRegistry.registerAlias("UNPOOLED", UnpooledDataSourceFactory.class);
    this.typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class);
    this.typeAliasRegistry.registerAlias("FIFO", FifoCache.class);
    this.typeAliasRegistry.registerAlias("LRU", LruCache.class);
    this.typeAliasRegistry.registerAlias("SOFT", SoftCache.class);
    this.typeAliasRegistry.registerAlias("WEAK", WeakCache.class);
    this.typeAliasRegistry.registerAlias("DB_VENDOR", VendorDatabaseIdProvider.class);
    this.typeAliasRegistry.registerAlias("XML", XMLLanguageDriver.class);
    this.typeAliasRegistry.registerAlias("RAW", RawLanguageDriver.class);
    this.typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class);
    this.typeAliasRegistry.registerAlias("COMMONS_LOGGING", JakartaCommonsLoggingImpl.class);
    this.typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class);
    this.typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class);
    this.typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class);
    this.typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class);
    this.typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class);
    this.typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class);
    this.typeAliasRegistry.registerAlias("JAVASSIST", JavassistProxyFactory.class);
    this.languageRegistry.setDefaultDriverClass(XMLLanguageDriver.class);
    this.languageRegistry.register(RawLanguageDriver.class);
}
其中有调用TypeAliasRegistry的构造方法,其中这个构造方法就初始化了一部分系统定义的别名
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);
    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);
    this.registerAlias("_byte", Byte.TYPE);
    this.registerAlias("_long", Long.TYPE);
    this.registerAlias("_short", Short.TYPE);
    this.registerAlias("_int", Integer.TYPE);
    this.registerAlias("_integer", Integer.TYPE);
    this.registerAlias("_double", Double.TYPE);
    this.registerAlias("_float", Float.TYPE);
    this.registerAlias("_boolean", Boolean.TYPE);
    this.registerAlias("_byte[]", byte[].class);
    this.registerAlias("_long[]", long[].class);
    this.registerAlias("_short[]", short[].class);
    this.registerAlias("_int[]", int[].class);
    this.registerAlias("_integer[]", int[].class);
    this.registerAlias("_double[]", double[].class);
    this.registerAlias("_float[]", float[].class);
    this.registerAlias("_boolean[]", boolean[].class);
    this.registerAlias("date", Date.class);
    this.registerAlias("decimal", BigDecimal.class);
    this.registerAlias("bigdecimal", BigDecimal.class);
    this.registerAlias("biginteger", BigInteger.class);
    this.registerAlias("object", Object.class);
    this.registerAlias("date[]", Date[].class);
    this.registerAlias("decimal[]", BigDecimal[].class);
    this.registerAlias("bigdecimal[]", BigDecimal[].class);
    this.registerAlias("biginteger[]", BigInteger[].class);
    this.registerAlias("object[]", Object[].class);
    this.registerAlias("map", Map.class);
    this.registerAlias("hashmap", HashMap.class);
    this.registerAlias("list", List.class);
    this.registerAlias("arraylist", ArrayList.class);
    this.registerAlias("collection", Collection.class);
    this.registerAlias("iterator", Iterator.class);
    this.registerAlias("ResultSet", ResultSet.class);
}
然后另一部分就是在Configuration的构造方法中注册的。

然后回到我们XMLConfigBuilder的构造方法,看其中的super(newConfiguration())看其调用父类的构造方法来初始化一些值。

public BaseBuilder(Configuration configuration) {
    this.configuration = configuration;
    this.typeAliasRegistry = this.configuration.getTypeAliasRegistry();
    this.typeHandlerRegistry = this.configuration.getTypeHandlerRegistry();
}

其中就把configuration中已经注册的别名赋值给了其typeAliasRegistry属性。
至此我们已经知道系统定义的别名来源。现在我们回到用户自定义别名的解析。继续看我们的XMLConfigBuildertypeAliasesElement方法。

我配置文件中配置了

<typeAliases>
    <typeAlias type="com.cyy.mybatis.domain.Cat" alias="cat"/>
    <typeAlias type="com.cyy.mybatis.domain.Dog" alias="dog"/>
    <package name="com.cyy.mybatis.alias"/>
</typeAliases>
这个解析会按照顺序来解析
解析配置的<typeAlias>看结果
解析package看结果

其中com.cyy.mybatis.alias包的内容如下


其中AAA类采用了Alias注解来指定别名,AbAbA没用采用注解,别名系统自动生成。

我们看到如果我们用注解指定指定别名,扫描注册的别名就是我们指定的,如果没有指定,就是系统自动生成的,生成规则就是简单类名的小写。

至此别名配置解析完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值