mysql - 我在使用 JDBC 连接池吗?

标签 mysql jakarta-ee jdbc connection-pooling

我正在尝试确定我是否真的在使用 JDBC 连接池。在做了一些研究之后,实现似乎太容易了。实际上比常规连接更容易,所以我想验证一下。

这是我的连接类:

public class DatabaseConnection {

Connection conn = null;

public Connection getConnection() {

    BasicDataSource bds = new BasicDataSource();
    bds.setDriverClassName("com.mysql.jdbc.Driver");
    bds.setUrl("jdbc:mysql://localhost:3306/data");
    bds.setUsername("USERNAME");
    bds.setPassword("PASSWORD");

    try{
        System.out.println("Attempting Database Connection");
        conn = bds.getConnection();
        System.out.println("Connected Successfully");
    }catch(SQLException e){
        System.out.println("Caught SQL Exception: " + e);
    }
    return conn;
}

public void closeConnection() throws SQLException {
    conn.close();
}

}

这是真正的连接池吗?我在另一个类中使用连接:

        //Check data against database.
    DatabaseConnection dbConn = new DatabaseConnection();
    Connection conn;
    ResultSet rs;
    PreparedStatement prepStmt;

    //Query database and check username/pass against table.
    try{
        conn = dbConn.getConnection();
        String sql = "SELECT * FROM users WHERE username=? AND password=?";
        prepStmt = conn.prepareStatement(sql);
        prepStmt.setString(1, user.getUsername());
        prepStmt.setString(2, user.getPassword());
        rs = prepStmt.executeQuery();

        if(rs.next()){ //Found Match.
            do{
                out.println("UserName = " + rs.getObject("username") + " Password = " + rs.getObject("password"));
                out.println("<br>");
            } while(rs.next());
        } else {
            out.println("Sorry, you are not in my database."); //No Match.
        }

        dbConn.closeConnection(); //Close db connection.

    }catch(SQLException e){
        System.out.println("Caught SQL Exception: " + e);
    }

最佳答案

假设是 BasicDataSource来自 DBCP ,那么是的,您正在使用连接池。但是,您在每次连接获取时都重新创建另一个连接池。您并没有真正从同一个池中汇集连接。您只需在应用程序启动时创建一次连接池并从中获取每个连接。您也不应该将连接保留为实例变量。您还应该关闭连接、语句和结果集,以确保正确关闭资源,即使出现异常也是如此。 Java 7 的 try-with-resources statement在这方面很有帮助,它会在 try block 完成时自动关闭资源。

这是一个小的重写:

public final class Database {

    private static final BasicDataSource dataSource = new BasicDataSource();

    static {
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/data");
        dataSource.setUsername("USERNAME");
        dataSource.setPassword("PASSWORD");
    }

    private Database() {
        //
    }

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

}

(如有必要,可以将其重构为抽象工厂以提高可插拔性)

private static final String SQL_EXIST = "SELECT * FROM users WHERE username=? AND password=?";

public boolean exist(User user) throws SQLException {
    boolean exist = false;

    try (
        Connection connection = Database.getConnection();
        PreparedStatement statement = connection.prepareStatement(SQL_EXIST);
    ) {
        statement.setString(1, user.getUsername());
        statement.setString(2, user.getPassword());

        try (ResultSet resultSet = preparedStatement.executeQuery()) {
            exist = resultSet.next();
        }
    }       

    return exist;
}

按如下方式使用:

try {
    if (!userDAO.exist(username, password)) {
        request.setAttribute("message", "Unknown login. Try again.");
        request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
    } else {
        request.getSession().setAttribute("user", username);
        response.sendRedirect("userhome");
    }
} catch (SQLException e) {
    throw new ServletException("DB error", e);
}

在真正的 Java EE 环境中,您应该将 DataSource 的创建委托(delegate)给容器/应用程序服务器并从 JNDI 获取。在 Tomcat 的情况下,另请参见以下文档:http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html

关于mysql - 我在使用 JDBC 连接池吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7592056/

相关文章:

java - 如何以字符串形式发送参数

php - 在每个查询的基础上重置 mysqli 缓存

mysql - 通过本地 phpMyAdmin 的 Google Cloud SQL 实例

c# - jBPM自定义授权

java - 如何将动态配置文件编号映射到 servlet?

java - Spring TransactionTemplate setPropagationBehavior

mysql - 如何计算每行的2个时间戳之间的总差

mysql - NDB集群创建撤消日志和数据文件

java - 如果同时有 100 个 doGet() 请求到一个 servlet,它会阻塞其他 99 个请求直到被调用的 doGet() 返回吗?

java - 无法打印从服务器传输到客户端的结果集