34

关于 JDBC 编码的几个问题:

  1. 对于单个客户端应用程序,我们是否需要连接池?
  2. Connection在开始时创建一个并保持它活着而不关闭它直到应用程序退出是一个好主意吗?为什么?
  3. PreparedStatement与 相关联Connection,如果每次查询后我的连接都没有关闭,为什么不保持PreparedStatement活动状态并在其他方法中重用它?
  4. 如果我们创建PreparedStatement每个查询,数据库是否知道它是相同的PreparedStatement并在第一次之后忽略不必要的操作?
  5. PreparedStatement是不是创建一次并重用多次语句?如果是,为什么每次都需要关闭它?

我知道调用close()将释放资源。但是,如果我们知道以后要使用它,为什么要释放它,然后再请求它呢?

多客户端应用程序怎么样?我们需要一个连接池,所以我们需要每次都创建和关闭 Connection,Statement和?PreparedStatement

4

2 回答 2

16

就我个人而言,我会使用一个池,因为它会为你处理所有的资源管理。如果您的连接要求发生变化,那么您可以轻松修改池配置。使用适当的池,您可以根据最佳实践打开/关闭连接和准备好的语句,并将资源管理留给池。

通常,在使用池时:

  • 关闭连接实际上只会将其返回到池中
  • 准备语句的行为将从连接的语句缓存中检索先前准备的语句,或者如果不可用,则创建一个新语句并将其缓存以供以后使用。
  • 关闭 PreparedStatement 的行为实际上只会将其返回到连接的语句缓存中。

此外 - 根据池的实现 - 它可能能够在发生资源泄漏时通知您,从而更容易识别代码中的此类问题。

看看像DBCP这样的示例实现的源代码- 看看它们是如何工作的非常有趣。

于 2009-06-24T16:43:21.240 回答
3

1.即使你只有一个客户端,连接池也可能是有益的。连接到数据库可能需要很长时间,因此经常这样做可能会因网络请求缓慢而降低应用程序的速度。此外,正如@teabot 解释的那样,池可能有助于识别是否有任何连接没有关闭。

2.打开一个连接并让它永远打开不是一个好主意,原因有两个。首先,如果网络暂时中断,连接可能会中断。它打开的时间越长,在需要时它就越有可能死掉。其次,失败的事务可能会使连接处于不适合继续操作的状态。最好的通常是打开几个连接,重复使用五到十分钟,然后回收它们。

3.根据数据库和驱动程序,连接可能有准备好的语句缓存。即使使用不同的连接,RDBMS 通常也会缓存完全相同的语句,包括它的参数。因此 SELECT * FROM table WHERE value=? 因为准备好的语句将跨连接缓存,但是如果您指定参数值,例如 SELECT * FROM table WHERE value='your_data' 那么它可能不会被缓存在服务器端。

4.如3所述,依赖于RDBMS的实现,做一个benchmark。

5.无需关闭并再次准备一条将要使用不同参数重用的语句。只需重新设置参数并执行。

对于多个客户端,数据库总是有一个并发连接限制,通常不是很大的数字。如果所有客户端都通过 webapp,那么像 DBCP 这样的池就可以了。但显然,为每个客户端创建一个永久打开多个连接的池是不可取的。

于 2016-12-01T14:29:00.093 回答