YU000HONG

持续学习,努力向前~

「MyBatis源码分析」MyBatis配置文件解析

2020-05-17     标签:  MyBatis

MyBatis配置文件大致如下:

<configuration>
    <properties/>
    <settings/>
    <typeAliases/>
    <typeHandlers/>
    <objectFactory/>
    <objectWrapperFactory/>
    <reflectorFactory/>
    <plugins/>
    <environments/>
    <databaseIdProvider/>
    <mappers/>
</configuration>

我们使用MyBatis的大致程序框架如下:

  • 使用SqlSessionFactoryBuilder构建一个SqlSessionFactory实例
  • 使用SqlSessionFactory开启一个会话SqlSession(真正的数据库连接在Transaction里面)
  • 使用SqlSession执行mapper对应的SQL
  • 处理结果
  • 关闭会话
public static void main(String[] args) throws IOException {
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession session = sqlSessionFactory.openSession();
    Student stu = session.selectOne("getStudentById", 345229);
    System.out.println(stu.getName());
    session.commit();
    session.close();
}

SqlSessionFactoryBuilder其实是一个工具类,没有实例字段,只有不同形式的build()方法。

public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
    try {
        XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
        return build(parser.parse());
    } catch (Exception e) {
        throw ExceptionFactory.wrapException("Error building SqlSession.", e);
    } finally {
        ErrorContext.instance().reset();
        try {
            reader.close();
        } catch (IOException e) {
            // Intentionally ignore. Prefer previous error.
        }
    }
}

所以,真正的解析工作还是在XMLConfigBuilder。我们下面来看看不同节点的解析流程。

properties

我们可以在配置文件中定义一些属性,也可以引用外部定义的Java属性文件。

<properties resource="org/mybatis/example/config.properties" url="http://xxx/xxx.properties">
    <property name="username" value="dev_user"/>
    <property name="password" value="F2Fa3!33TYyg"/>
</properties>

⚠️注意:

  • resourceurl最多只能选一个,否则会报错
  • 我们最多能引用一个外部Java属性文件
  • 所有这些属性会合并,然后被设置为Configuration.varaiables字段,用于后续的属性替换

settings

<settings>
    <setting name="cacheEnabled" value="true"/>
    <setting name="useColumnLabel" value="true"/>
    <setting name="useGeneratedKeys" value="false"/>
</settings>

这些设置会被反射到Configuration对应的setter方法,如:cacheEnabled映射到setCacheEnabled()方法。如果某个设置通过反射没有找到对应的setter方法,那么将抛出异常。

typeAliases

<typeAliases>
    <package name="com.yu000hong.domain"/>
    <typeAlias alias="Author" type="com.yu000hong.blog.domain.Author"/>
</typeAliases>

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。

MyBatis内置的类型别名有:

_byte => byte_long => long_short => short_int => int
_integer => int_double => double_float => float_boolean => boolean
byte => Bytelong => Longshort => Shortint => Integer
integer => Integerdouble => Doublefloat => Floatboolean => Boolean
string => Stringdate => Datedecimal => BigDecimalbigdecimal => BigDecimal
object => Objectmap => Maphashmap => HashMaplist => List
arraylist => ArrayListcollection => Collectioniterator => Iterator