2011-07-15 20 views
9

Việc sử dụng PreparedStatements và ResultSets có tạo ra một "cá thể cơ sở dữ liệu mới" mỗi khi chúng được sử dụng không? Hoặc, với các từ khác, nếu tôi sử dụng PreparedStatement và ResultSet, tôi có nên đóng chúng sau mỗi lần sử dụng hoặc khi tôi hoàn thành?Đóng báo cáo đã chuẩn bị

Ví dụ:

while (...){ 
     p = connection.prepareStatement(...); 
     r = p.executeQuery(); 
     while (r.next()) { 
     .... 
     } 
} 
// We close at the end. Or there are any other p and r still opened...? 
p.close(); 
r.close(); 

HOẶC

while (...){ 
     p = connection.prepareStatement(...); 
     r = p.executeQuery(); 
     while (r.next()) { 
     .... 
     } 
     p.close(); 
     r.close(); 
} 

LƯU Ý: Tất nhiên là tôi sẽ sử dụng thử và đóng đúng cách, đây chỉ là một ví dụ.

+0

Bạn đóng chúng trong một khối cuối cùng, để bạn đảm bảo đóng cửa của nó ngay cả khi có bất kỳ runtimeexception – chedine

Trả lời

5

Bạn nên đóng mọi thứ bạn mở. Khi bạn tạo một câu lệnh chuẩn bị hoặc kết quả thiết lập cơ sở dữ liệu phân bổ tài nguyên cho chúng, và đóng chúng sẽ cho cơ sở dữ liệu giải phóng các tài nguyên đó (có khả năng cơ sở dữ liệu sẽ phân bổ lại các tài nguyên này sau một khoảng thời gian chờ, nhưng gọi gần cho phép cơ sở dữ liệu biết nó có thể đi trước và dọn dẹp). Ví dụ thứ hai của bạn tốt hơn, ngoại trừ tôi sẽ đóng tập kết quả trước câu lệnh đã chuẩn bị.

Vì vậy, với các khối try bao gồm nó sẽ trông giống như:

while (...){ 
     PreparedStatement p = connection.prepareStatement(...); 
     try { 
      ResultSet r = p.executeQuery(); 
      try { 
      while (r.next()) { 
       .... 
      } 
      } finally { 
      try { 
       r.close(); 
      } catch (SQLException e) { 
      // log this or something -- prevent these from masking original exception 
      } 
      } 
     } 
     finally { 
      try { 
      p.close(); 
      } catch (SQLException e) { 
      // log this or something -- prevent these from masking original exception 
      } 
     } 
} 

bắt các ngoại lệ từ gần là xấu xí, nhưng nếu bạn có một ngoại lệ ném trong thực hiện các tuyên bố chuẩn bị, hoặc trong quá trình traversal của kết quả thiết lập, bạn muốn chắc chắn rằng bạn nhìn thấy nó, và không phải là một ngoại lệ ném khi đóng báo cáo chuẩn bị hoặc kết quả thiết lập (đó là do một số trục trặc mạng bạn không thể làm bất cứ điều gì về anyway). Cũng cần lưu ý rằng việc sử dụng try-with-resources sẽ hoạt động, ngoại trừ nếu bạn có trường hợp hoạt động cơ sở dữ liệu thành công nhưng gọi kết quả gần như là ngoại lệ thì ngoại lệ sẽ bị ném.

Tôi khuyên mọi người nên sử dụng thư viện spring-jdbc (xử lý việc đóng tất cả mọi thứ cho bạn) thay vì tạo ra jdbc iffy hoặc verbose bằng tay.

+0

Bất kỳ trợ giúp ở đây? :) http://stackoverflow.com/questions/35849664/sonar-close-this-preparedstatement –

5

Cách đầu tiên tốt hơn.

Tuy nhiên, bạn nên biết rằng bạn có thể tái sử dụng câu lệnh đã chuẩn bị (do đó tên "được chuẩn bị") nếu SQL bạn đang sử dụng giống nhau mỗi lần. Ví dụ:

//Note: try/catch/finally blocks removed for brevity 
p = connection.prepareStatement(...); 
while (...){ 
    r = p.executeQuery(); 
    while (r.next()) { 
     .... 
    } 
    r.close(); 
} 
p.close(); 
+1

+1 để sử dụng lại câu lệnh đã chuẩn bị –

+0

Bất kỳ trợ giúp nào ở đây? :) http://stackoverflow.com/questions/35849664/sonar-close-this-preparedstatement –

1

Thậm chí nếu bạn không muốn sử dụng Spring, hoặc Apache DbUtils, hoặc tương tự, nhận ra rằng có một LOT của soạn sẵn ở đây mà bạn muốn tiếp tục yếu tố ra khỏi thói quen truy vấn của bạn để bạn có phải lặp lại nó càng ít lần càng tốt.