我使用JDBC连接池吗?

我想确定我是否实际使用JDBC连接池。 经过一番研究,实现起来似乎太简单了。 实际上比常规连接更容易,所以我想validation一下。

这是我的连接类:

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 ,那么是的,你正在使用连接池。 但是,您正在每个连接获取上重新创build另一个连接池。 你不是真的从同一个池中汇集连接。 您只需在应用程序启动时创build连接池一次,并从中获取每个连接。 你也不应该把连接作为一个实例variables。 您还应closures连接,语句和结果集,以确保资源已正确closures,并且在出现exception的情况下。 Java 7的try-with-resources语句在这方面很有帮助,它会在try块完成时自动closures资源。

这是一个小改写:

 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的创build委托给容器/应用程序服务器,并从JNDI获取。 在Tomcat的情况下,也可以参考这个文档: http : //tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html

似乎不像它汇集。 您应该将DataSource存储在DatabaseConnection中,而不是使用getConnection()调用创build一个新的DataSource。 getConnection()应该返回datasource.getConnection()。

看起来像一个DBCP用法。 如果是这样,那么是的。 它已经合并。 这里是DBCP的默认池属性值。

 /** * The default cap on the number of "sleeping" instances in the pool. * @see #getMaxIdle * @see #setMaxIdle */ public static final int DEFAULT_MAX_IDLE = 8; /** * The default minimum number of "sleeping" instances in the pool * before before the evictor thread (if active) spawns new objects. * @see #getMinIdle * @see #setMinIdle */ public static final int DEFAULT_MIN_IDLE = 0; /** * The default cap on the total number of active instances from the pool. * @see #getMaxActive */ public static final int DEFAULT_MAX_ACTIVE = 8; 

作为BalusC解决scheme的后续,下面是一个实现,我可以在需要多个连接的应用程序中使用,或者在一个公共库中预先不知道连接属性。

 import org.apache.commons.dbcp.BasicDataSource; import java.sql.Connection; import java.sql.SQLException; import java.util.concurrent.ConcurrentHashMap; public final class Database { private static final ConcurrentHashMap<String, BasicDataSource> dataSources = new ConcurrentHashMap(); private Database() { // } public static Connection getConnection(String connectionString, String username, String password) throws SQLException { BasicDataSource dataSource; if (dataSources.containsKey(connectionString)) { dataSource = dataSources.get(connectionString); } else { dataSource = new BasicDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl(connectionString); dataSource.setUsername(username); dataSource.setPassword(password); dataSources.put(connectionString, dataSource); } return dataSource.getConnection(); } }