DBUtils QueryRunner 实例化

Posted

技术标签:

【中文标题】DBUtils QueryRunner 实例化【英文标题】:DBUtils QueryRunner instantiation 【发布时间】:2013-01-30 22:48:18 【问题描述】:

我有一个 Web 服务,它在初始化时使用数据源实例化单个 QueryRunner。它通过将这个QueryRunner 对象作为servlet 上下文属性传递给来自webapp 使用的多个不同servlet 的所有servlet 请求。即:

// in servlet context listener (on app initialization)
QueryRunner myQueryRunner = new QueryRunner(myDataSource);
myServletContext.setAttribute("queryRunner", myQueryRunner);

// in the servlets
QueryRunner myQueryRunner = (QueryRunner) myServletContext.getAttribute("queryRunner");
myQueryRunner.query(myStoredProcedure, handler, params)

我试图弄清楚这是否是一个瓶颈。 servlet 是否应该为每个请求都实例化一个新的QueryRunner

在四处寻找答案时,我还发现了这个AsyncQueryRunner。但我只是变得更加困惑,因为 API 文档中对 QueryRunner 和 AsyncQueryRunner 的解释说的完全一样。

我查看了示例here,似乎应该在每个请求中实例化它,但我不确定这是否只是因为它是示例代码。

换句话说,当使用 DBUtils QueryRunner 时,我应该:

    为每个请求使用单个QueryRunner 实例? (我是什么 现在做) 为每个 servlet 请求实例化一个新的QueryRunner? 为每个请求使用单个 AsyncQueryRunner 实例?

【问题讨论】:

我想弄清楚这是否是一个瓶颈。这是不可能的。 QueryRunner 是一个线程安全的类,您可以对所有请求使用单个 QueryRunner。 AsyncQueryRunner 使用 ThreadPool 处理每一个查询,但不是正常情况,它只用于长查询花费。 【参考方案1】:

QueryRunner 是一个线程安全的类,因为它是无状态的,因此您可以在多线程环境中使用单个实例而不会出现任何问题。

所有方法都是自包含的,因此无需同步方法访问,因此您也可以排除瓶颈。

我在生产环境中使用它没有问题,但我的实现遵循“用每个语句实例化一个新的 QueryRunner”的模式,因为它是一个没有状态的委托类,所以没有繁重的初始化和堆消耗,我避免使用单例或其他共享实例来存储这种类型的类。

AsyncQueryRunner 也是线程安全的,但其用途和用法完全不同(请参阅http://commons.apache.org/proper/commons-dbutils/examples.html)。它用于为长时间运行的语句创建非阻塞调用。如果您的业务层需要异步,它可能会很有用。

总结:

使用来自多个线程的单个 QueryRunner 实例(每个请求一个线程?)没有反指示,但也没有优势,但在某处需要一点代码来管理此实例 为每个线程甚至是要通过它委托的每个语句使用新的 QueryRunner 实例有两个主要优点:简单和本地化的使用,如果不需要它们,内存中不会有实例。 AsyncQueryRunner 需要对查询响应进行繁琐的管理,因此只有在业务代码中需要异步行为时才使用它。

【讨论】:

以上是关于DBUtils QueryRunner 实例化的主要内容,如果未能解决你的问题,请参考以下文章

后端开发Druid数据库连接池,DbUtils.QueryRunner和DbUtils.closeQuietly的使用实例

后端开发Druid数据库连接池,DbUtils.QueryRunner和DbUtils.closeQuietly的使用实例

Apache—DBUtils框架简介DbUtils类QueryRunner类 ResultSetHandler接口

QueryRunner类

commons-dbutils学习——QueryRunner类和ResultSetHandler接口介绍

[JavaWeb]关于DBUtils中QueryRunner的一些解读.