我试图确定我是否实际上正在使用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语句对此很有帮助,它会在try块完成后自动关闭资源。
BasicDataSource
try-with- resources
try
这是一个小的重写:
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给容器/应用程序服务器,并从JNDI获取它。如果是Tomcat,请另参见本文档的示例:http : //tomcat.apache.org/tomcat-6.0-doc/jndi-resources- howto.html
DataSource