作用域(Scope)和生命周期
这个主要是讲sqlSessionFactoryBuilder
、sqlSessionFactory
和sqlSession
三者的作用域和生命周期,先看这三者的关系(接下来的比喻可能都不恰当,但是是我的理解,有错误希望可以指出)
6.1 sqlSessionFactoryBuilder:
sqlSessionFactoryBuilder的作用就是通过xml文件来建造一个sqlSessionFactory。
我们可以想象成它是一个工厂的施工队(乙方)
另外一个是工厂的老板(甲方)
xml文件是甲方提供给乙方的建造图纸
回想一下平时的建筑工业:乙方建造好,拿到钱就可以走了。不需要在留在这个地方,它还可以接别的建造单。
所以再读官方文档给的话(如下)
这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但最好还是不要一直保留着它,以保证所有的 XML 解析资源可以被释放给更重要的事情。
以保证所有的 XML 解析资源可以被释放给更重要的事情。 对于这句话的理解就是,xml文件种不仅仅只有工厂的建造图纸,还有产品的生产指南mapper.xml,存放sql的地方
6.2 sqlSessionFactory
生活种的工厂都是建造完就一直生产产品的,应该没有哪个老板那么大气,建造好一个工厂生产了一个产品以后就把它拆掉,然后再建立一个。
所以官方文档对这个的解释也是比较好理解的
SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏习惯”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。
6.3 sqlSession
我对这个的理解就是:它是工厂里的生产线,对照的生产图纸就是<mappers>
标签里的内容。
一个生产线可以生产一种产品,如果多条生产线混合生产,那就会造成混乱。
如果这个生产线结束了,那就应该把里面的机器等都关闭,不然电费和人力费可能会让老板亏损。
所以相对于工厂的稳定存在,生产线是不一定稳定存在的
官网原话如下:
每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。 如果你现在正在使用一种 Web 框架,考虑将 SqlSession 放在一个和 HTTP 请求相似的作用域中。 换句话说,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 这个关闭操作很重要,为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中。
6.4 总结
作用域 | 生命周期 | |
---|---|---|
sqlSessionFactoryBuilder | 方法作用域(局部) | 生产完sqlSessionFactory就结束 |
sqlSessionFactory | 应用作用域 | 运用期间一直在运行 |
sqlSession | 请求或方法作用域 | 使用结束后需要关闭 |