Skip to content

Latest commit

 

History

History
150 lines (116 loc) · 4.51 KB

db_model.md

File metadata and controls

150 lines (116 loc) · 4.51 KB

模型

概述

要使用模型需要先修改 usr/init.php,取消 \Cabal\DB\Model::setDBManager($server->db()); 注释。

这里顺便说一下,Martin Fowler架构大神 很久之前就开始质疑ORM到底好与不好了[点击查看原文]。

使用 ORM 后通常开发效率会提高很多,但是在复杂的业务场景下,对象到处传递后,对象的值和数据库中的值是否一致变得很模糊,也就会增加代码的复杂度和维护难度变高。

定义

下面是一个最简单的 模型类:

use Cabal\DB\Model;
class User extends Model
{
    // 表名
    protected $tableName = 'user';
}

模型类还支持下面的配置和语法:

use Cabal\DB\Model;
use Cabal\DB\Table;

class User extends Model
{
    // 表名
    protected $tableName = 'user';
    // 日期字段 这些字段会字段转换为 Carbon\Carbon 对象
    protected $dates = array('created_at', 'deleted_at', 'updated_at');
    // 是否使用数据时间戳 - created_at&updated_at 字段会自动填充创建时间也编辑时间
    protected $timestamps = true;
    // toArray 时会追加的字段 需要定义 __getXX魔术方法
    protected $appends = ['anno_name'];
    // 允许用 fill 方法填充的字段
    protected $fillable = array();
    // 不允许自动填充的字段
    protected $guarded = array('*');
    // 日期字段 数据库保存格式
    protected $dateFormat = 'Y-m-d H:i:s';

    // 数据库不存在的字段 可以使用魔术方法支持获取
    public function __getAnnoName($value = null)
    {
        return 'AnnoName';
    }

    // 复杂的数据格式可以用一对魔术方法实现 写入序列话,读取反序列化
    public function __getJson($value = null)
    {
        return json_decode($value, true);
    }
    public function __setJson($value)
    {
        $this->dbData['json'] = json_encode($value);
    }

    // 可以自定义关联数据字段
    public function __getPublishArticles()
    {
        return $this->has(Article::class, function (Table $table) {
            $table->where('status = ?', 1);
        }, 'publishedArticle');
    }
}

增删改查

查询

查询语法和 DB 基础语法一致,只是需要用 ModelName::query() 开始一个查询。

User::query()->where('id = ?', 1)->first();
User::query()->rows();
User::query()->paginate(3, 2);

创建

一个新的模型对象调用 ->save() 方法表示创建。

$user = new User;
$user->name = uniqid();
$user->save();

编辑

一个已存在的模型对象 调用 ->save() 方法只会保存修改过的字段,如果没用修改过的字段不会操作数据。

$user = User::query()->first();
$user->name = 'new name';
$user->save();

删除

$user = User::query()->first();
$user->delete();

魔术方法

采用的是和PHP的模式方法类似的 __ 开头函数,方法名采用驼峰命名,如字段 ->anno_name 对应的是 __getAnnoName 方法。

可以采用一对魔术方法实现数据库字段自动序列化和反序列化:

public function __getJson($value = null)
{
    return json_decode($value, true);
}
public function __setJson($value)
{
    $this->dbData['json'] = json_encode($value);
}

关联查询

模型的关联查询和关联查询的语法类似,只是第一个参数从表明变成了类名:

$user->has($model, $foreignKeyOrCallback = null, $callback = null, $storeKey = null);

  • className 目标类名
  • foreignKeyOrCallback 外键名称或者回调函数,如果不传或传入的是一个函数则外键默认为:表名+_id user_id
  • callback 回调函数,可以自己追加一些查询条件
  • storeKey 存储键名 默认为类名,同一个关联类多次查询但是条件不同需要自定义存储键名

$article->belongs($model, $foreignKeyOrCallback = null, $callback = null, $storeKey = null);

  • className 目标类名
  • foreignKeyOrCallback 外键名称或者回调函数,如果不传或传入的是一个函数则外键默认为:目标表表名+_id user_id
  • callback 回调函数,可以自己追加一些查询条件
  • storeKey 存储键名 默认为类名,同一个关联类多次查询但是条件不同需要自定义存储键名
use Cabal\DB\Table;

$articles = $user->has(Article::class, function (Table $table) {
    $table->where('status = ?', 1);
}, 'publishedArticle');