1

在 Java 应用程序中创建数据库连接的最佳方法是什么?使用单例、静态方法、服务定位器、连接池或其他什么?

请您让我知道上述每种方法的优缺点吗?

4

3 回答 3

3

有两种处理连接的方法:

  • 每个请求一个连接
  • 按需连接

每个请求一个连接意味着您在流程开始时获得连接,并在结束时返回它。这对于 Web 请求来说不是一个好主意,因为这意味着您的应用程序只能处理与可用的数据库连接一样多的并发 Web 请求。但是,对于批处理来说,这可能是一个好主意,因为您知道您只需要 N 个连接。

按需连接意味着您在即将进行 db 调用时获得连接,然后在 db 调用完成后立即返回。

在这两种情况下,都建议使用连接池,但它对于按需连接策略尤其重要,因为您希望连接在返回后保持打开状态,因为打开连接会产生很大的开销。

处理连接池一般有两种方式:

  • 容器管理
  • 应用程序管理

容器管理是指应用服务器通过 JNDI 向应用程序提供连接池。这是 JBoss 通常做的事情。如果它在那里,您不妨使用这种方法。否则,您应该使用应用程序托管池。

大多数 DI 框架都会为您提供一个连接池,只需进行少量配置。使用连接池确实没有明显的缺点。java中最常见的两个是DBCP和C3P0,都是非常成熟的库。如果您没有使用 DI 框架,您应该查看这些库的入门指南并实施他们的建议。

于 2012-08-29T11:37:03.143 回答
2

如果您的应用程序将使用许多连接,则最好使用连接池。它已经在 J​​ava 中实现,您可以轻松使用它。这个在使用 tomcat 的 web 应用程序中使用池的示例(如果您编写 web-app 也可以使用 tomcat 的池,这样会更好)

package usepool;

import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;

/**
*
* @author brainless
*/
public class ConnectionPool {

private static DataSource datasource;
public static String dbURL = "jdbc:mysql://localhost:3306/"
                + "<YourDataBase>?useUnicode=true&useEncoding=true&characterEncoding=UTF-8";
public static String driverClass = "com.mysql.jdbc.Driver";
public static String userName = "root";
public static String password = "password";
public static boolean jmx = true;
public static boolean testIdle = false;
public static boolean testBorrow = true;
public static boolean testReturn = false;
public static int validationInterval = 30000;
public static int timeBetweenEviction = 30000;
public static int maxActive = 100;
public static int initialSize = 10;
public static int maxWait = 10000;
public static int removeAbandonedTimeout = 60;
public static int minEvictableIdle = 30000;
public static int minIdle = 10;
public static boolean logAbandoned = true;
public static boolean removeAbandoned = true;
public static String jdbcInterceptors = "org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;"
        + "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer";

private ConnectionPool() {
}

public static synchronized DataSource getInstance() {
    if (datasource == null) {
        PoolProperties p = new PoolProperties();
        p.setUrl(dbURL);
        p.setDriverClassName(driverClass);
        p.setUsername(userName);
        p.setPassword(password);
        p.setJmxEnabled(jmx);
        p.setTestWhileIdle(testIdle);
        p.setTestOnBorrow(testBorrow);
        p.setTestOnReturn(testReturn);
        p.setValidationInterval(validationInterval);
        p.setTimeBetweenEvictionRunsMillis(timeBetweenEviction);
        p.setMaxActive(maxActive);
        p.setInitialSize(initialSize);
        p.setMaxWait(maxWait);
        p.setRemoveAbandonedTimeout(removeAbandonedTimeout);
        p.setMinEvictableIdleTimeMillis(minEvictableIdle);
        p.setMinIdle(minIdle);
        p.setLogAbandoned(logAbandoned);
        p.setRemoveAbandoned(removeAbandoned);
        p.setJdbcInterceptors(jdbcInterceptors);
        datasource = new DataSource();
        datasource.setPoolProperties(p);
    }
    return datasource;
}

public static synchronized void closePool() {
    if (datasource != null) {
        datasource.close();
    }
}

}

这个类是单例的。要在您的代码中获得连接,您需要使用类似这样的东西

import usepool.ConnectionPool;
/* 
* code
*/
connect = ConnectionPool.getInstance().getConnection();
于 2012-08-29T11:25:50.907 回答
0

在大多数 Java 应用程序中,这不如使用连接池重要。与使用连接池而不是手动管理连接所获得的便利和收益相比,您的问题更多的是个人喜好问题。

于 2012-08-29T10:55:23.973 回答