Nói như một người đã dành khá nhiều thời gian làm việc với JPA (API liên tục Java, về cơ bản là API ORM được tiêu chuẩn hóa cho Java / J2EE / EJB), bao gồm Hibernate, EclipseLink, Toplink, OpenJPA và những người khác, tôi sẽ chia sẻ một số quan sát.
- ORM không nhanh. Chúng có thể đầy đủ và hầu hết thời gian phù hợp là OK nhưng trong môi trường độ trễ thấp khối lượng lớn, chúng là không có;
- Trong các ngôn ngữ lập trình mục đích chung như Java và C #, bạn cần rất nhiều phép thuật để làm cho chúng hoạt động (ví dụ: dệt thời gian tải trong Java, thiết bị, v.v.);
- Khi sử dụng ORM, thay vì nhận thêm từ SQL (dường như là mục đích), bạn sẽ ngạc nhiên về việc bạn dành bao nhiêu thời gian để điều chỉnh XML và / hoặc chú thích / thuộc tính để ORM của bạn tạo SQL hiệu quả;
- Đối với các truy vấn phức tạp, thực sự không có thay thế. Giống như trong JPA, có một số truy vấn đơn giản là không thể có trong SQL thô và khi bạn phải sử dụng SQL thô trong JPA, nó không đẹp (C # /. Net ít nhất có các kiểu động - var - rất nhiều đẹp hơn một mảng Object);
- Có rất nhiều "gotchas" khi sử dụng ORM. Điều này bao gồm hành vi ngoài ý muốn hoặc không mong muốn, thực tế là bạn phải xây dựng khả năng thực hiện cập nhật SQL cho cơ sở dữ liệu của mình (bằng cách sử dụng refresh () trong JPA hoặc các phương thức tương tự vì mặc định JPA lưu trữ mọi thứ để nó không bắt được cơ sở dữ liệu trực tiếp cập nhật - chạy cập nhật SQL trực tiếp là một hoạt động hỗ trợ sản xuất phổ biến);
- Sự không phù hợp quan hệ đối tượng luôn luôn gây ra vấn đề. Với bất kỳ vấn đề nào như vậy, có một sự đánh đổi giữa sự phức tạp và tính đầy đủ của sự trừu tượng. Đôi khi tôi cảm thấy JPA đã đi quá xa và đạt được một quy luật thực sự về lợi nhuận giảm dần trong đó mức độ phức tạp không được chứng minh bằng sự trừu tượng.
Có một vấn đề khác cần thêm một chút giải thích.
Mô hình truyền thống cho một ứng dụng Web là có một lớp kiên trì và một lớp trình bày (có thể có một dịch vụ hoặc các lớp khác ở giữa nhưng đây là hai lớp quan trọng cho cuộc thảo luận này). Các ORM buộc một cái nhìn cứng nhắc từ lớp kiên trì của bạn lên đến lớp trình bày (tức là các thực thể của bạn).
Một trong những lời chỉ trích về các phương thức SQL thô hơn là bạn kết thúc với tất cả các VO (đối tượng giá trị) hoặc DTO (đối tượng truyền dữ liệu) được sử dụng chỉ bằng một truy vấn. Điều này được quảng cáo là một lợi thế của ORM vì bạn thoát khỏi điều đó.
Điều đó là những vấn đề không biến mất với ORM, chúng chỉ đơn giản là chuyển lên lớp trình bày. Thay vì tạo VO / DTO cho các truy vấn, bạn tạo các đối tượng trình bày tùy chỉnh, thường là một đối tượng cho mỗi chế độ xem. Làm thế nào là tốt hơn? IMHO không phải vậy.
Tôi đã viết về điều này trong ORM hoặc SQL: Chúng ta đã ở đó chưa? .
Công nghệ kiên trì lựa chọn của tôi (trong Java) những ngày này là ibatis. Đó là một trình bao bọc khá mỏng xung quanh SQL, thực hiện 90% + những gì JPA có thể làm (thậm chí nó có thể thực hiện các mối quan hệ lười biếng mặc dù nó không được ghi chép đầy đủ) nhưng với chi phí thấp hơn nhiều (về độ phức tạp và mã thực tế).
Điều này đã xuất hiện vào năm ngoái trong một ứng dụng GWT mà tôi đang viết. Rất nhiều bản dịch từ EclipseLink sang các đối tượng trình bày trong triển khai dịch vụ. Nếu chúng ta đang sử dụng ibatis, việc tạo các đối tượng phù hợp với ibatis sẽ đơn giản hơn rất nhiều và sau đó chuyển chúng lên và xuống ngăn xếp. Một số người theo chủ nghĩa thuần túy có thể cho rằng đây là Bad ™. Có thể là như vậy (về lý thuyết) nhưng tôi nói với bạn điều gì: nó sẽ dẫn đến mã đơn giản hơn, ngăn xếp đơn giản hơn và năng suất cao hơn.