31

以下是我获取数据库连接的助手类:

我已经使用了这里描述的 C3P0 连接池。

public class DBConnection {

    private static DataSource dataSource;
    private static final String DRIVER_NAME;
    private static final String URL;
    private static final String UNAME;
    private static final String PWD;

    static {

        final ResourceBundle config = ResourceBundle
                .getBundle("props.database");
        DRIVER_NAME = config.getString("driverName");
        URL = config.getString("url");
        UNAME = config.getString("uname");
        PWD = config.getString("pwd");

        dataSource = setupDataSource();
    }

    public static Connection getOracleConnection() throws SQLException {
        return dataSource.getConnection();
    }

    private static DataSource setupDataSource() {
        ComboPooledDataSource cpds = new ComboPooledDataSource();
        try {
            cpds.setDriverClass(DRIVER_NAME);
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
        cpds.setJdbcUrl(URL);
        cpds.setUser(UNAME);
        cpds.setPassword(PWD);
        cpds.setMinPoolSize(5);
        cpds.setAcquireIncrement(5);
        cpds.setMaxPoolSize(20);
        return cpds;
    }
}

在 DAO 我会写这样的东西:

try {
            conn = DBConnection.getOracleConnection();

            ....


} finally {
    try {
        if (rs != null) {
            rs.close();
        }
        if (ps != null) {
            ps.close();
        }
        if (conn != null) {
            conn.close();
        }
    } catch (SQLException e) {
        logger
                .logError("Exception occured while closing cursors!", e);

    }

现在,我的问题是除了关闭 finally 块中列出的游标(连接/语句/resultSet/preparedStatement)之外,我是否应该费心做任何其他清理工作。

这是什么清理??我应该在何时何地进行此操作?

如果您发现上述代码有任何错误,请指出。

4

4 回答 4

26

对于池化数据源,池中的连接实际上并没有关闭,它们只是返回到池中。但是,当应用程序关闭时,那些与数据库的连接应该正确并实际关闭,这就是最终清理的地方。

顺便说一句,c3p0 项目几乎已经死了,我建议您改用Apache Commons DBCP,它仍在维护中。

于 2009-09-22T08:01:18.783 回答
6

DAO 不应该负责获取与数据库的连接。他们无法知道它们何时被用作更大交易的一部分。您应该将数据源或连接实例传递到 DAO。

如果 finally 块中的任何关闭调用引发异常,则不会调用任何后续调用。每个都需要在自己的 try/catch 块中。我将它们作为静态方法放入实用程序类中。

于 2009-09-22T09:53:48.323 回答
5

代码对我来说看起来不错,但我会编写一个辅助方法来执行关闭操作,否则你会在每个 DAO 或方法中得到这个冗长的 finally 块。也许您应该在 close 操作周围编写三个单独的 try-catch-blocks,以确保无论语句和结果集是否引发了执行,连接都已关闭。另请注意,javadoc 说

当 Statement 对象关闭时,其当前的 ResultSet 对象(如果存在)也将关闭。

所以你不需要关闭上面例子中的结果集,但是你可以。

链接清理方法用于关闭数据源,大多数项目不需要这样做,因为只要您的应用程序正在运行,DS 就会存在。

于 2009-09-22T08:03:37.560 回答
0

我使用 Play Framework 和 Scala,所以以下示例在 play 项目中。

第1步。配置

在 build.sbt 中,如果使用 mysql/hive 作为数据库,则需要添加这些属性。

libraryDependencies ++ = Seq (
   jdbc,
  "mysql" % "mysql-connector-java" % "5.1.31",
  "org.apache.hive" % "hive-jdbc" % "0.12.0",
  "com.mchange" % "c3p0" % "0.9.2.1"
)

第2步。如何访问它?您需要导入 c3p0 库。

import com.mchange.v2.c3p0.ComboPooledDataSource

第三步。然后你需要创建实例。

val cpds = new ComboPooledDataSource()
cpds.setDriverClass(...)
cpds.setJdbcUrl(...)
cpds.setUser(...)
cpds.setPassword(...)

第4步。你得到一个连接

cpds.getConnection
于 2014-11-24T20:43:54.297 回答