数据模型


MiniFramwork 在 2.11.0 版本中对 Mini\Base\Model 模型类进行了升级,从 2.11.0 版本开始支持 ORM 特性,可以创建与数据表映射绑定的 ORM 数据模型,将 SQL 等数据库底层操作交由 ORM 数据模型处理,有助于开发者专注处理业务逻辑.

创建 ORM 数据模型

首先,假设数据库中有一个名为 user 的数据表,用于存储用户数据,数据表结构如下:

CREATE TABLE `user` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(32) DEFAULT NULL,
  `age` int(10) unsigned DEFAULT NULL,
  `email` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

然后,在应用的 Model 目录创建一个名为 User.php 的类,代码如下:

<?php
namespace App\Model;

use Mini\Base\Model;

class User extends Model
{
    public $id;
    public $name;
    public $age;
    public $email;

    protected function tableName()
    {
        return 'user';
    }
}

上述代码通过声明 public 属性,与数据表中的字段进行映射绑定,并通过 tableName() 方法绑定了数据表名。

使用数据模型

首先,在任意控制器中(例如 Index.php),实例化上一步创建的 User.php 模型类,代码如下:

<?php
namespace App\Controller;

use Mini\Base\Action;
use Mini\Base\Config;
use Mini\Db\Db;
use App\Model\User; // 引入 User.php

class Index extends Action
{
    function indexAction()
    {
        // 从配置文件中读入数据配置参数
        $dbParams = Config::load('database:default');

        // 实例化数据库对象
        $db = Db::factory('Mysql', $dbParams);

        // 实例化 User 数据模型
        $userModel = new User($db);

        // 后续业务逻辑代码......
    }
}

通过上述代码,获得了一个名为 $userModel 的模型对象,接下来逐一演示说明模型个各方法的用法。

findById

用途说明:按主键查找记录。

示例代码:

// 从配置文件中读入数据配置参数
$dbParams = Config::load('database:default');

// 实例化数据库对象
$db = Db::factory('Mysql', $dbParams);

// 实例化 User 数据模型
$userModel = new User($db);

// 通过主键查找记录(默认主键名为:id)
$userModel->findById(1);

// 如果找到记录,则下边的属性值与数据记录一致,否则为 NULL (数据记录的值也可能就是 NULL)
echo "主键:{$userModel->id}\n";
echo "姓名:{$userModel->name}\n";
echo "年龄:{$userModel->age}\n";
echo "邮箱:{$userModel->email}\n";

findByField

用途说明:按指定字段查找记录。

示例代码:

// 通过指定字段名查找记录
$userModel->findByField(1, 'id');

// 显示结果
echo "主键:{$userModel->id}\n";
echo "姓名:{$userModel->name}\n";
echo "年龄:{$userModel->age}\n";
echo "邮箱:{$userModel->email}\n";

findByFields

用途说明:按多个字段条件查找记录。

示例代码:

// 按多个字段条件查找记录,条件之间的逻辑关系默认 AND(第三个参数)
$userModel->findByFields(['name' => '小红', 'email' => 'xiaohong@email.com']);

// 显示结果
echo "主键:{$userModel->id}\n";
echo "姓名:{$userModel->name}\n";
echo "年龄:{$userModel->age}\n";
echo "邮箱:{$userModel->email}\n";

findAll

用途说明:查询多条记录。

示例代码:

// findAll 将返回一个对象数组,数组中每个对象映射一条数据记录
$users = $userModel->findAll();

// 遍历对象数组
foreach ($users as $user) {
    echo "主键:{$user->id}\n";
    echo "姓名:{$user->name}\n";
    echo "年龄:{$user->age}\n";
    echo "邮箱:{$user->email}\n";
}

提示:只有 findAll 方法是返回对象数组形式,其他 find 开头的方法均返回单个对象。

create

用途说明:创建新记录。

示例代码:

// 实例化数据模型
$userModel = new User($db);

// 给属性赋值
$userModel->name = '小杰';
$userModel->age = 19;
$userModel->email = 'xiaojie@email.com';

// 创建记录
$res = $userModel->create();

dump($res);

persist

用途说明:持久化存储(将当前模型中改变的属性保存至数据库)。

示例代码:

 // 查找主键为 1 的记录
if ($userModel->findById(1)) {

    // 如果找到了主键为 1 的记录,则将其属性(字段) age 的值修改为 19
    $userModel->age = 19;

    // 将修改后的数据保存至数据库
    $userModel->persist();

}

上边的代码也可以这样写:

// 查找主键为 1 的记录
$user = $userModel->findById(1);
if ($user) {

    // 如果找到了主键为 1 的记录,则将其属性(字段) age 的值修改为 19
    $user->age = 20;

    // 将修改后的数据保存至数据库
    $user->persist();
}

提示:未调用 persist 方法前,所有针对属性的修改,仅在对象内部生效, 调用 persist 方法后,修改后的数据才会保存至数据库。

remove

用途说明:从数据库中删除当前记录。

示例代码:

// 查找主键为 1 的记录
$user = $userModel->findById(1);
if ($user) {

    // 如果找到了主键为 1 的记录,且 age >= 18 时,则将其从数据库中删除
    if ($user->age >= 18) {
        $user->remove();
    }
}

删除多条记录可以这样写:

// 查找全部记录
$users = $userModel->findAll();

if ($users) {

    // 如果对象数组不为空,则进行遍历
    foreach ($users as $user) {

        // 将 age >= 18 的记录从数据库中删除
        if ($user->age >= 18) {
            $user->remove();
        }
    }
}