Mybatis官方文档里对SqlSession对象的作用域范围这样说明:
每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。 如果你现在正在使用一种 Web 框架,考虑将 SqlSession 放在一个和 HTTP 请求相似的作用域中。 换句话说,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。这个关闭操作很重要,为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中。 下面的示例就是一个确保SqlSession 关闭的标准模式:
try (SqlSession session = sqlSessionFactory.openSession()) {
// 你的应用逻辑代码
}
在所有代码中都遵循这种使用模式,可以保证所有数据库资源都能被正确地关闭。
问题
读到这里有一丝疑惑,它这也没写finally,也没写close()方法啊,怎么就能确保SqlSession关闭呢?不用多想,一百度就有了答案。
以下内容摘自:java try(){}catch(){}自动资源释放
从 Java 7 build 105 版本开始,Java 7 的编译器和运行环境支持新的 try-with-resources 语句,称为 ARM 块(Automatic Resource Management) ,自动资源管理。数据流会在 try 执行完毕后自动被关闭,前提是,这些可关闭的资源必须实现 java.lang.AutoCloseable 接口。
打开SqlSession源码一看,果真实现了AutoCloseable接口。
官方文档说明
AutoCloseable的接口说明中也明确了其作用:
AutoCloseable是一种在关闭之前可以保存资源(例如文件或套接字句柄)的对象。 当退出try -with-resources块(已在资源规范头中为其声明对象)时,将自动调用AutoCloseable对象的close()方法。 这种构造可确保及时释放,避免资源耗尽异常和可能发生的错误。