harp-orm / harp
轻量级且灵活的ORM,无魔法
Requires
- php: >=5.4.0
- harp-orm/query: ~0.2.0
- harp-orm/serializer: ~0.1.0
- harp-orm/util: ~0.2.2
- harp-orm/validate: ~0.4.0
This package is auto-updated.
Last update: 2024-09-21 20:59:09 UTC
README
Harp ORM
Harp ORM 是一个轻量级的 PHP 对象持久层 DataMapper。
快速示例
// Model Class use Harp\Harp\AbstractModel; class UserModel extends AbstractModel { public static function initialize($config) { $config ->addRel(new Rel\BelongsTo('address', $config, Address::getRepo())); } public $id; public $name; public $email; public $addressId; public function getAddress() { return $this->get('address'); } public function setAddress(Address $address) { return $this->set('address', $address); } } // Saving new model $user = new UserModel(['name' => 'my name']); UserRepo::save($user); // Loading model $loadedUser = UserRepo::find(1); var_dump($loadedUser); // Loading related model $address = $loadedUser->getAddress(); var_dump($loadedUser->getAddress());
为什么?
为什么还需要另一个ORM?目前没有ORM使用最新的PHP特性。PHP语言本身的近期进步(例如 traits),以及外部静态分析工具,使得编写易于验证为正确的应用程序成为可能,然而大多数现有的ORM都没有使用它们,这使得静态代码分析不太有用。最后,这个包旨在更接近底层,智能地使用现有的PHP类和扩展来使您的模型快速,而不牺牲功能。这里是简要介绍:
- 尽可能使用 harp-orm/query 和 PDO,从而大大提高性能。它具有一些当前ORM没有的非常有用的功能。
- 完全支持 多态 - 既有“属于多态”又有“单表继承”
- 正确的 软删除,代码的每个部分都知道
- 延迟加载 和 预加载,适用于多态关系
- 使用 分组查询 保存多个模型,以增加性能
- 不强制文件夹结构,将您的类放置在任何地方
- 使用 PSR编码风格 和 symfony命名约定,使代码库更干净、更易于阅读
- 使用单个命令保存所有关联模型,底层使用 查询分组。
- 完全可扩展的接口。使用原生PHP5构造来允许使用 traits 和接口进行 扩展
- 所有方法都有 正确的docblocks,以便对基于此构建的代码进行更准确的静态代码分析。
安装
Harp 使用 composer,所以安装就像这样简单
composer require harp-orm/harp:~0.3.0
它使用 harp-orm/query 连接到数据库,因此您还需要配置连接
use Harp\Query\DB; DB::setConfig([ 'dsn' => 'mysql:dbname=harp-orm/harp;host=127.0.0.1', 'username' => 'root', 'password' => 'root', ]);
子部分
定义模型
以下是一个示例模型类。
use Harp\Harp\AbstractModel; class User extends AbstractModel { // Configure the "Repo" object for this model class // This holds all the database-specific configs, // as well as relations with other models public static function initialize($config) { $config // Configure relations ->addRel(new Rel\BelongsTo('address', $config, AddressRepo::get())); // Configure validations ->addAssert(new Assert\Present('name')) ->addAssert(new Assert\Email('name')); } // Public properties persisted as columns in the table public $id; public $name; public $email; public $addressId; }
所有公共属性都持久化到数据库中,如果可用,则使用原生类型。
提示 一旦加载了相关对象,它们将被缓存并在后续请求中返回,然而数据不会保留在模型本身中,因此如果您对一个模型进行
var_dump
,它将仅返回模型本身的数据,并保持堆栈跟踪的清晰。
所有配置方法的详细列表
有关事件的更多信息,请参阅 使用事件进行扩展
从数据库检索
从数据库中检索模型(以及保存,但稍后再说)是通过模型类上的静态方法处理的。要按主键查找模型,请使用 find
方法。
$user1 = User::find(8); $user2 = User::find(23);
如果模型有一个“name”属性(或配置了nameKey),则可以使用 findByName
方法。
$user1 = User::findByName('Tom'); $user2 = User::findByName('John');
对于更复杂的检索,可以使用 findAll
方法,它返回一个 'Find' 对象。它具有构建SQL查询的方法的丰富接口
$select = User::findAll(); $select ->where('name', 'John') ->whereIn('type', [1, 4]) ->joinRels(['address' => 'city']) ->limit(10); $users = $select->load(); foreach ($users as $user) { var_dump($user); }
从数据库检索的所有模型都存储在“身份映射”中。因此,如果在以后的时间,再次加载相同的模型。它将返回相同的PHP对象,与数据库行相关联。
$user1 = User::find(10); $user2 = User::find(10); // Will return true echo $user1 === $user2;
详细 findAll 的文档
持久化模型
当模型被创建、修改或删除后,通常需要再次持久化。这可以通过模型上的 "save" 方法完成。
$user = User::find(10); $user->name = 'new name'; $address = new Address(['location' => 'home']); $user->setAddress($address); // This will save the user, the address and the link between them. User::save($user); $user2 = User::find(20); $user2->delete(); // This will remove the deleted user from the database. User::save($user2);
当你添加/删除或以其他方式修改相关模型时,它们将与你的主要模型一起保存。
保留多个模型
你可以使用 saveArray
方法一次性保留同一仓库中的多个模型(使用查询分组)。只需传递一个模型数组。
$save = User::saveArray([$user1, $user2, $user3]);
软删除
如果你需要在删除模型后仍将其保留在数据库中,例如逻辑删除,可以使用 SoftDeleteTrait
// Model File use Harp\Harp\AbstractModel; use Harp\Harp\Model\SoftDeleteTrait; class Order extends AbstractModel { use SoftDeleteTrait; public static function initialize($config) { // The trait has its own initialize method that you'll have to call SoftDeleteTrait::initialize($config); } } $order = Order::find(2); $order->delete(); // This will issue an UPDATE instaead of a DELETE, marking this row as "deleted". Order::save($order); $order = Order::find(2); // This will return true echo $order->isVoid();
这将在你的模型上添加一些方法。关于软删除的详细信息请在此处阅读
继承
有时你需要多个模型共享同一个数据库表 - 例如,如果同一功能只有细微的差别。这被称为单表继承。
Harp ORM 支持开箱即用的模型继承。关于继承的详细信息请在此处阅读
模型状态
在整个生命周期中,模型有不同的状态(Harp\Harp\Model\State)。它们可以是
有几种方法可以处理模型状态
脏跟踪
模型跟踪其公共属性的所有更改,以最小化对数据库的更新。你可以通过调用这些方法来使用该功能
示例
$user = User::find(10); // returns false echo $user->isChanged(); $user->name = 'new test'; // returns true $user->isChanged(); // returns true $user->hasChange('name'); // returns ['name' => 'new test'] $user->getChanges(); // returns original name $user->getOriginal('name'); $user->resetOriginal(); // returns 'new test' $user->getOriginal('name');
扩展
当你想编写扩展 Harp ORM 功能的包,或者简单地在不同模型之间共享代码时,你可以使用 PHP 的原生 Traits。它们允许你静态地扩展类。Harp ORM 的所有内部结构都是围绕允许你轻松完成此操作构建的,这是编写 "行为" 或 "模板" 的首选方式。
除此之外,你还将能够为模型生命周期的各种事件添加事件监听器。
关于扩展的详细信息请在此处阅读
直接数据库访问。
有时你需要直接接触底层并编写自定义 SQL。为了帮助你这样做,你可以直接使用内部查询类。
$update = User::insertAll() ->columns(['name', 'id']) ->select( Profile::selectAll() ->clearColumns() ->column('name') ->column('id') ->where('name', 'LIKE', '%test') ); // INSERT INTO User (name, id) SELECT name, id FROM Profile WHERE name LIKE '%test' $update->execute();
关于自定义查询的更多细节,请参阅查询部分
许可协议
版权所有 (c) 2014, Clippings Ltd. 由 Ivan Kerin 在clippings.com开发
在 BSD-3-Clause 许可协议下,请阅读 LICENSE 文件。
图标由 Freepik 制作,来源于 www.flaticon.com