1. ORM là gì?

ORM (Object-Relational Mapping) là kỹ thuật giúp kết nối giữa cách tổ chức dữ liệu trong lập trình hướng đối tượng và cách lưu trữ dữ liệu trong cơ sở dữ liệu quan hệ. Thông thường, trong database, dữ liệu được lưu dưới dạng bảng, gồm các hàng và cột. Trong khi đó, khi lập trình bằng các ngôn ngữ như Python, Java, PHP hoặc C#, dữ liệu thường được biểu diễn dưới dạng object (đối tượng) và class (lớp).

Theo mình tìm hiểu, ORM đóng vai trò trung gian giúp lập trình viên làm việc với dữ liệu database thông qua các đối tượng trong code, thay vì phải viết câu lệnh SQL cho mọi thao tác. ORM có thể hỗ trợ những công việc như thêm dữ liệu, đọc dữ liệu, cập nhật thông tin và xóa bản ghi.

Ví dụ, khi xây dựng một ứng dụng quản lý người dùng, thay vì tự viết câu SQL để thêm một người dùng mới, mình có thể tạo một đối tượng User trong code rồi sử dụng phương thức của ORM để lưu đối tượng đó vào database.

Một số ORM phổ biến hiện nay gồm SQLAlchemy của Python, Django ORM, Hibernate của Java, Entity Framework của .NET và Eloquent ORM của Laravel.ORM là gì? Một số lưu ý để ứng dụng ORM Framework hiệu quả

2. ORM hoạt động như thế nào?

ORM hoạt động bằng cách ánh xạ các thành phần trong chương trình với những thành phần tương ứng trong cơ sở dữ liệu. Thông thường, một class có thể được ánh xạ với một bảng, các thuộc tính của class tương ứng với các cột, còn mỗi object đại diện cho một bản ghi cụ thể.

Ví dụ, trong chương trình có class User với các thuộc tính như id, name và email. ORM có thể ánh xạ class này với bảng users trong database. Khi cần lưu một object thuộc class User, ORM sẽ chuyển thao tác đó thành câu lệnh SQL phù hợp với hệ quản trị cơ sở dữ liệu đang sử dụng.

Quá trình này có thể diễn ra theo các bước cơ bản:

  • Lập trình viên định nghĩa model hoặc class để mô tả dữ liệu.
  • ORM xác định mối liên hệ giữa model và các bảng trong database.
  • Lập trình viên gọi các phương thức để truy vấn hoặc thay đổi dữ liệu.
  • ORM chuyển những thao tác đó thành câu lệnh SQL tương ứng.
  • Database thực thi câu lệnh và trả kết quả về cho ORM.
  • ORM chuyển kết quả thành object hoặc cấu trúc dữ liệu để chương trình tiếp tục xử lý.

Nhờ cơ chế này, lập trình viên có thể thao tác với dữ liệu theo cách gần gũi với ngôn ngữ lập trình đang sử dụng hơn.

ORM là gì? Hiểu Object Relational Mapping thế nào cho đúng?

3. Ví dụ sử dụng ORM

Để dễ hình dung, mình lấy ví dụ với Python và SQLAlchemy. Giả sử ứng dụng cần lấy danh sách người dùng từ bảng users.

Nếu sử dụng SQL thuần, mình có thể viết câu lệnh như sau:

SELECT * FROM users;

Nếu sử dụng SQLAlchemy ORM, có thể định nghĩa model và truy vấn dữ liệu thông qua model đó. Ví dụ minh họa dưới đây sử dụng cú pháp SQLAlchemy 2.x với một phiên làm việc session đã được thiết lập:

from sqlalchemy import select

stmt = select(User)
users = session.scalars(stmt).all()

for user in users:
    print(user.name, user.email)

Trong đoạn code này, User là model đại diện cho dữ liệu người dùng, select(User) tạo câu truy vấn lấy các đối tượng User, còn session.scalars(stmt).all() thực hiện truy vấn và lấy kết quả.

ORM sẽ chuyển yêu cầu thành SQL phù hợp để database thực thi. Lập trình viên không cần tự viết câu SELECT cho ví dụ này, nhưng vẫn cần hiểu câu truy vấn được tạo ra để kiểm soát hiệu suất và tránh những truy vấn không cần thiết.

Cú pháp cụ thể có thể khác nhau tùy vào ORM và phiên bản thư viện được sử dụng.

4. Các thao tác CRUD trong ORM

CRUD là viết tắt của bốn thao tác cơ bản khi làm việc với dữ liệu, gồm Create (tạo), Read (đọc), Update (cập nhật) và Delete (xóa). Hầu hết các ORM đều hỗ trợ những thao tác này thông qua các phương thức hoặc API riêng.

Create – Thêm dữ liệu: Khi cần tạo một người dùng mới, mình có thể tạo object rồi yêu cầu ORM lưu vào database.

user = User(name="An", email="[email protected]")
session.add(user)
session.commit()

Read – Đọc dữ liệu: ORM hỗ trợ truy vấn và lấy dữ liệu theo điều kiện.

stmt = select(User).where(User.name == "An")
users = session.scalars(stmt).all()

Update – Cập nhật dữ liệu: Có thể truy vấn một bản ghi, thay đổi thuộc tính của object rồi lưu thay đổi thông qua session.

user = session.get(User, 1)

if user is not None:
    user.name = "Binh"
    session.commit()

Delete – Xóa dữ liệu: Có thể xóa một object đã được truy vấn và quản lý bởi session.

user = session.get(User, 1)

if user is not None:
    session.delete(user)
    session.commit()

Các ví dụ trên giả định model User và session đã được cấu hình đúng. Trong ứng dụng thực tế, cần xử lý thêm những tình huống như dữ liệu không tồn tại, lỗi database và việc rollback khi giao dịch thất bại.

5. Ưu điểm của ORM

Ưu điểm đầu tiên của ORM là giúp giảm lượng SQL phải viết thủ công đối với những thao tác dữ liệu thông thường. Thay vì phải tự xây dựng câu truy vấn cho từng chức năng, lập trình viên có thể sử dụng các phương thức có sẵn của ORM để làm việc với dữ liệu.

Thứ hai, ORM giúp code có cấu trúc rõ ràng hơn khi dữ liệu được tổ chức thành các model. Những model này có thể được sử dụng xuyên suốt các chức năng của ứng dụng, giúp việc quản lý dữ liệu và bảo trì code thuận tiện hơn.

Thứ ba, nhiều ORM hỗ trợ quản lý quan hệ giữa các bảng, xử lý tham số truy vấn và cung cấp công cụ migration để quản lý thay đổi cấu trúc database. Khi sử dụng đúng cách, cơ chế truyền tham số của ORM cũng giúp hạn chế nguy cơ SQL Injection so với việc ghép trực tiếp dữ liệu đầu vào vào chuỗi SQL.

Ngoài ra, một số ORM hỗ trợ nhiều hệ quản trị cơ sở dữ liệu khác nhau. Điều này có thể giúp giảm lượng code cần thay đổi khi chuyển đổi database, mặc dù không đảm bảo ứng dụng có thể chuyển đổi hoàn toàn mà không cần chỉnh sửa.

6. Nhược điểm và những điều cần lưu ý

Mặc dù có nhiều lợi ích, ORM không phải lúc nào cũng là lựa chọn tối ưu. Một trong những hạn chế là lập trình viên có thể khó nhận ra câu SQL thực tế được tạo ra phía sau các phương thức của ORM. Nếu không hiểu cách ORM truy vấn dữ liệu, code có thể vô tình thực hiện nhiều truy vấn hoặc lấy nhiều dữ liệu hơn mức cần thiết.

Một vấn đề thường gặp là N+1 Query Problem. Ví dụ, chương trình lấy danh sách bài viết bằng một truy vấn, sau đó mỗi lần truy cập thông tin tác giả lại phát sinh thêm một truy vấn riêng. Khi số lượng bài viết tăng lên, số truy vấn cũng tăng theo và có thể làm giảm hiệu suất của ứng dụng.

Ngoài ra, với những truy vấn phức tạp, báo cáo dữ liệu lớn hoặc thao tác cần tối ưu sâu, việc viết SQL trực tiếp đôi khi dễ kiểm soát hơn. ORM cũng có thể bổ sung một lượng xử lý trung gian và yêu cầu người lập trình hiểu các khái niệm như session, transaction, lazy loading và eager loading.

Vì vậy, theo mình hiểu, sử dụng ORM không có nghĩa là không cần học SQL. Để phát triển ứng dụng hiệu quả, mình vẫn cần hiểu cách truy vấn dữ liệu, cách thiết kế bảng và cách kiểm tra hiệu suất khi cần thiết.

7. ORM và SQL thuần khác nhau như thế nào?

SQL thuần là cách làm việc trực tiếp với database bằng các câu lệnh như SELECT, INSERT, UPDATE và DELETE. ORM là cách thao tác với dữ liệu thông qua model và các phương thức trong ngôn ngữ lập trình, sau đó ORM chuyển những thao tác này thành SQL.

Với SQL thuần, lập trình viên có thể kiểm soát chi tiết câu truy vấn, cách kết hợp bảng và những phép tính cần thực hiện. Điều này hữu ích khi tối ưu các truy vấn phức tạp hoặc xử lý dữ liệu với yêu cầu đặc biệt.

Ngược lại, ORM thường giúp code dễ đọc và thuận tiện hơn đối với các chức năng CRUD phổ biến. Khi một ứng dụng có nhiều model và quan hệ dữ liệu, ORM cũng có thể giúp tổ chức code thống nhất hơn.

Trong thực tế, hai cách làm này không loại trừ lẫn nhau. Một dự án có thể sử dụng ORM cho phần lớn thao tác dữ liệu và dùng SQL thuần cho những truy vấn cần kiểm soát đặc biệt. Việc lựa chọn phụ thuộc vào yêu cầu dự án, kinh nghiệm của nhóm phát triển và hiệu suất thực tế.

8. Kết luận

Theo mình tìm hiểu, ORM là một kỹ thuật quan trọng trong phát triển phần mềm, giúp kết nối các đối tượng trong code với dữ liệu được lưu trữ trong cơ sở dữ liệu quan hệ. Nhờ ORM, lập trình viên có thể thực hiện những thao tác như thêm, đọc, cập nhật và xóa dữ liệu thông qua các model và phương thức của ngôn ngữ lập trình.

ORM giúp giảm bớt việc viết SQL thủ công, hỗ trợ tổ chức code và quản lý quan hệ giữa các bảng. Tuy nhiên, nếu sử dụng không đúng cách, ORM vẫn có thể gây ra những vấn đề về hiệu suất, đặc biệt là N+1 Query Problem hoặc những truy vấn lấy dữ liệu không cần thiết.

Vì vậy, khi làm việc với ORM, mình cần hiểu cách model ánh xạ với database, cách truy vấn được thực thi và cách quản lý transaction. Đồng thời, việc nắm vững SQL vẫn rất cần thiết để có thể kiểm tra, tối ưu và xử lý những tình huống phức tạp trong quá trình phát triển ứng dụng.

Bài viết khác

Message Broker

1. Message Broker là gì? Message Broker là một thành phần trung gian được sử dụng để tiếp nhận, quản lý và chuyển tiếp thông điệp giữa các ứng dụng hoặc các thành phần trong một hệ thống phần mềm. Công nghệ này thường xuất hiện trong những hệ thống Backend, kiến trúc Microservices và […]

Background Jobs and Queues

1. Background Jobs and Queues là gì? Background Jobs & Queues là hai khái niệm thường gặp trong quá trình phát triển phần mềm, đặc biệt là khi xây dựng các ứng dụng web, ứng dụng di động hoặc những hệ thống cần xử lý nhiều yêu cầu cùng lúc. Hai khái niệm này liên […]

Redis and Caching

1. Caching là gì? Caching là kỹ thuật lưu trữ tạm thời những dữ liệu thường xuyên được sử dụng để có thể truy xuất lại nhanh chóng khi cần thiết. Thay vì mỗi lần người dùng thực hiện một thao tác, hệ thống đều phải truy vấn cơ sở dữ liệu hoặc xử lý […]

Database Migration

1. Database Migration là gì? Database Migration là quá trình quản lý và cập nhật cấu trúc cơ sở dữ liệu theo từng phiên bản trong quá trình phát triển phần mềm. Khi xây dựng một ứng dụng, cơ sở dữ liệu thường xuyên thay đổi để đáp ứng các yêu cầu mới. Ví dụ, […]

Bun ORM

1. Bun ORM là gì? Bun ORM là một thư viện ORM dành cho ngôn ngữ lập trình Go (Golang), được sử dụng để làm việc với cơ sở dữ liệu quan hệ. Bun giúp lập trình viên xây dựng và thực hiện các truy vấn database thông qua những cấu trúc dữ liệu và […]

Date / Number / Currency Formatting

       Trong quá trình phát triển phần mềm, đặc biệt là các ứng dụng web và di động phục vụ người dùng ở nhiều quốc gia, việc hiển thị dữ liệu theo đúng định dạng ngày tháng, số và tiền tệ đóng vai trò vô cùng quan trọng. Người dùng không chỉ quan […]

Leave a Reply

Your email address will not be published. Required fields are marked *