2011-09-29 37 views
22

Tôi đang cố gắng xác định xem tôi có thực sự đang sử dụng kết nối JDBC hay không. Sau khi thực hiện một số nghiên cứu, việc triển khai gần như có vẻ quá dễ dàng. Dễ dàng hơn một kết nối thông thường trong thực tế vì vậy tôi muốn xác minh.Tôi có đang sử dụng kết nối JDBC không?

Đây là lớp kết nối của tôi:

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(); 
} 

}

là kết nối này tổng hợp đúng không? Tôi đang sử dụng kết nối trong lớp khác như vậy:

 //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); 
    } 

Trả lời

45

Giả sử rằng đó là BasicDataSource là từ DBCP, sau đó có, bạn đang sử dụng một hồ bơi kết nối. Tuy nhiên, bạn đang tái tạo một nhóm kết nối khác trên mọi kết nối thu được. Bạn không thực sự gộp các kết nối từ cùng một nhóm. Bạn chỉ cần tạo hồ bơi kết nối một lần khi khởi động ứng dụng và nhận mọi kết nối từ nó. Bạn cũng không nên giữ kết nối như một biến cá thể. Bạn cũng nên đóng kết nối, tuyên bố và kết quả để đảm bảo rằng các tài nguyên được đóng đúng cách, cũng trong trường hợp ngoại lệ. Java 7's try-with-resources statement hữu ích trong việc này, nó sẽ tự động đóng tài nguyên khi khối try kết thúc.

Dưới đây là một viết lại nhỏ:

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(); 
    } 

} 

(điều này có thể nếu cần được refactored như một nhà máy trừu tượng để cải thiện pluggability)

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; 
} 

mà là để được sử dụng như sau:

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); 
} 

Trong môi trường Java EE thực tế, bạn nên ủy thác việc tạo DataSource cho máy chủ/máy chủ ứng dụng và lấy nó từ JNDI. Trong trường hợp của Tomcat, xem thêm ví dụ tài liệu này: http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html

+0

Xin lỗi, cảm ơn bạn đã viết lại. Trợ giúp hoàn hảo cho người mới như tôi. – ryandlf

+0

giải pháp này sẽ là threadsafe? Tôi có cần phải gọi connection.close(); – swapyonubuntu

+0

@swapyonubuntu: đóng được tự động thực hiện với câu lệnh 'try-with-resources' Java7 mới https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html – BalusC

3

Dường như nó không được gộp chung. Bạn nên lưu trữ DataSource trong DatabaseConnection thay vì tạo một nguồn mới với mỗi lệnh gọi getConnection(). getConnection() nên trả về datasource.getConnection().

2

Có vẻ như sử dụng DBCP. Nếu có, thì có. Nó đã được gộp lại. Và đây là giá trị thuộc tính pool mặc định của 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; 
1

Theo dõi giải pháp của BalusC, dưới đây là triển khai tôi có thể sử dụng trong một ứng dụng yêu cầu nhiều kết nối hoặc trong thư viện chung không biết trước thuộc tính kết nối. .

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(); 

    } 

} 
+0

Giải pháp này không hoạt động luôn. Nó phụ thuộc vào điều kiện chủng tộc mặc dù sử dụng ConcurrentHashMap. –

Các vấn đề liên quan