2012-04-02 24 views
6

Theo documentation cho getResultSet trong java.sql.Statement, nó nói:getResultSet() "nên được gọi là chỉ một lần mỗi kết quả"

Lấy kết quả hiện tại như một đối tượng ResultSet. Phương pháp này nên chỉ được gọi một lần cho mỗi kết quả.

Sử dụng một số mã kiểm tra, tôi chạy executeQuery() và một số cuộc gọi đến getResultSet() và quan sát thấy rằng các ResultSet trở chỉ vào cùng một đối tượng. Vì vậy, tôi đoán nó không trả lại một số khác nhau ResultSet mà bạn sẽ cần phải đóng riêng. Nhưng tất nhiên điều này có thể là duy nhất đối với các trình điều khiển JDBC của tôi.

Nhìn vào documentation cho ResultSet nó nói: đối tượng ResultSet

Một mặc định là không thể cập nhật và có một con trỏ mà di chuyển về phía trước mà thôi. Do đó, bạn chỉ có thể lặp qua nó một lần và chỉ từ hàng đầu tiên đến hàng cuối cùng.

Điều này có vẻ là lý do chính đáng tại sao bạn nên gọi nó nhiều lần vì điều này có thể dẫn đến một số tình huống "khó hiểu". Nếu đây là lý do duy nhất, tôi cảm thấy rằng họ có thể vừa mới nói vậy nên tôi nghĩ có thể có nhiều hơn thế.

Vì vậy, không ai biết tại sao một người không nên gọi số getResultSet nhiều lần một lần cho mỗi kết quả? question là điều khiến tôi tò mò ngay từ đầu.

+1

Không đăng câu trả lời này vì nó chỉ là linh cảm, nhưng tôi nghi ngờ đây là cách để các nhà phát triển trình điều khiển JDBC mất nhiều thời gian, cho phép họ không xác định điều gì xảy ra khi bạn gọi nó nhiều lần. Trong trường hợp cụ thể của bạn nó hoạt động, nhưng nếu bạn đã từng chuyển đổi các trình điều khiển JDBC nó có thể không. –

+1

Tôi nghĩ nó đơn giản như vậy: đối tượng ResultSet có trạng thái. Chỉ có một đối tượng ResultSet là một thành viên của Tuyên bố. Bắt đối tượng không thực hiện lại câu lệnh. Bắt đối tượng lần thứ hai không được đảm bảo ở trạng thái giống như lần đầu tiên nhận được nếu bạn sửa đổi thứ gì đó sau lần đầu tiên nhận được. Vì vậy, nó chỉ là một sự thận trọng. Nhìn vào trình điều khiển jdbc của Postres (org.postgresql.jdbc2.AbstractJdbc2Statement), chúng ta có thể thấy rằng bên trong nó thực hiện nhiều cuộc gọi như thế này: return (result! = Null && result.getResultSet()! = Null); – Glenn

Trả lời

4

Đối tượng ResultSet là giao diện được cung cấp bởi Java JDBC - chúng không cung cấp triển khai. Mặc dù mã cơ sở dữ liệu cụ thể của bạn và các trình điều khiển liên quan thực hiện ResultSet để bạn có thể gọi nó nhiều lần cho mỗi kết quả, nếu bạn phụ thuộc vào hành vi đó ngoài hợp đồng, bạn chắc chắn đang chơi với lửa.

Một lý do có thể khiến hợp đồng được viết với dòng this method should be called only once per result là vì lý do hiệu quả. Việc xây dựng ResultSet rất có thể sẽ thực hiện một cuộc gọi RPC JDBC tới cơ sở dữ liệu và các tác giả của đặc tả JDBC muốn ngăn cản nhiều chuyến đi vòng. Họ có thể không muốn buộc người thực hiện bảo vệ chống lại nhiều cuộc gọi trên mỗi kết quả một cách hiệu quả. Một lần nữa, mặc dù cơ sở dữ liệu của bạn đang bảo vệ chống lại hành vi đó không có nghĩa là hành vi tiếp theo sẽ.

Hầu hết các triển khai ResultSet cũng giữ kết nối với cơ sở dữ liệu mở để khi bạn nhận được các trường nhất định (chẳng hạn như các đốm màu lớn), nó có thể gọi lại cơ sở dữ liệu để lấy dữ liệu. Có nhiều kết nối mở hoặc (tệ hơn) bằng cách sử dụng cùng một kết nối từ nhiều đối tượng ResultSet sẽ rất nguy hiểm/gây nhầm lẫn.

Ngoài ra, họ có thể đã lo lắng về hai phần mã của bạn gọi getResultSet() hai lần và được trả về một tham chiếu đến cùng một đối tượng không đồng bộ duy nhất. Điều này sẽ gây nhầm lẫn khi next() được gọi và ghi đè lên đối tượng có nhiều tham chiếu.

Tôi đang suy đoán tất nhiên nhưng tôi hy vọng điều này sẽ hữu ích.

+0

Chắc chắn hữu ích! Nếu tôi nhớ chính xác, việc đóng 'ResultSet' không đóng bất kỳ các đốm màu tiềm năng nào được tạo ra. Tôi hơi bối rối về đoạn thứ 3 liên quan đến nhiều kết nối. Liệu 'ResultSet' có sử dụng cùng một' Connection' để lấy bất kỳ dữ liệu nào từ cơ sở dữ liệu không? Ngoài ra, tôi không rõ lý do tại sao 'Connection' giống nhau từ nhiều' ResultSet' là xấu - Tôi chắc rằng có điều gì đó hiển nhiên tôi đang xem. Ngoài ra, nếu bạn có thể cung cấp một ví dụ (ngay cả khi nó dành cho một trình điều khiển JDBC cụ thể) của việc gọi 'getResult' hai lần sẽ là vấn đề thì tôi nghĩ đó sẽ là câu trả lời hoàn hảo. – nevets1219

+0

Re đoạn thứ 3, tôi chỉ nói rằng quản lý kết nối là một vấn đề. Có nhiều bản sao của đối tượng 'Connection' hoặc nếu hai luồng có một' ResultSet' và đang thực hiện các hoạt động trên cùng một 'Connection' không đồng bộ, nó sẽ nguy hiểm. – Gray

+0

Về việc cung cấp một ví dụ, tôi không có thời gian cho điều đó. Đây là về vi phạm hợp đồng. Postgres có thể nâng cấp trình điều khiển của họ và thay đổi hành vi một chút nhưng vẫn hoàn thành hợp đồng và mã của bạn sẽ bị hỏng nếu bạn phụ thuộc vào nhiều cuộc gọi để hoạt động. Đó là vấn đề nguyên tắc. – Gray

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