在许多类之间共享JDBC连接池

时间:2011-11-21 22:21:33

标签: java jdbc connection-pooling

我将一些c3p0池封装在一个用于执行SQL语句的类中。 它以这种方式初始化:

public PooledQueryExecutor(String url, Properties connectionProperties) throws DALException {
        try {
            dataSource = new ComboPooledDataSource();
            dataSource.setDriverClass(DRIVER);
            dataSource.setJdbcUrl(url);
            dataSource.setProperties(connectionProperties);
        } catch (PropertyVetoException ve) {
            throw new DALException(ve);
        }
    }

然后 - 在同一个类中 - 我使用一些方法来执行基本任务:

public CachedRowSet executeSelect(String sql) throws DALException {
        // Get a connection, execute the SQL, return the rows that match, return resources to the pool
    }

“问题”是:
我有很多不同的类代表我收到的网络数据包。大多数类需要使用这个PooledQueryExecutor来执行数据库操作,但有些不需要。我是否将这个PooledQueryExecutor传递给需要它的类的构造函数(80%的数据包),还是让PooledQueryExecutor成为单例?或者也许是“其他东西”?我也使用ThreadLocal来避免污染我的构造函数,但我认为这不是一个好主意,是吗?

编辑:它不是Web应用程序,目前没有使用依赖注入框架。

感谢您的时间!

4 个答案:

答案 0 :(得分:2)

我假设您没有使用任何DI框架?如果是这种情况,您有几个选择:

  • PooledQueryExecutor传递给需要它的类的构造函数。从测试和架构的角度来看,这实际上非常好。

  • 让需要JDBC的类实现一些简单的界面,如:


interface PooledQueryExecutorAware {

    void setPooledQueryExecutor(PooledQueryExecutor executor);

}

然后你甚至可以遍历类并发现哪些实现了这个,并且注入 PooledQueryExecutor。你是在这里重新发现DI的一步,但没关系。

  • 类似的方法是创建一个抽象基类,该基类需要PooledQueryExecutorAware作为依赖项,并且protected final字段持有它。

  • 每个类都知道PooledQueryExecutor - 不推荐,不必要的耦合

  • Singleton是你能做的最差的,不可测试且难以理解的代码。请不要。

  • ThreadLocal?忘掉它。请记住,显性是王道。

另请查看JdbcTemplate。它是Spring的一部分,但是你可以只使用spring-jdbc.jar而不使用整个框架。我认为它可以轻松取代PooledQueryExecutor

答案 1 :(得分:0)

我更喜欢设置(注入)池。这样你可以决定某些实例是否应该获得不同的池,你可以用记录器等包装池,并且很清楚哪些类需要池。

我也认为这使代码更容易测试。

答案 2 :(得分:0)

常见的方法,例如Web服务器是让JNDI启动并运行,然后从JNDI获取数据源。 Simpel JDNI实现适用于独立应用程序。

如果在程序中使用依赖注入,那么这是可以在需要时注入的资源的一个很好的示例。这可能意味着Java EE 6或启用Spring / Guice / CDI的应用程序。

答案 3 :(得分:0)

对象代表网络数据包?他们使用数据库连接是什么?这对我来说不合适。您想更多地谈谈您正在尝试做什么,以及您的架构是什么?

我倾向于使数据包对象成为域的纯模型 - 它们可以保持状态,并且它们应该定义行为,但是它们不应该在数据库中徘徊。数据库访问应该是系统的不同部分,存储层或子系统。它中的关键对象很可能是单例(或者,至少它们将只有一个实例,即使它们不是正式的单例),并且能够自然地包含单个全局连接池。 / p>

然后存在域对象如何与存储子系统交互的问题。实际上,在您询问有关连接池时,您的问题基本相同。一般来说,我希望有一些控制器对象来协调程序的工作;他们可以很好地与不同层次的物体交谈,并将它们彼此介绍。

具体示例可以使这种解释更容易。告诉我们您的数据包!