2011-01-10 29 views
6

Chúng tôi tất cả knowthat chúng ta nên sử dụng lại JDBC PreparedStatement hơn là tạo một phiên bản mới trong vòng lặp.Sử dụng lại một PreparedStatement giữa các phương pháp?

Nhưng cách xử lý PreparedStatement sử dụng lại giữa các lời gọi phương thức khác nhau? Liệu tái sử dụng - "quy tắc" vẫn được tính?

Tôi có nên cân nhắc sử dụng trường cho PreparedStatement hay tôi nên đóng và tạo lại câu lệnh đã chuẩn bị trong mọi lời gọi (giữ địa phương) không? (Tất nhiên một trường hợp của một lớp như vậy sẽ bị ràng buộc vào một Connection có thể là bất lợi trong một số kiến ​​trúc)

Tôi biết rằng câu trả lời lý tưởng có thể là "nó phụ thuộc".
Nhưng tôi đang tìm cách thực hành tốt nhất cho các nhà phát triển ít kinh nghiệm hơn, họ sẽ thực hiện lựa chọn đúng trong hầu hết các trường hợp.

+3

Chắc chắn không biến nó thành trường của lớp học. Giữ cho nó phương pháp. – BalusC

Trả lời

13

Tất nhiên một thể hiện của một lớp học như vậy sẽ được ràng buộc với một kết nối mà có thể là một bất lợi

Có thể? nó sẽ là một bất lợi lớn. Bạn cần phải đồng bộ hóa quyền truy cập vào nó, điều này sẽ giết chết hiệu suất đa người dùng của bạn bằng đá, hoặc tạo nhiều phiên bản và giữ chúng trong một hồ bơi. Đau lớn trong mông.

Việc gộp nhóm bản ghi là công việc của trình điều khiển JDBC, và hầu hết, nếu không phải tất cả, của trình điều khiển hiện tại của trình điều khiển sẽ thực hiện điều này cho bạn. Khi bạn gọi prepareStatement hoặc prepareCall, trình điều khiển sẽ xử lý việc sử dụng lại tài nguyên hiện có và các câu lệnh được biên dịch trước.

Statement đối tượng được liên kết với một kết nối và kết nối sẽ được sử dụng và trả lại hồ bơi nhanh nhất có thể.

Tóm lại, thực hành tiêu chuẩn có được PreparedStatement khi bắt đầu phương pháp, sử dụng liên tục trong vòng lặp, sau đó đóng nó ở cuối phương thức, là thực hành tốt nhất.

+0

Tôi không hiểu tại sao đây là một vấn đề lớn. Bạn có một luồng cho mỗi kết nối. Mỗi lớp dịch vụ (chứa các phương thức CRUD của bạn) xây dựng các PreparedStatements ở phía trước và tái sử dụng chúng trên tất cả các phương thức. Các PreparedStatements được đóng lại khi kết nối được đóng lại. – Gili

0

Có thể sử dụng lại, nhưng tôi tin rằng điều này chỉ được tính nếu cùng một đối tượng Connection đang được sử dụng và nếu bạn đang sử dụng Hồ bơi kết nối cơ sở dữ liệu (ví dụ trong ứng dụng web) thì các đối tượng Connection khác nhau mỗi lần.

Tôi luôn tạo lại PreparedStatement trước mỗi lần sử dụng trong một Ứng dụng web vì lý do này.

Nếu bạn không sử dụng Hồ bơi kết nối thì bạn đang vàng!

0

Tôi không thấy sự khác biệt: Nếu tôi thực hiện cùng một câu lệnh liên tục đối với cùng một kết nối, tại sao không sử dụng lại PreparedStatement bằng bất kỳ cách nào? Nếu nhiều phương thức thực hiện cùng một câu lệnh, thì có lẽ câu lệnh đó cần phải được đóng gói theo phương thức riêng của nó (hoặc thậm chí là lớp riêng của nó). Bằng cách đó bạn sẽ không cần phải vượt qua một số PreparedStatement.

+1

Kể từ khi một PreparedStatement "thuộc" cho một kết nối cụ thể bạn chỉ không thể tái sử dụng nó trong số các kết nối khác nhau. Tất nhiên bạn có thể tái sử dụng một số mã sẽ được thực thi dọc theo các kết nối khác nhau, nhưng điều tốt về PreparedStatment là để nó được chuẩn bị một lần và tái sử dụng nó, điều này là không thể khi bạn sử dụng một kết nối khác. –

6

Nhiều khối lượng công việc cơ sở dữ liệu là CPU bị ràng buộc, không phải IO-bound. Điều này có nghĩa là cơ sở dữ liệu sẽ mất nhiều thời gian hơn để thực hiện công việc như phân tích các truy vấn SQL và tìm ra cách xử lý chúng (thực hiện 'kế hoạch thực hiện'), hơn là dùng để truy cập đĩa.Điều này đúng với khối lượng công việc 'giao dịch' hơn khối lượng công việc 'báo cáo', nhưng trong cả hai trường hợp, thời gian chuẩn bị kế hoạch có thể cao hơn bạn mong đợi. Vì vậy nó luôn luôn là một ý tưởng tốt, nếu tuyên bố sẽ được thực hiện thường xuyên và rắc rối của việc sắp xếp (chính xác) để cache PreparedStatements 'giữa invocations phương pháp' là giá trị thời gian phát triển của bạn. Như mọi khi với hiệu suất, đo lường là chìa khóa, nhưng nếu bạn có thể làm điều đó đủ rẻ, hãy nhớ cache PreparedStatement của bạn ra khỏi thói quen.

Một số trình điều khiển JDBC và/hoặc các hồ bơi kết nối cung cấp "bộ nhớ đệm báo cáo đã chuẩn bị trong suốt", do đó bạn không phải tự làm điều đó. Vì vậy, miễn là bạn hiểu được hành vi của chiến lược bộ nhớ đệm trong suốt được chọn cụ thể của bạn, nó là tốt để cho nó theo dõi những thứ ... những gì bạn thực sự muốn tránh là hit trên cơ sở dữ liệu.

+0

Có rất nhiều truy vấn sane sẽ đòi hỏi nhiều IO trên cơ sở dữ liệu. Cụ thể, bất cứ điều gì làm tính toán/tổng hợp/... của các tập dữ liệu lớn. –

+0

@Jochaim Sauer: Tôi có đủ điều kiện xác nhận phát ban của tôi :-) –

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