【问题标题】:Using PreparedStatement pooling in dbcp在 dbcp 中使用 PreparedStatement 池
【发布时间】:2010-09-21 20:35:02
【问题描述】:

有人能解释一下如何使用 dbcp 准备的连接池吗? (如果可能,请提供一些示例代码)。我已经想出了如何打开它 - 将 KeyedObjectPoolFactory 传递给 PoolableConnectionFactory。 但是具体的prepared statements应该如何定义呢? 现在我只使用 PoolingDataSource 从池中获取连接。如何使用池中的预处理语句?

【问题讨论】:

  • 你为 KeyedObjectPoolFactory 传递了什么? GenericKeyedObjectPoolFactory 的构造函数需要一个 KeyedPoolableObjectFactory,我不知道如何创建一个将使用 PreparedStatement 所针对的连接的构造函数。

标签: java prepared-statement connection-pooling apache-commons-dbcp


【解决方案1】:

关于从池中获取连接与获得“非池”连接,您的代码有什么变化吗:)?我打赌你不会。与准备好的语句相同。您的代码不应更改。因此,没有有用的代码示例。

您应该阅读有关您的 JDBC 数据源实现的文档,并了解开发人员对池的看法。没有其他可靠信息来源。

来自here: 该组件还具有池 PreparedStatements 的能力。启用后,将为每个 Connection 创建一个语句池,并且将池化由以下方法之一创建的 PreparedStatements:

* public PreparedStatement prepareStatement(String sql)
* public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)

因此,您只需继续使用 prepareStatement() 调用,理论上您的 dbcp 将负责池化(即,如果您尝试创建“select * from users u where u.name like :id”,它将尝试先在池中找到这个语句)

【讨论】:

  • 真的吗?那为什么 PoolableConnectionFactory 有一个用于语句池的参数呢?显然必须有某种方法来设置它。 Apache - 像往常一样 - 没有任何帮助。
  • @Dan:想扩展您的评论?你不同意我回答的哪一部分?如果您再次阅读该问题,作者已经知道如何启用语句池。他想知道他需要对代码进行哪些更改(如果有的话)。
  • 很抱歉,由于 Apache 通常缺乏文档,所以有点胡思乱想。
【解决方案2】:

这是我使用的基本代码。

    GenericObjectPool connectionPool = new GenericObjectPool(null);
    connectionPool.setMinEvictableIdleTimeMillis(1000 * 60 * 30);
    connectionPool.setTimeBetweenEvictionRunsMillis(1000 * 60 * 30);
    connectionPool.setNumTestsPerEvictionRun(3);
    connectionPool.setTestOnBorrow(true);
    connectionPool.setTestWhileIdle(false);
    connectionPool.setTestOnReturn(false);

    props = new Properties();
    props.put("user", username);
    props.put("password", password);
    ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(url, props);

    PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, connectionPool, null, "SELECT 1", false, true);
    PoolingDataSource dataSource = new PoolingDataSource(connectionPool);

【讨论】:

  • 这不可能。根据 commons.apache.org/dbcp/apidocs/org/apache/commons/dbcp/…, org.apache.commons.pool.ObjectPool, org.apache.commons.pool.KeyedObjectPoolFactory, java.lang.String, boolean, boolean) 为 PoolableConnectionFactory 的第三个参数传递 null 会禁用 PreparedStatement 缓存。该论点应该使用什么?
【解决方案3】:

问题是,如果您使用单个 Connection,无论您是否需要,它都会缓存 PreparedStatements,唯一可能影响这一点的方法是使用 DataSource 属性或使用特定于供应商的属性API。但是这些语句对其他连接不可见,如果您使用另一个连接准备相同的语句,它将再次重新创建它。所以像 DBCP 这样的连接池允许在不同的连接之间重用PreparedStatements(它使用PooledConnection 接口而不是简单的Connection),它们跟踪所有连接准备的所有语句。

更新:看来我对这个信息有误,至少我在 C3P0 中找不到这个功能。

【讨论】:

    猜你喜欢
    • 2012-08-29
    • 2019-03-03
    • 2013-01-06
    • 2011-11-17
    • 2013-09-04
    • 1970-01-01
    • 2013-11-29
    • 2017-04-19
    相关资源
    最近更新 更多