2011-06-26 26 views
8

Được rồi, tôi đã nhận ra rằng tôi thực sự đã hỏi quá nhiều câu hỏi mà không đóng góp lại cho cộng đồng, nhưng tôi muốn ý kiến ​​của bạn về điều này. Giả sử tôi cóThực hiện hai Java PreparedStatements với một lựa chọn kiểu kết nối

private void closeAll(ResultSet rs, PreparedStatement ps, Connection con) { 
    if (rs != null) 
     try { 
      rs.close(); 
     } catch (SQLException e) { 
     } 
    if (ps != null) 
     try { 
      ps.close(); 
     } catch (SQLException e) { 
     } 
    if (con != null) 
     try { 
      con.close(); 
     } catch (SQLException e) { 
     } 
} 

và tôi muốn thực hiện một số thao tác trên cơ sở dữ liệu MySQL của mình bằng một kết nối. Là nó tốt hơn để viết

Connection con = ...; 
PreparedStatement ps = null; 
ResultSet rs = null; 
try { 
    ps = con.prepareStatement(...); 
    rs = ps.executeQuery(); 
    if (rs.next()) ...; 
} catch (SQLException e) { 
    System.err.println("Error: " + e); 
} finally { 
    closeAll(rs, ps, null); 
} 
try { 
    ps = con.prepareStatement(...); 
    rs = ps.executeQuery(); 
    if (rs.next()) ...; 
} catch (SQLException e) { 
    System.err.println("Error: " + e); 
} finally { 
    closeAll(rs, ps, con); 
} 

hoặc

Connection con = ...; 
PreparedStatement ps = null; 
ResultSet rs = null; 
try { 
    ps = con.prepareStatement(...); 
    rs = ps.executeQuery(); 
    if (rs.next()) ...; 
    rs.close(); 
    ps.close(); 

    ps = con.prepareStatement(...); 
    rs = ps.executeQuery(); 
    if (rs.next()) ...; 
} catch (SQLException e) { 
    System.err.println("Error: " + e); 
} finally { 
    closeAll(rs, ps, con); 
} 

tôi xem xét tốt hơn để có nghĩa là một trong hai an toàn hơn, rõ ràng hơn, súc tích hơn, hoặc mạnh mẽ hơn. Tôi không chắc liệu sau này sẽ luôn luôn đóng bất kỳ báo cáo chuẩn bị và bộ kết quả được mở bất cứ khi nào nó gặp một ngoại lệ, trong khi tôi tin rằng nó trông ngắn gọn hơn. Nhưng trước đây trông đẹp hơn vì nó phù hợp hơn, nhưng nó đặt nhiều chi phí hơn vì nó sử dụng nhiều thử cuối cùng khối.

Tôi nhận thấy rằng phần quản lý tài nguyên tự động của Java 7 của Dự án Coin sẽ buộc tôi phải dựa vào tài nguyên cũ vì tài nguyên được sử dụng trong tiêu đề hoàn toàn là cuối cùng trong nội dung. Tuy nhiên, tôi có một thời gian khá lâu trước khi tôi phải lo lắng về việc sửa đổi mã của tôi để thích ứng với nó để ARM và có thể loại bỏ mã soạn sẵn, vì vậy câu hỏi vẫn đứng: hai phong cách trên, đó sẽ là thực hành tốt hơn? Nếu cả hai đều thực hiện các hành vi mong đợi, liệu cái sau có mang lại cho tôi hiệu suất đáng chú ý có thể tha thứ cho phong cách "xấu xí" hơn không?

Trả lời

6

Dường như với tôi đây là một trường hợp sở thích cá nhân. Trong thời gian của tôi, tôi đã viết mã giống như cả hai khối. Liên quan đến hiệu suất tôi không nghĩ rằng sẽ có một sự khác biệt đáng chú ý đặc biệt, chỉ có các bài kiểm tra hiệu suất sẽ cho biết. Có thể là trường hợp chênh lệch mili giây mà một phiên bản phân phối không phải là một nửa quan trọng như mười phút hoặc lâu hơn để người khác đọc mã của bạn sau sáu tháng kể từ khi bạn viết nó sẽ chi tiêu tại sao.

Sở thích cá nhân của tôi sẽ là tùy chọn thứ hai. Bạn nói rằng bạn đang nắm giữ một kết nối mở cho cơ sở dữ liệu. Với khối mã đầu tiên nếu bạn nhận được một ngoại lệ được ném, điều đó sẽ được xử lý nhưng sau đó bạn sẽ thả xuống lần thử/bắt thứ hai và thử lại. Bạn có thể không muốn điều đó nếu người đầu tiên thất bại. Với thứ hai, một ngoại lệ sẽ khiến bạn thoát khỏi mã và sau đó đóng kết nối của bạn.

Tôi đã lập trình chủ yếu trong C#. Đó là khoảng tám năm trước khi tôi cuối cùng đã làm bất kỳ Java. Nhưng tôi nghĩ có rất nhiều lập trình viên C# đã suy nghĩ về điều này. Tôi có bất kỳ giá nào.

1

Người thứ 2 là con đường để đi. Người đầu tiên có thể không đóng kết nối khi một ngoại lệ xảy ra trong lần thử đầu tiên. Khi bạn chỉ cần in để stderr trong khối catch thì không, nhưng bạn sẽ không làm điều đó. Hay câu lệnh thứ 2 nên được thực hiện mà không liên quan đến thành công/thất bại của câu lệnh đầu tiên?

4

Nếu bạn nhìn vào nó, bạn sẽ thấy logic đó hơi khác - phiên bản đầu tiên sẽ thực hiện truy vấn thứ hai ngay cả khi xử lý truy vấn đầu tiên sẽ không thành công. Phiên bản thứ hai sẽ chỉ tiến hành thực hiện truy vấn thứ hai, nếu xử lý truy vấn đầu tiên + kết quả sẽ thành công.

0

Tôi nhận thấy rằng bài đăng này cũ, nhưng nếu bạn đủ may mắn để chạy trong môi trường Java7- tôi sẽ đề xuất sử dụng try-with-resource.

Nó sẽ xử lý kết nối đóng cho bạn- khi các phiên bản mới của lớp thực hiện giao diện Closable.

public static void viewTable(Connection con) throws SQLException { 

String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from COFFEES"; 

try (Statement stmt = con.createStatement()) { 
    ResultSet rs = stmt.executeQuery(query); 

    while (rs.next()) { 
     String coffeeName = rs.getString("COF_NAME"); 
     int supplierID = rs.getInt("SUP_ID"); 
     float price = rs.getFloat("PRICE"); 
     int sales = rs.getInt("SALES"); 
     int total = rs.getInt("TOTAL"); 

     System.out.println(coffeeName + ", " + supplierID + ", " + 
          price + ", " + sales + ", " + total); 
    } 
} catch (SQLException e) { 
    JDBCTutorialUtilities.printSQLException(e); 
} 
} 
+1

câu trả lời của bạn không liên quan đến câu hỏi – MozenRath

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