MySQL - 使用Singleton模式或ConnectionPool连接?

时间:2009-10-11 20:15:30

标签: mysql jdbc singleton connection-pooling

以前的一些问题已经讨论过这个话题。新元素带来了新问题。我在这里寻求处理数据库连接的最佳方法,涉及以下方面:可维护性性能安全性实施。我必须提一下,我现在对Hibernate,Spring等抽象不感兴趣。以下是事实:


场景1 - 单身人士模式


这里的主要思想是:验证连接细节,实例化连接,为她编写静态getter,并在需要时使用它。代码示例:

  static Connection connection;
  private Statement stmt = null;

  connection = createConnection(...)
  stmt = connection.createStatement();

将使用以下命令执行查询:

  stmt.execute();

现在,这可能听起来不太花哨,但是......有效。我可以完全控制我的连接,关闭它,实例化它,关闭resultSet(必须由每个调用者完成)等等。


场景2 - 具有PreparedStatement的单例模式


正如有些人在这里建议的,我已经引入了PreparedStatement来执行查询,基本上我已经删除了 stmt 变量,而是使用了表达式:

PreparedStatement pStmt= getConnection().prepareStatement(query);
pStmt.execute();

使用PMD代码分析器,我注意到 pSmt 可能无法关闭,这是真的,因为我无法在这里关闭它,我也无法指示调用者关闭它。这种方法导致了下一个场景。


场景3 - 具有静态PreparedStatement的单例模式


所有的一切,我已经宣布:

private static PreparedStatement preparedStmt = null;

我的executeQuery()方法适应:

setPreparedStmt(getConnection().prepareStatement(query));
getPreparedStmt().execute();

其中setter和getter只是.. setter和getter,具有公共可见性和静态属性。 这种方法很容易理解,并且调用者必须关闭PreparedStatement他们自己(没问题,但是关闭PreparedStatement也会关闭ResultSet,如果是这样的话?)。但是,不知何故,我觉得重复使用这个预编译的语句对于数据库的事务方面并不是那么安全。这里有危险吗?


场景4 - 使用连接池


这方面需要进一步研究,但我得到了主要的想法。我不能详细介绍这种做法,但这里也有一些问题:

4.1我知道可以设置连接数,即池的最大大小。例如,这个数字对于单个用户来说是多少,结果是我将该数字乘以用户数。

4.2使用连接池,从池中获取一个连接并使用它来执行某些查询时,我应该使用Statement还是PreparedStatement

4.3我的理解是使用这个策略,我必须在他的任务完成后关闭连接。但是,如果由于某些原因,连接未能关闭呢?如果那样,由于某种原因,重复多次等于连接池大小..我们注定要失败。

好的,我会在这里停下来,也许会有一些更新,取决于答案。曼尼谢谢。

1 个答案:

答案 0 :(得分:1)

在几乎所有可以想象的情况下,我都会使用连接池。可维护性,性能和实施方面已为您完成。大多数服务器为您提供可通过JNDI访问的内置数据源,并且还有独立的连接池。

对于安全性,请为需要用户输入参数的任何查询使用预准备语句。这样,用户输入就永远不会允许SQL注入攻击。

关于你的问题:

4.1 :理想情况下,每个网页请求都会使用1个连接。因此,为了弄清楚您需要多少总池连接,您需要计算每个平均查询时间(例如,每秒请求数)的请求数量。除非该数字很高,否则大多数连接池提供的默认连接数就足够了(通常是20,就我所见)。

4.2 :您可以使用来自池中的Connection的Statement或PreparedStatement。在大多数情况下(包括查询中使用的任何用户输入),您应该使用PreparedStatements。

4.3 :如果你把你的连接关闭代码放在try语句的finally块中并记得每次访问数据库时都这样做,那么你应该永远不会遇到用完的问题连接。