Analogue ORM入门实战教程:手把手写出第一个Entity与EntityMap映射类
【免费下载链接】analogueAnalogue ORM : Data Mapper ORM for Laravel/PHP项目地址: https://gitcode.com/gh_mirrors/an/analogue
Analogue 是一个专为 PHP 和 Laravel 打造的Data Mapper(数据映射器)ORM,它用严格的关注点分离取代了 Eloquent 的 Active Record 模式。本文带你从 0 开始,手把手写出第一个 Entity 实体类与 EntityMap 映射类,掌握对象与数据库表之间的映射核心玩法。
为什么选择 Analogue ORM?🤔
Laravel 自带的 Eloquent 很优秀,但它属于 Active Record 模式——模型既负责数据又负责行为,在复杂业务中容易出现架构耦合。Analogue ORM 采用Data Mapper 模式,把模型层拆成两个类:
| 对比项 | Eloquent(Active Record) | Analogue(Data Mapper) |
|---|---|---|
| 模型数量 | 1 个 Model | 1 个 Entity + 1 个 EntityMap |
| 业务逻辑 | 混在 Model 里 | 集中在纯 PHP 实体中 |
| 值对象(Value Object) | 难以正确实现 | 原生支持 |
| 单表继承 | 基本不可能 | 完整支持 |
| 懒加载 / 急加载 | 支持 | 支持 |
💡 一句话理解:Entity 是你的领域对象(纯业务),EntityMap 是"翻译官"(负责告诉 ORM 数据库里长什么样)。
环境安装:一条命令搞定
在 Laravel 项目根目录执行:
composer require analogue/ormAnalogue 要求PHP >= 7.0,兼容 Laravel 5.5 / 5.6,作为 Laravel 包会自动发现服务提供者,无需额外配置(见 composer.json 中的extra.laravel.providers自动注册逻辑)。
如果你的本地环境没有 Composer 包源,也可以先克隆仓库源码再引入:
git clone https://gitcode.com/gh_mirrors/an/analogue第一步:编写你的第一个 Entity 实体
Entity 就是普通的 PHP 类,继承Analogue\ORM\Entity即可获得魔法 Getter/Setter、隐藏属性、数组转换等能力(实现见 src/Entity.php):
use Analogue\ORM\Entity; class Blog extends Entity { // 可以直接定义构造函数和领域方法 public function __construct() { $this->title = ''; } }就是这么简单!你甚至不需要写任何 getter/setter——Analogue 通过__get/__set魔法方法自动读写属性(源码见 src/Entity.php#L23-L60)。
第二步:编写 EntityMap 映射类
EntityMap 继承Analogue\ORM\EntityMap(核心实现见 src/EntityMap.php),负责三件事:
- 表名映射:默认取实体类名的复数蛇形命名,如
Blog→blogs表; - 主键定义:默认为
id; - 关系定义:用方法声明一对一、一对多等关系。
对应上面的 Blog 实体,写一个最小可用的映射类:
use Analogue\ORM\EntityMap; class BlogMap extends EntityMap { // 开启 created_at / updated_at 时间戳 public $timestamps = true; // 可选:自定义表名 // protected $table = 'my_blogs'; // 可选:自定义主键 // protected $primaryKey = 'uuid'; // 可选:数据库列名与属性名不一致时,做映射 // protected $mappings = ['title' => 'blog_title']; }📌命名约定:EntityMap 放在与实体相同命名空间下时会自动检测,例如App\Blog对应App\BlogMap。
第三步:定义实体之间的关系
关系的声明方式与 Eloquent 几乎一致,只是写在 Map 里。参考项目测试用例中的完整示例 tests/src/Maps/BlogMap.php:
class BlogMap extends EntityMap { public $timestamps = true; // 博客属于一个用户 public function user(Blog $blog) { return $this->belongsTo($blog, User::class); } // 一个博客有多篇文章 public function articles(Blog $blog) { return $this->hasMany($blog, Article::class); } }Analogue 支持的常用关系类型(源码目录 src/Relationships/):
hasOne/hasMany:一对一 / 一对多belongsTo/belongsToMany:多对一 / 多对多morphOne/morphMany/morphTo/morphToMany:多态关系hasOneThrough/hasManyThrough:穿透查询embedsOne/embedsMany:嵌入值对象,这是 Eloquent 做不到的(如把图片尺寸存成 JSON 字段)
第四步:用 mapper() 持久化与查询
Analogue 提供全局辅助函数mapper()(定义在 src/helpers.php),返回实体的 Mapper 对象:
use TestApp\Blog; // 创建并保存:Analogue 会自动级联同步关联对象 $blog = new Blog; $blog->title = "我的第一个博客"; mapper(Blog::class)->store($blog);查询同样流畅,Mapper 支持完整的链式 Query Builder:
// 取第一条 $blog = mapper(Blog::class)->first(); // 条件查询 + 急加载关联 $blogs = mapper(Blog::class) ->where('title', 'like', '%博客%') ->with('articles') // 急加载,避免 N+1 问题 ->get(); // 分页 $paginator = mapper(Blog::class)->paginate(15);✨ 只需
store($blog)保存主实体,Analogue 会在幕后自动同步所有关联的 Blog、Article 对象,省去一堆手动save()。
项目源码结构速览 🔍
理解以下核心文件,能帮你快速深入 Analogue 内部机制:
- 实体基类:src/Entity.php
- 映射基类:src/EntityMap.php
- Mapper 核心(store/delete/事件):src/System/Mapper.php
- 全局辅助函数:src/helpers.php
- 事件系统(Creating/Stored/Deleted 等):src/Events/
- 软删除 / 时间戳插件:src/Plugins/
- 更多实体映射范例:tests/src/Maps/
常见新手问题 FAQ
Q1:Entity 里可以直接写构造函数吗?可以。Analogue 通过doctrine/instantiator绕过构造函数创建实例;若实体需要依赖注入,在 Map 中设置$dependencyInjection = true即可(见 src/System/Mapper.php#L554-L563)。
Q2:数据库列名是蛇形、属性想用小驼峰怎么办?在 Map 中开启protected $camelCaseHydratation = true;,或使用$mappings数组手动映射列名(如remember_token→rememberToken,参考 tests/src/Maps/UserMap.php)。
Q3:怎么开启软删除和时间戳?在 Map 中声明public $softDeletes = true;和public $timestamps = true;,两者都由 src/EntityMap.php 内置支持。
总结
恭喜你!已经掌握了 Analogue ORM 的核心工作流:
- Entity:继承
Entity的纯业务实体,零样板代码; - EntityMap:继承
EntityMap的映射类,配置表名、时间戳、关系; - mapper():一行代码完成对象的保存、查询、删除。
相比 Eloquent,Analogue 用"两个类换一份清晰",让领域模型不再被框架污染,非常适合需要值对象、单表继承等企业级场景的 Laravel 项目。下一步建议阅读仓库内的测试目录,那里有涵盖所有关系类型的完整可运行示例(tests/cases/Relationships/)。
【免费下载链接】analogueAnalogue ORM : Data Mapper ORM for Laravel/PHP项目地址: https://gitcode.com/gh_mirrors/an/analogue
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考