MyBatis 作用域和生命周期

2020-03-18   92 次阅读


生命周期,和作用域,是至关重要的,因为错误的使用会导致非常严重的并发问题。

1. SqlSessionFactoryBuilder


这个类可以在任何时候被实例化、使用和销毁。一旦您创造SqlSessionFactory 就不需要再保留它了。所以SqlSessionFactoryBuilder 实例的最好的作用域是方法体内(即一个本地方法变量)。您能重用SqlSessionFactoryBuilder 创建多个SqlSessionFactory 实例,但最好不要把时间、资源放在解析XML 文件上,而是要从中解放出来做最重要事情。

个人理解:

●一旦创建了SqISessionFactory, 就不再需要它了
●局部变量

2. SqlSessionFactory

一旦创建,SqlSessionFactory 将会存在于您的应用程序整个运行生命周期中。很少或根本没有理由去销毁它或重新创建它。最佳实践是不要在一个应用中多次创建SqlSessionFactory。这样做会被视为“没品味”。所是SqlSessionFactory 最好的作用域范围是一个应用的生命周期范围。这可以由多种方式来实现,最简单的方式是使用Singleton 模式或静态Singleton 模式。但这不是被广泛接受的最佳做法,相反,您可能更愿意使用像Google Guice 或Spring 的依赖注入方式。这些框架允许您创造一个管理器,用于管理SqlSessionFactory 的生命周期。

个人理解:

●说白了就是可以想象为:数据库连接池
●SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。
●因此SqISessionFactory的最佳作用域是应用作用域。
●最简单的就是使用单例模式或者静态单例模式。

3. SqlSession

每个线程都有一个SqlSession 实例,SqlSession 实例是不被共享的,并且不是线程安全的。因此最好的作用域是request 或者method。决不要用一个静态字段或者一个类的实例字段来保存SqlSession 实例引用。也不要用任何一个管理作用域,如Servlet 框架中的HttpSession,来保存SqlSession 的引用。如果您正在用一个WEB 框架,可以把SqlSession 的作用域看作类似于HTTP 的请求范围。也就是说,在收到一个HTTP 请求,您可以打开一个SqlSession,当您response 返回时,就可以把SqlSession 关闭。关闭会话是非常重要的,您应该要确保会话在一个finally 块中被关闭。

SqlSession session = sqlSessionFactory.openSession();
try {
    // do work
} finally {
    session.close();
}

个人理解:

●连接到连接池的一个请求!
●SqISession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域
●用完之后需要赶紧关闭,否则资源被占用!

在您的代码里都使用这一模式将保证所有的数据库资源被正确地关闭(假如您没有把您自己的数据库连接传递给MyBatis 管理,这就对MyBatis 表明您希望自己管理连接)。

SqlSession session = sqlSessionFactory.openSession();
try {
    BlogMapper mapper = session.getMapper(BlogMapper.class);
    // do work
} finally {
    session.close();
}

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

如人饮水、冷暖自知