Sau khi sử dụng Hibernate trên hầu hết các dự án của tôi trong khoảng 8 năm, tôi đã đến một công ty không khuyến khích sử dụng và muốn các ứng dụng chỉ tương tác với DB thông qua các thủ tục được lưu trữ.
Sau khi thực hiện điều này trong một vài tuần, tôi đã không thể tạo ra một mô hình miền phong phú của ứng dụng mà tôi bắt đầu xây dựng và ứng dụng trông giống như một kịch bản giao dịch (khủng khiếp).
Một số vấn đề tôi tìm thấy là:
- Không thể điều hướng biểu đồ đối tượng vì các thủ tục được lưu trữ chỉ tải lượng dữ liệu tối thiểu, điều đó có nghĩa là đôi khi chúng ta có các đối tượng tương tự với các trường khác nhau. Một ví dụ là: chúng tôi có một quy trình được lưu trữ để truy xuất tất cả dữ liệu từ khách hàng và một quy trình khác để truy xuất thông tin tài khoản cộng với một vài trường từ khách hàng.
- Rất nhiều logic kết thúc trong các lớp của trình trợ giúp, do đó mã trở nên có cấu trúc hơn (với các thực thể được sử dụng như các cấu trúc C cũ).
- Mã giàn giáo nhàm chán hơn, vì không có khung trích xuất các tập kết quả từ một thủ tục được lưu trữ và đặt nó vào một thực thể.
Câu hỏi của tôi là:
- có ai gặp tình huống tương tự và không đồng ý với cách tiếp cận thủ tục cửa hàng không? bạn đã làm gì?
- Có một lợi ích thực sự của việc sử dụng các thủ tục được lưu trữ? ngoài quan điểm ngớ ngẩn "không ai có thể đưa ra bảng thả".
- Có cách nào để tạo một miền phong phú bằng cách sử dụng các thủ tục được lưu trữ không? Tôi biết rằng có khả năng sử dụng AOP để tiêm DAO / Kho lưu trữ vào các thực thể để có thể điều hướng biểu đồ đối tượng. Tôi không thích tùy chọn này vì nó rất gần với voodoo.
Phần kết luận
Đầu tiên, cảm ơn tất cả các câu trả lời của bạn. Kết luận mà tôi đã đưa ra là các ORM không cho phép tạo các mô hình Rich Domain (như một số người đã đề cập), nhưng nó đơn giản hóa số lượng công việc (thường lặp đi lặp lại). Sau đây là giải thích chi tiết hơn về kết luận, nhưng không dựa trên bất kỳ dữ liệu cứng nào.
Hầu hết các ứng dụng yêu cầu và gửi thông tin đến các hệ thống khác. Để làm điều này, chúng tôi tạo ra một sự trừu tượng trong các điều khoản mô hình (ví dụ: một sự kiện kinh doanh) và mô hình miền gửi hoặc nhận sự kiện. Sự kiện thường cần một tập hợp nhỏ thông tin từ mô hình, nhưng không phải toàn bộ mô hình. Ví dụ: trong một cửa hàng trực tuyến, một cổng thanh toán yêu cầu một số thông tin người dùng và tổng số để tính phí người dùng, nhưng không yêu cầu lịch sử mua hàng, các sản phẩm có sẵn và tất cả các cơ sở khách hàng. Vì vậy, sự kiện này có một bộ dữ liệu nhỏ và cụ thể.
Nếu chúng ta lấy cơ sở dữ liệu của một ứng dụng làm hệ thống bên ngoài, thì chúng ta cần tạo ra một sự trừu tượng cho phép chúng ta ánh xạ các thực thể Mô hình miền vào cơ sở dữ liệu ( như NimChimpsky đã đề cập , sử dụng trình ánh xạ dữ liệu). Sự khác biệt rõ ràng là bây giờ chúng ta cần tạo thủ công ánh xạ cho từng thực thể mô hình vào cơ sở dữ liệu (có thể là lược đồ kế thừa hoặc các thủ tục được lưu trữ), với một nỗi đau thêm, vì hai thực thể này không đồng bộ hóa, một thực thể miền có thể ánh xạ một phần đến một thực thể cơ sở dữ liệu (ví dụ: lớp UserCredentials chỉ chứa tên người dùng và mật khẩu được ánh xạ tới bảng Người dùng có các cột khác) hoặc một thực thể mô hình miền có thể ánh xạ tới nhiều thực thể cơ sở dữ liệu (ví dụ: nếu có một thực thể cơ sở dữ liệu một ánh xạ trên bảng, nhưng chúng tôi muốn tất cả dữ liệu chỉ trong một lớp).
Trong một ứng dụng có một vài thực thể, số lượng công việc làm thêm có thể nhỏ nếu không cần phải vượt qua các thực thể, nhưng nó sẽ tăng lên khi có nhu cầu có điều kiện để vượt qua các thực thể (và do đó chúng ta có thể muốn thực hiện một loại 'lười biếng tải'). Khi một ứng dụng phát triển để có nhiều thực thể hơn, công việc này chỉ tăng lên (và tôi có cảm giác rằng nó tăng phi tuyến tính). Giả định của tôi ở đây, là chúng tôi không cố gắng phát minh lại ORM.
Một lợi ích của việc coi DB là một hệ thống bên ngoài, là chúng ta có thể viết mã xung quanh các tình huống trong đó chúng ta muốn có 2 phiên bản khác nhau của một ứng dụng đang chạy, trong đó mỗi ứng dụng có một ánh xạ khác nhau. Điều này trở nên thú vị hơn trong kịch bản giao hàng liên tục cho sản xuất ... nhưng tôi nghĩ điều này cũng có thể xảy ra với các ORM ở mức độ thấp hơn.
Tôi sẽ loại bỏ khía cạnh bảo mật, trên cơ sở rằng một nhà phát triển, ngay cả khi anh ta không có quyền truy cập vào cơ sở dữ liệu, có thể có được hầu hết nếu không phải tất cả thông tin được lưu trữ trong hệ thống, chỉ bằng cách tiêm mã độc (ví dụ: Tôi không thể tin rằng tôi đã quên xóa dòng ghi nhật ký chi tiết thẻ tín dụng của khách hàng, thưa ông chủ! ).
Cập nhật nhỏ (ngày 6 tháng 6 năm 2012)
Các thủ tục được lưu trữ (ít nhất là trong Oracle) ngăn chặn thực hiện bất cứ điều gì như phân phối liên tục với thời gian chết bằng 0, vì bất kỳ thay đổi nào đối với cấu trúc của các bảng sẽ làm mất hiệu lực các thủ tục và trình kích hoạt. Vì vậy, trong thời gian DB đang được cập nhật, ứng dụng cũng sẽ ngừng hoạt động. Oracle cung cấp một giải pháp cho Định nghĩa dựa trên Phiên bản này , nhưng một số DBA tôi đã hỏi về tính năng này đã đề cập rằng nó được cấy ghép kém và họ sẽ không đưa nó vào DB sản xuất.