2008-12-23 4 views
22

Tôi muốn biết liệu chúng ta có thể tái sử dụng cùng một đối tượng Statement để thực thi nhiều truy vấn không. Hoặc, chúng ta nên tạo một câu lệnh mới cho các truy vấn khác nhau.Tái sử dụng đối tượng câu lệnh Java?

Ví dụ,

Connection con = getDBConnection(); 
Statement st1 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); 
int i = st1.executeUpdate("update tbl_domu set domU_status=1 where domU_id=" + dom_U_id); 
Statement st2 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); 
String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime()); 
int j = st2.executeUpdate("insert into tbl_domU_action_history values('" + dom_U_name + "', 1, '" + date + "')"); 

Trong trường hợp trên, là có bất kỳ tác hại trong việc sử dụng st1 tuyên bố tương tự cho cả hai() truy vấn executeUpdate? Tôi có thể sử dụng cùng một đối tượng Statement st1 cho một executeQuery() khác không?

Trả lời

15

Có, bạn có thể. Tuy nhiên, tốt hơn hết là sử dụng PreparedStatement để tránh các lỗ hổng SQL injection.

0

Bất cứ khi nào bạn gán thứ gì đó cho loại tham chiếu, bạn sẽ thay thế tham chiếu cũ bằng một tham chiếu mới.

Ví dụ ...

MyObject obj = new MyObject("foo"); 
obj = new MyObject("bar"); 

Sẽ có một trường hợp tại phi tham chiếu của MyObject với một số tài sản thiết lập để "foo" mà cuối cùng sẽ được thu gom rác thải.

obj lưu trữ tham chiếu đến MyObject với một số thuộc tính được đặt thành "thanh".

+1

Đây không phải là những gì anh ấy đang làm. Anh ta hỏi liệu anh ta có thể tái sử dụng thể hiện * cùng *, không chỉ cùng một tham chiếu – n4rzul

2

Điểm ban đầu của việc sử dụng câu lệnh đã chuẩn bị là để tránh việc phân tích cú pháp cơ sở dữ liệu và biên dịch lại câu lệnh, vì vậy nó được cho là nhanh hơn.

Tôi đã không xem xét các lỗ hổng SQL injection sử dụng, nhưng tôi không chắc chắn những gì, nếu bất kỳ kiểm tra dữ liệu được thực hiện. Tôi nghi ngờ rằng nó phụ thuộc vào trình điều khiển, vì việc cài đặt trình điều khiển miễn phí chỉ cần dán các câu lệnh vào nhau. Nếu có ai có thêm chi tiết, xin vui lòng gửi bài.

+0

Dường như đặc tả JDBC không yêu cầu xử lý đúng các ký tự đặc biệt. Tôi muốn nghe về bất kỳ trình điều khiển nào không để chúng có thể tránh được. –

+0

Steve, ý tưởng tái: SQL injection là sử dụng các báo cáo tham số tránh rủi ro. Xem http://en.wikipedia.org/wiki/SQL_injection#Preventing_SQL_Injection. Tất nhiên bạn đúng rằng mục đích ban đầu của họ là để tránh phân tích cú pháp không cần thiết. –

+0

Có, tuy nhiên khi trình điều khiển chỉ thực hiện giao diện JDBC, không rõ mức độ này thực sự xảy ra, và nó hoàn toàn phụ thuộc vào trình cài đặt trình điều khiển. Tôi đã hy vọng một người nào đó sẽ có kiến ​​thức cụ thể hơn dựa trên việc phải đối phó với vấn đề này trong quá khứ. –

19

Tôi đã xem qua các câu trả lời tôi đang tìm kiếm trong Javadocs

Theo mặc định, chỉ có một đối tượng ResultSet mỗi đối tượng Statement có thể được mở cùng một lúc. Do đó, nếu việc đọc một đối tượng ResultSet được xen kẽ với việc đọc một đối tượng khác, mỗi đối tượng phải được tạo bởi các đối tượng Statement khác nhau.

+6

Nó không thấy cách này trả lời câu hỏi: chúng ta nên gọi phương thức close() trên bản Tuyên Bố? –

1

Tôi không chắc chắn rằng các bộ kết quả thu thập rác thải chỉ khi chúng được đóng lại. Tôi nghĩ rằng tôi đã có một rò rỉ bộ nhớ mát mẻ khi tôi đang viết một hồ bơi kết nối để cùng một tuyên bố/kết nối đã được tái sử dụng một triệu lần. Giữ lấy JVM của tôi. Tôi đoán điều này cũng có thể được thực hiện cụ thể như bộ sưu tập garabage của một tập kết quả đóng có thể không được kiểm tra.