SqlSessionFactoryBuilder
SqlSessionFactoryBuilder 有五个 build() 方法,每一种都允许你从不同的资源中创建一个 SqlSessionFactory 实例。
- SqlSessionFactory build(InputStream inputStream)
- SqlSessionFactory build(InputStream inputStream, String environment)
- SqlSessionFactory build(InputStream inputStream, Properties properties)
- SqlSessionFactory build(InputStream inputStream, String env, Properties props)
- SqlSessionFactory build(Configuration config)
第一种方法是最常用的,它接受一个指向 XML 文件(也就是之前讨论的 mybatis-config.xml 文件)的 InputStream 实例。可选的参数是 environment 和 properties。environment 决定加载哪种环境,包括数据源和事务管理器。比如:
- <environments default="development">
- <environment id="development">
- <transactionManager type="JDBC">
- ...
- <dataSource type="POOLED">
- ...
- </environment>
- <environment id="production">
- <transactionManager type="MANAGED">
- ...
- <dataSource type="JNDI">
- ...
- </environment>
- </environments>
如果你调用了带 environment 参数的 build 方法,那么 MyBatis 将使用该环境对应的配置。当然,如果你指定了一个无效的环境,会收到错误。如果你调用了不带 environment 参数的 build 方法,那么就会使用默认的环境配置(在上面的示例中,通过 default=”development” 指定了默认环境)。
如果你调用了接受 properties 实例的方法,那么 MyBatis 就会加载这些属性,并在配置中提供使用。绝大多数场合下,可以用 ${propName} 形式引用这些配置值。
回想一下,在 mybatis-config.xml 中,可以引用属性值,也可以直接指定属性值。因此,理解属性的优先级是很重要的。在之前的文档中,我们已经介绍过了相关内容,但为了方便查阅,这里再重新介绍一下:
如果一个属性存在于下面的多个位置,那么 MyBatis 将按照以下顺序来加载它们:
- 首先,读取在 properties 元素体中指定的属性;
- 其次,读取在 properties 元素的类路径 resource 或 url 指定的属性,且会覆盖已经指定了的重复属性;
- 最后,读取作为方法参数传递的属性,且会覆盖已经从 properties 元素体和 resource 或 url 属性中加载了的重复属性。
因此,通过方法参数传递的属性的优先级最高,resource 或 url 指定的属性优先级中等,在 properties 元素体中指定的属性优先级最低。
总结一下,前四个方法很大程度上是相同的,但提供了不同的覆盖选项,允许你可选地指定 environment 和/或 properties。以下给出一个从 mybatis-config.xml 文件创建 SqlSessionFactory 的示例:
- String resource = "org/mybatis/builder/mybatis-config.xml";
- InputStream inputStream = Resources.getResourceAsStream(resource);
- SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
- SqlSessionFactory factory = builder.build(inputStream);
注意,这里我们使用了 Resources 工具类,这个类在 org.apache.ibatis.io 包中。Resources 类正如其名,会帮助你从类路径下、文件系统或一个 web URL 中加载资源文件。在略读该类的源代码或用 IDE 查看该类信息后,你会发现一整套相当实用的方法。这里给出一个简表:
- URL getResourceURL(String resource)
- URL getResourceURL(ClassLoader loader, String resource)
- InputStream getResourceAsStream(String resource)
- InputStream getResourceAsStream(ClassLoader loader, String resource)
- Properties getResourceAsProperties(String resource)
- Properties getResourceAsProperties(ClassLoader loader, String resource)
- Reader getResourceAsReader(String resource)
- Reader getResourceAsReader(ClassLoader loader, String resource)
- File getResourceAsFile(String resource)
- File getResourceAsFile(ClassLoader loader, String resource)
- InputStream getUrlAsStream(String urlString)
- Reader getUrlAsReader(String urlString)
- Properties getUrlAsProperties(String urlString)
- Class classForName(String className)
最后一个 build 方法接受一个 Configuration 实例。Configuration 类包含了对一个 SqlSessionFactory 实例你可能关心的所有内容。在检查配置时,Configuration 类很有用,它允许你查找和操纵 SQL 映射(但当应用开始接收请求时不推荐使用)。你之前学习过的所有配置开关都存在于 Configuration 类,只不过它们是以 Java API 形式暴露的。以下是一个简单的示例,演示如何手动配置 Configuration 实例,然后将它传递给 build() 方法来创建 SqlSessionFactory。
- DataSource dataSource = BaseDataTest.createBlogDataSource();
- TransactionFactory transactionFactory = new JdbcTransactionFactory();
- Environment environment = new Environment("development", transactionFactory, dataSource);
- Configuration configuration = new Configuration(environment);
- configuration.setLazyLoadingEnabled(true);
- configuration.setEnhancementEnabled(true);
- configuration.getTypeAliasRegistry().registerAlias(Blog.class);
- configuration.getTypeAliasRegistry().registerAlias(Post.class);
- configuration.getTypeAliasRegistry().registerAlias(Author.class);
- configuration.addMapper(BoundBlogMapper.class);
- configuration.addMapper(BoundAuthorMapper.class);
- SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
- SqlSessionFactory factory = builder.build(configuration);
现在你就获得一个可以用来创建 SqlSession 实例的 SqlSessionFactory 了。