belongsTo 理念来源
1. 根本来源:关系型数据库设计
belongsTo 理念源于 关系型数据库的外键概念:
sql
-- 数据库层面:外键关系
CREATE TABLE shopro_commission_member_pv (
id INT PRIMARY KEY,
member_id INT,
pv_amount INT,
-- member_id 是外键,指向 shopro_user 表的 id
FOREIGN KEY (member_id) REFERENCES shopro_user(id)
);
这表达了一种数据关系:PV 记录"属于"某个用户。
2. ORM 框架的抽象化
Rails 的 ActiveRecord ORM (2005年左右)首创了将数据库关系转化为代码方法:
ruby
# Rails 中的做法(ActiveRecord)
class MemberPv < ApplicationRecord
belongs_to :user, foreign_key: "member_id"
end
# 使用
pv = MemberPv.find(1)
pv.user.nickname # 自动根据 foreign_key 关联查询
3. ThinkPHP 的借鉴
ThinkPHP 框架设计者参考了 Rails 的思想,设计了类似的 ORM 关联系统:
php
// ThinkPHP 的做法(模仿 Rails)
class MemberPv extends Common {
public function user() {
return $this->belongsTo(User::class, 'member_id', 'id');
}
}
4. 设计理念演变链
关系型数据库外键
↓
SQL 中的 JOIN 操作
↓
Rails ActiveRecord ORM
↓
Eloquent (Laravel)
↓
ThinkPHP ORM
↓
其他 PHP 框架 (Doctrine, Propel)
5. 抽象化的三个层级
第一层:数据库层
sql
-- 数据关系定义在数据库中
FOREIGN KEY (member_id) REFERENCES shopro_user(id)
第二层:SQL 查询层
sql
-- 通过 JOIN 关联查询
SELECT pv.*, u.* FROM shopro_commission_member_pv pv
LEFT JOIN shopro_user u ON pv.member_id = u.id
第三层:ORM 对象层
php
// belongsTo 将上面两层抽象为对象方法
$pv = MemberPv::with('user')->find(1);
$pv->user->nickname; // 一句代码完成前两层的工作
6. 为什么要设计 belongsTo?
| 原因 | 说明 |
|---|---|
| 屏蔽 SQL 复杂性 | 开发者不需要写复杂的 JOIN 语句 |
| 思维对象化 | 用对象关系思考,而不是表和字段 |
| 减少重复代码 | 关联逻辑集中在模型中定义一次 |
| 提高可维护性 | 关系变化只需改模型定义 |
| 自动优化查询 | 框架可自动选择 JOIN 还是子查询 |
7. 同类产品对比
所有现代 ORM 都有类似的概念,名称略有不同:
| 框架 | 概念名 | 语法 |
|---|---|---|
| Rails | belongs_to |
belongs_to :user |
| Laravel | belongsTo |
belongsTo(User::class, 'member_id') |
| ThinkPHP | belongsTo |
belongsTo(User::class, 'member_id', 'id') |
| Doctrine (PHP) | @ManyToOne |
注解定义 |
| Hibernate (Java) | @ManyToOne |
注解定义 |
8. 完整演变示例
php
// ❌ 原始时代(2005年前)- 纯 SQL
$sql = "SELECT pv.*, u.* FROM shopro_commission_member_pv pv
LEFT JOIN shopro_user u ON pv.member_id = u.id
WHERE pv.id = 1";
$result = $db->query($sql);
// ⚠️ 中期(2005-2010)- 查询构造器
$result = $db->table('shopro_commission_member_pv')
->leftJoin('shopro_user', 'shopro_commission_member_pv.member_id', '=', 'shopro_user.id')
->where('shopro_commission_member_pv.id', 1)
->get();
// ✅ 现代(2010+)- ORM 关联
class MemberPv extends Common {
public function user() {
return $this->belongsTo(User::class, 'member_id', 'id');
}
}
$pv = MemberPv::with('user')->find(1);
核心设计思想
belongsTo 的核心是: 用面向对象的语言描述关系型数据库的约束关系,让开发者可以像操作对象一样操作数据关联,而不是写 SQL。
这是 ORM (Object-Relational Mapping) 的核心目标。