注入 MyBatis 组件
本节将带你详细了解发现和注入的过程。
创建一个工厂
SqlSessionFactory
是 MyBatis 组件的开始,因此首先需要创建它,
并让容器知道它的存在。 要做到这一点,请使用 producer 方法创建一个组件,并确保添加了 @ApplicationScoped
注解。因为我们只希望在整个应用程序中拥有一个工厂的实例。
为了让容器标识要使用的生产者,你必须用 @SessionFactoryProvider
:
public class MyProducers {
@Produces
@ApplicationScoped
@SessionFactoryProvider
public SqlSessionFactory produceFactory() {
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
return sqlSessionFactory;
}
}
NOTE
如果你忘记添加 @ApplicationScoped
,工厂将在每次注入时创建,这意味着将解析和加载所有的 MyBatis xml 文件。你的应用程序不会有问题,但速度会非常慢。
NOTE
如果你忘记了 @SessionFactoryProvider
,该工厂将被 mybatis-cdi 忽略。
发现和注入映射器
没有什么比将映射器作为 CDI 依赖注入更特别的了:
public class FooService {
@Inject UserMapper userMapper;
public User doSomeStuff(String userId) {
return this.userMapper.getUser(userId);
}
}
然后,它将从 CDI 容器中注册的 SqlSessionFactory
中获取该映射器的实例(实际上是代理) ,并将其注入到组件中。这个代理不是一个普通的映射器,而是一个线程安全的单例,所以你不需要担心它的作用域。
在初始化过程中可能发生的任何配置问题都会使模块抛出
MyBatisCdiConfiurationException
。考虑到没有太多需要配置的东西,只有当 SqlSessionFactory
找不到或配置错误时,才会抛出此异常。
解决歧义
如果有多个 SqlSessionFactory
,则可以使用以下方法选择要在任何注入点中使用的一个:
- 使用一个或多个限定符(由你定义)
- 为
SqlSessionFactory
命名(使用@Named
注解) - 还可以将它们组合使用
下面是一个代码段,该代码段创建了两个 SqlSessionFactory
的 producer。限定符用于区分它们,就像处理任何其他 CDI 组件一样:
@ApplicationScoped
@Produces
@FooQualifier
@SessionFactoryProvider
public SqlSessionFactory createManagerFoo() throws IOException {
...
}
@ApplicationScoped
@Produces
@BarQualifier
@SessionFactoryProvider
public SqlSessionFactory createManagerBar() throws IOException {
...
}
现在没有歧义了,你可以通过向其添加限定符来选择要注入的工厂:
@Inject @FooQualifier UserMapper userMapper;
你还可以为 SqlSessionFactory
命名:
@ApplicationScoped
@Produces
@Named("fooManager")
@SessionFactoryProvider
public SqlSessionFactory createManager() throws IOException {
...
}
在注入点中用它的名字来代替它:
@Inject @Named("fooManager") UserMapper userMapper;
注入 SqlSession
你可以通过请求注入线程安全的 SqlSession
,如下所示:
@Inject SqlSession sqlSession;
我们看到的映射器的工厂选择标准也适用于 SqlSession
注入。
NOTE
MyBatis-CDI 控制注入的 SqlSession
的生命周期,因此你不能调用任何事务方法,如 commit()
或 rollback()
。也没有像 close()
这样的生命周期方法。