ORM and Code generation for persistent layer – which one is better?

Object Relation Mapping là kĩ thuật ánh xạ từ mô hình hướng đối tượng xuống cơ sở dữ liệu quan hệ.
Code generation for persistent layer là kĩ thuật sinh code từ các bảng cơ sở dữ liệu quan hệ dưới database ra tầng persistent để giao tiếp với hệ quản trị cơ sở dữ liệu. Trong bài viết này tôi không đề cập đến khái niệm code generation chung chung – mà muốn đề cập đến những framework gen code cụ thể cho persistent layer hiện nay như Net Tier.
Đã có rất nhiều người hỏi tôi rằng ORM (Object Relation Mapping) và Code generation for persistent layer – cái nào tốt hơn? Và khi nào thì dùng ORM, khi nào ta nên sử dụng các tool gen code cho persistent layer .
Thực tình mà nói – tôi không dám khuyên bạn sử dụng công cụ nào – nếu tôi không biết dự án bạn đang làm là gì? và nguồn lực bạn đang có ra sao?
Tôi đã đánh hơn 5 dự án sử dụng Hibernate (kể cả NHibernate của .NET), 1 dự án sử dụng iBatis của Java. Với những nền tảng đó – tôi tương đối hiểu sâu về những kĩ thuật và cách thức tương tác với các ORM framework.
Dự án đầu đời mà tôi bắt tay làm – tôi sử dụng MyGeneration (một công cụ gen code) để sinh ra persistent layer cho .NET. Tôi cũng nghiên cứu khá kĩ về các tool gen code đang sử dụng phổ biến trong cộng đồng open source (.NET cũng như Java). Với những kinh nghiệm đó, tôi muốn chia sẻ với các bạn những gì tôi đã từng trải qua. Hy vọng có thể đóng góp được những điều bổ ích và thú vị cho các bạn.
Những ưu điểm và nhược điểm của ORM
Trước tiên ta tạm xét những ưu điểm nổi trội của các framework ORM hiện nay:
Độc lập hệ quản trị cơ sở dữ liệu. Điều này hẳn ai cũng biết – hầu hết các framework ORM luôn được thiết kế để độc lập với các hệ quản trị cơ sở dữ liệu quan hệ. Chỉ cần thay đổi driver tương tác là bạn có thể giao tiếp với một database khác mà không phải thay đổi bất kì dòng code nào.
Cung cấp các API đơn giản – dễ dùng. Lập trình viên không cần phải nhớ mình nên select, update bao nhiêu field cho lọai đối tượng nào, chỉ cần sử dụng thành thạo các hàm Save, Load, Query, Update + một ngôn ngữ query ORM (nếu như framework ORM hỗ trợ – ví dụ ngôn ngữ HQL của Hibernate).
Giúp cho bản thiết kế của bạn gần gũi hơn với lập trình viên – vì đi theo tư duy OOP khi thiết kế entity cho persistent layer. Lập trình viên chỉ cần nắm được sơ đồ thiết kế lớp là đã có thể implement dễ dàng.
Bảng thiết kế sẽ linh động – chi phí trả giá cho việc sửa code khi thay đổi model ít hơn so với sử dụng các tool gencode để sinh ra persistent layer.
Vậy nhược điểm của các ORM là gì?
Nếu thiết kế không đúng cách bạn sẽ trả giá rất lớn về performance.
Các ORM thường gen ra sql để insert, update, query phía bên dưới – nên đôi khi bạn khó can thiệp sâu để optimize performance. Thông thường các ORM framework vẫn hỗ trợ ta gọi câu sql trực tiếp xuống database trong những tình huống cần thiết
Bạn sẽ phải đối đầu với rất nhiều tình huống nan giải mà bất kì ai làm việc với ORM cũng phải gặp qua: cách thức quản lý session truy xuất của ORM – nếu bạn làm việc với Web project, lazy loading, tình huống load tòan bộ database lên nếu không thiết kế đúng cách, …
Để nắm bắt được cách thiết kế tối ưu cho ORM và có thể control được một ORM framework đòi hỏi phải có một thời gian làm việc lâu dài – không phải chỉ trong một sớm một chiều mà đạt được. Vì vậy bạn khó tìm được nguồn nhân sự nắm vững về ORM cho dự án (ở Việt Nam).
Đôi khi bạn sẽ thấy cấu trúc bảng quan hệ bên dưới database rất khó quản lý – nếu như bạn lạm dụng việc kế thừa quá nhiều trong thiết kế class cho ORM.
Những ưu điểm và nhược điểm của việc sử dụng các tool gencode cho Persistent layer
Để dễ đọc tôi tạm viết tắt cụm từ “việc sử dụng các tool gencode cho Persistent layer” thành PLCG – Persistent Layer Code Generation.
Ưu điểm:
Code được sinh ra một cách tường minh – bạn có thể dễ dàng thay đổi và optimize tùy thích.
Ít gặp vấn đề về performance.
Dễ dàng tìm được nguồn nhân sự phục vụ dự án. Chỉ cần người có thể nắm vững các kĩ năng truy vấn database – và người có kinh nghiệm sử dụng code generation tool (cách sử dụng code generation tool cũng rất đơn giản).
Nếu bạn là một người phụ trách việc quản lý dữ liệu trên database – bạn sẽ thấy cấu trúc bảng quan hệ bên dưới “thân thiện hơn và dễ quản lý hơn”.
Nhược điểm:
Khi bạn đối đầu với những cấu trúc phức tạp về model, những quan hệ business rule chằng chịt thì những tool gen code không đủ sức đáp ứng nhu cầu của bạn nữa. Khi đó bạn phụ thuộc rất nhiều vào cấu trúc bảng phức tạp dưới database – khả năng sử dụng tool gen code sẽ ít đi, mà thay vào đó bạn phải viết những hàm xử lý tách biệt nhiều hơn.
Khi cấu trúc của model thay đổi – nếu như bạn đã có sửa đổi code trong các class ở persistent layer, bạn gần như không thể gen code lại mà buộc phải sửa đổi trong các hàm đã gen ra. Điều gì xảy ra – nếu như việc thay đổi không chỉ là thêm/bớt field mà thay đổi cả mối quan hệ phụ thuộc giữa các bảng => Kết quả tất yếu là chi phí sửa đổi code sẽ cao hơn so với sử dụng các framework ORM.
Sau khi phân tích một số ưu khuyết điểm của 2 xu hướng trên, ắt hẳn bạn sẽ hỏi tôi: “vậy khi nào thì dùng cái nào?”… Dưới đây là câu trả lời của tôi.
Uống thuốc đúng liều và đúng cách
Khi nào thì sử dụng ORM
Chỉ sử dụng ORM cho dự án của bạn nếu bạn có người từng có kinh nghiệm về một framework ORM trên 2 năm. (điều kiện tiên quyết)
Nên sử dụng ORM nếu cấu trúc của các đối tượng nghiệp vụ phức tạp – thường xuyên thay đổi.
Sử dụng ORM nếu bạn có thể đánh đổi chi phí phát triển với chi phí upgrade hardware để optimize performance trong tình huống xấu nhất.
Khi nào thì sử dụng PLCG
Khi cấu trúc các đối tượng nghiệp vụ của bạn đơn giản. Phần lớn là ánh xạ 1-1 với các class nghiệp vụ và ít thay đổi.
Nếu bạn không có người expert về ORM để làm dự án (sure – )
Bạn cần tốc độ tối ưu cho ứng dụng nhưng không muốn tốn chi phí cho việc upgrade hardware.
Nếu bạn host một dự án web (ASP.NET) bằng share hosting service thì nên test cẩn thận việc gọi qua lại giữa các dll của ORM và các hàm của ứng dụng Web. (thường bị chặn security level). Nếu không thể gọi được các DLL của ORM tại host đó thì nên chuyển qua host khác hoặc viết lại Persistent layer sử dụng các tool gen code