Để thao tác với dữ liệu trên Server thông thường chúng ta thường dùng các câu truy vấn thuần túy nhưng với Yii2 ngoài việc hỗ trợ truy vấn dạng Query Buider thì Yii2 còn hỗ trợ thêm dạng đôi tượng là ActiveRecord giúp việc viết các câu truy vấn dễ dàng và hiệu quả hơn.
Cách thức hoạt động ActiveRecord
ActiveRecord là một đối tượng (Object) được liên kết với cơ sở dữ liệu, một đối tượng như vậy tương ứng với 1 bản ghi trong bảng dữ liệu và một thuộc tính(attribute) của 1 ActiveRecord thể hiện giá trị của một cột cụ thể trong bản ghi đó.Thay vì sử dụng viết các câu truy vấn thuần SQL, các đồng code sẽ truy cập các thuộc tính và phương thức của ActiveRecord để thao tác với cơ sở dữ liệu.
Ví dụ, tại hạ có 1 đối tượng là User được liên kết với bảng user và có 2 cột là name và phone
- Việc thêm mới dữ liệu sẽ như sau
// Cách insert dữ liệu thông thường
$user = new User();
$user->name = 'ABC';
$user->phone = '0123456789';
$user->save();
//Cách insert cùng lúc các thuộc tính
$values = [
'name' => 'ABC',
'phone' => '0123456789',
];
$user = new User();
$user->attributes = $values;
$user->save();
//trong SQL
INSERT INTO `user` (`name`, `phone`) VALUES ('ABC', '0123456789');
- Để update dữ liệu tại hạ sử dụng hàm find() hoặc hàm update() hoặc updateAttributes() với 1 số field tùy chọn
// sử dụng với findOne() và save()
$user = User::findOne(1);
$user->name = 'ABCD';
$user->phone = '0123456789';
$user->save();
// sử dụng với update()
$user = User::findOne(1);
$user->name = 'ABCD';
$user->phone = '0123456789';
$user->update();
//sử dụng với updateAttributes
$user = User::findOne(1);
$user->updateAttributes(['name' => 'DEF']);
//SQL tương ứng
UPDATE `user` SET `name` = 'ABCD',`phone` = '0123456789' WHERE `user`.`id` = 1
Các hàm save(), update() sẽ chạy các event đi kèm của Yii2 sau khi thực thi xong còn đối với hàm updateAttributes thì sẽ không chạy các event sau khi đã update.
Hàm save(), các đồng code có thể truyền tham số vào dạng boolean, mặc định tham số truyền vào là true thì trước khi save các trường dữ liệu hay các thuộc tính(attribute) sẽ chạy qua rules để validate trước nếu hợp lệ thì sẽ được lưu lại. Ngược lại, nếu set tham số là save(false) thì các trường dữ liệu sẽ không validate mà sẽ lưu thẳng vào cơ sở dữ liệu, đối với hàm update() cũng tương tự.
Hàm findOne(), các đồng code có thể truyền trực tiếp vào là giá trị của khóa chính(PrimaryKey) hoặc truyền vào 1 mảng các điều kiện.
$user = User::findOne(1); // 1 là id của user là khóa chính
$user = User::findOne(['id' => 1, 'status' => 10]); // truyền vào mảng các điều kiện, ở đây là id = 1 và status = 10
- Để update nhiều bản ghi một lúc ngoài việc các đồng code có thể sử dụng vòng lặp để update thì nên dùng hàm updateAll()
//sử dụng updateALL
User::updateAll(['name' => 'GHK'], 'phone = 0123456789'); // update name tất cả các user có số điện thoại là 0123456789 thành GHK
// tham số đầu tiên sẽ là giá trị set update, tham số thứ 2 là điều kiện
- Để xóa bản ghi tại hạ sử dụng hàm delete() và xóa nhiều là deleteAll()
//xóa 1 bản ghi
$user = User::findOne(1);
$user->delete();
//xóa nhiều bản ghi
Customer::deleteAll(['name' => 'ABC']); // xóa các bản ghi có name là ABC
Ngoài việc lấy ra một bản ghi dữ liệu bằng cách sử dụng findOne thì có thể dùng find()->where(condition)->one() cũng có kết quả tương tự
$user = User::findOne(1); // vói findOne() tham số truyền vào là bắt buộc
// hoặc
$user = User::find()->where(['id' => 1])->one();
//để lấy bản ghi đầu tiên trong bảng dữ liệu
$user = User::find()->one();
Để lấy ra nhiều bản ghi các đồng code sử dụng findAll() hoặc find()->all()
$user = User::findAll(['status' => 10]); //giống như findOne() các tham số bắt buộc phải truyền vào
//hoăc
$user = User::find()->where(['status' => 10])->all();
//hoặc
$user = User::find()->all(); //lấy ra tất cả các bản ghi mà không cần điều kiện
Các đồng code cũng có thể sử dụng findBySql() để viết các câu SQL như bình thường
$sql = 'SELECT * FROM user WHERE type=:type';
$user = User::findBySql($sql, [':type' => 10])->all();
Nếu sử dụng đồng thời hoặc không đồng thời các điều kiện trong truy vấn thì các đồng code sử dụng như sau
// lấy ra user có phone là 0123456789 và có status là 10
$user = User::find()->where(['phone' => '0123456789'])->andWhere(['status' => 10])->all();
// lấy ra user có phone là 0123456789 hoặc có status là 10
$user = User::find()->where(['phone' => '0123456789'])->orWhere(['status' => 10])->all();
// lấy ra các user có trong mảng id
$ids = [1,2,3,4,5];
$user = User::find()->where(['in', 'id', $ids])->all();
// lấy ra các user không có trong mảng id
$user = User::find()->where(['not in', 'id', $ids])->all();
//lấy ra các user khác id = 1
$user = User::find()->where(['<>','id',1])->all();
//lấy ra các user khác id > 1
$user = User::find()->where(['>','id',1])->all();
//lấy ra các user có tên ABC
$user = User::find()->where(['like','name','ABC'])->all();
Ngoài sử dụng where(), các đồng code có thể sử dụng filterWhere để loại bỏ các toán hạng rỗng trong câu truy vấn, nó cũng tương tự như where().
Trên đây tại hạ chỉ đưa ra các hàm cơ bản của ActiveRecord thường dùng, để cụ thể hơn các đồng code có thể tham khảo thêm tại đây.
Sử dụng với model
Với việc sử dụng model để tương tác dữ liệu với mô hình hướng đối tượng bằng việc kế thừa từ ActiveRecord.
namespace app\models;
use yii\db\ActiveRecord;
class User extends ActiveRecord
{
public static function tableName()
{
return '{{user}}';
}
}
- Hàm tableName() trả về tên bảng dữ liệu tương ứng trong cơ sở dữ liệu. ActiveRecord được coi như là một model vì ActiveRecord kế thừa từ class yii\base\Model. nó sẽ kế thừa tất cả các tính năng có từ Model.
Để có thể hiểu rõ hơn việc hoạt động cũng như vòng đời của ActiveRecord, tại hạ xin phép sẽ cập nhật trong bài viết sau về Trigger và Relation.