07/09/2018, 10:39

Chính Xác Thì Active Record Là Gì

Đây là một trong những câu hỏi khiến rất nhiều lập trình viên phải bỏ ra không ít thời gian để tìm câu trả lời cho nó. Cũng đã có rất nhiều những tài liệu trên mạng giải thích về thuật ngữ này. Tuy nhiên theo đánh giá của cá nhân tôi, phần lớn đều chưa đưa ra được những dẫn giải cụ thể, dễ hiểu và ...

Đây là một trong những câu hỏi khiến rất nhiều lập trình viên phải bỏ ra không ít thời gian để tìm câu trả lời cho nó. Cũng đã có rất nhiều những tài liệu trên mạng giải thích về thuật ngữ này. Tuy nhiên theo đánh giá của cá nhân tôi, phần lớn đều chưa đưa ra được những dẫn giải cụ thể, dễ hiểu và dễ tiếp cận. Để giải đáp thắc mắc này thì ở bài viết này chúng ta sẽ cùng nhau giải mã thuật ngữ này.

Active Record Là Gì

Một định nghĩa theo tôi là đơn giản nhất về thuật ngữ này sẽ như sau:

Active Record là một phương pháp thiết kế object với mục đích nhằm đơn giản hoá quá trình quản lý dữ liệu trong database khi lập trình ứng dụng.

Nếu đọc xong định nghĩa trên mà bạn vẫn thấy khó hiểu thì cũng không sao vì chúng ta sẽ bắt tay vào một ví dụ cụ thể ngay sau đây. Giả sử chúng ta đang cần xây dựng một ứng dụng blog cá nhân.

Tạo Cơ Sở Dữ Liệu

Hãy bắt đầu bằng việc kết nối với MySQL database server (trên server thực hoặc trên máy local của bạn) và tạo một cơ sở dữ liệu (database):

CREATE DATABASE `test_active_record`;

Tiếp theo chúng ta sẽ chạy câu lệnh sau để chọn database mới tạo để làm việc với nó:

USE `test_active_record`;

Trên database chúng ta sẽ tạo bảng tbl_posts dùng để lưu trữ các bài viết với 2 trường là title để lưu tiêu đề bài viết và content để lưu nội dung bài viết. Đoạn SQL tạo để tạo bảng này như sau:

create tbl_posts(
    `id` int(11) AUTO INCREMENT,
    `title` VARCHAR(255),
    `content` TEXT,
    PRIMARY KEY (`id`)
)

Kiểm tra lại cấu trúc của bảng tbl_posts bằng câu lệnh sau:

describe tbl_posts;

Kết quả:

+---------+--------------+------+-----+---------+----------------+
| Field   | Type         | Null | Key | Default | Extra          |
+---------+--------------+------+-----+---------+----------------+
| id      | int(11)      | NO   | PRI | NULL    | auto_increment |
| title   | varchar(255) | YES  |     | NULL    |                |
| content | text         | YES  |     | NULL    |                |
+---------+--------------+------+-----+---------+----------------+

Tương Tác Giữa Ứng Dụng Với Database

Để ứng dụng có thể tương tác với database thì chúng ta sẽ sử dụng một class có tên là MyActiveRecord. Class này sẽ chứa toàn bộ logic code để ứng dụng chúng ta có thể thực hiện việc kết nối tới database, lưu trữ dữ liệu, chỉnh sửa cũng như xoá dữ liệu từ database:

class MyActiveRecord {
    private $table;

    // logic xử lý việc lưu trữ vào bảng $table
    public function save() {
        // ... Tạm thời để rỗng
    }
}

Ở trên bạn chú ý giá trị của thuộc tính $table sẽ ứng với tên bảng trên database mà ứng dụng cần tương tác với nó.

Tiếp theo, chúng ta tạo thêm một class khác là Post, các đối tượng (object) được tạo ra từ class này sẽ được dùng để mô hình hoá các bài viết:

class Post extend MyActiveRecord {
    private $table = "tbl_posts";

    public $title;
    public $content;
}

$post = new Post;
$post->title = "Bài Viết 1";
$post->cotent = "Nội dung của bài viết 1.";
$post->save();

Điều đặc biệt với đoạn code ở trên đó là ở chỗ ngay cả khi bạn không phải là một lập trình viên PHP thì bạn vẫn có thể hình dung ra được ý nghĩa của nó. Tất cả các logic phức tạp tương tác với cơ sở dữ liệu được đóng gói trong class MyActiveRecord.

Một trong những tính năng mà ActiveRecord cung cấp đó là việc kết dữ liệu của object trong ứng dụng với cấu trúc của bảng trên database. Khi gọi method save trong class MyActiveRecord, thì dữ liệu của các thuộc tính title và content trong object $post sẽ được dùng để lưu trữ vào bảng tbl_posts tương ứng với các trường title và content.

Ohm thật là vi diệu! Nhưng mà tôi thấy hiện tại thì method save() của MyActiveRecord là đang để rỗng?

Chúng ta sẽ triển khai tính năng kết nối Object với database trong class MyActiveRecord ngay tiếp sau đây.

Trước tiên chúng ta sẽ thêm method connect_database() vào class này để thực hiện việc kết nối tới cơ sở dữ liệu:

class MyActiveRecord {
    private $table;

    private $database_host = "localhost";
    private $database_username = "root";
    private $database_password = "";
    private $connection;

    public function connect_database() {
        // Trả về kết nối hiện tại nếu đã kết nối tới database trước đó
        if ($this->connection) {
            return $this->connection;
        }

        // Tạo kết nối mới
        $this->connection = new mysqli($this->database_host, $this->database_username, $this->database_password);

        // Test connection
        if ($this->connection->connect_error) {
            die("Lỗi kết nối tới database: " . $this->connection->connect_error);
        }

        return $this->connection;
    }
}

Ở trên bạn cần thay đổi giá trị các thuộc tính như $database_host (thay bằng địa chỉ IP của database server trong trường hợp bạn kết nối tới database nằm ở remote server thay vì ở máy local), $database_name và $database_password.

Cuối cùng logic code của method save() để lưu trữ dữ liệu vào bảng $table lúc này sẽ như sau:

class MyActiveRecord {
    ...

    // logic xử lý việc lưu trữ vào bảng $table
    public function save() {
        // Kết nối tới database
        $this->connect_database();

        // Lấy ra giá trị của tất cả các thuộc tính của object hiện tại theo dạng array
        $data = get_object_vars($this);

        // Debug code: Kiểm tra dữ liệu của biến $data
        // print_r($data);

        // Logic sử dụng dữ liệu của object để lưu trữ vào bảng $table
        // Mỗi thuộc tính của object sẽ tương ứng với một trường trên bảng $table
        // Ví dụ: $title sẽ ứng với trường `title`, $content sẽ ứng với trường `content`

        $keys = array_keys($data);
        $values = array_values($data);

        $$sql = "INSERT INTO "
            . $this->table . "(" . implode(",", $keys) . ") "
            . "VALUES(" . implode(",", $values) . ")";

        // Debug code: Kiểm tra câu lệnh insert data
        // echo $$sql;

        // Chạy truy vấn tới database để lưu trữ dữ liệu vào bảng $table
        $mysqli->query($sql);
    }
}

Kết Luận

Trên đây chúng ta đã cùng nhau tham khảo ví dụ đơn giản minh hoạ cho kiểu thiết kế một class ActiveRecord. Trên thực tế thì hầu hết tất cả các ngôn ngữ lập trình hay framework đều cung cấp sẵn class ActiveRecord và chúng ta chỉ việc sử dụng thay vì phải viết lại từ đầu như ở trên.

0