crocodile2u/tinyorm

v1.1.12 2018-03-11 21:37 UTC

This package is auto-updated.

Last update: 2024-09-14 22:43:37 UTC


README

非常简洁的 PHP ORM & 数据库工具

为什么还要另一个库?

我知道很多类似的项目,但它们都不令我满意。因此,我制定了一份要求列表,我的完美 ORM 库应该满足这些要求。

  • 它应该很小。我不想因为想自动化数据库操作而在我的下一个项目中添加大量的类。
  • 它不应该太智能。它应该帮助我完成普通任务,并尽可能保持在我的控制之下。
  • 它不应该生成数据库模式。对于迁移,我将使用专门的工具。
  • 不要懒加载相关对象。没有这种魔法,没有幕后垃圾。
  • 不要在 SQL 中使用奇怪的别名,例如 SELECT * FROM \model\Foo JOIN \model\Bar ...
  • 瘦实体,不包含任何业务逻辑或甚至存储特定逻辑(关系等)。这会使事情变得过于复杂,并导致开发人员控制力降低。将持久化逻辑与实体分离,即使在切换存储后端时,实体也可以重用。虽然这并不经常需要,但这是一个方便的功能,很容易实现。此外,有时我可能希望以不同的方式访问同一个实体:例如,如果我有一张表,我想通过 MySQL & Handlersocket 同时访问它。
  • 具有整洁界面的查询对象实现。我通常喜欢手动编写 SQL 查询。然而,在某些情况下,查询需要动态生成,在这种情况下,具有整洁界面的对象比手动组合 SQL 字符串具有很大的优势。
  • 它应该能够处理多个数据库连接。理想情况下,它应该有一个事务管理器,为所有参与数据库交互的连接发出 BEGIN/COMMIT/ROLLBACK。
  • 理想情况下,它应该有一个脚手架工具,可以从数据库表生成实体。

尽管有一些工具符合某些要求,但我未能找到具有所有这些功能的库。

给我看代码!

选择使用方法

$select = (new Select("my_table"))
    ->join("LEFT JOIN another_table USING (join_column)")
    ->where("filter_column = ?", $filterColumnValue)
    ->setConnection($db);
$count = $select->count("DISTINCT id");
$rows = $select->execute()->fetchAll(\PDO::FETCH_ASSOC);

您可以设置 Select 的获取模式

$select->setFetchMode(\PDO::FETCH_ASSOC);
$select->setFetchClass(MyTableEntity::class);
$select->setFetchInto(new MyTableEntity());

使用多个数据库连接

$txManager = new \tinyorm\TxManager();
$txManager->registerConnection($this->connection)
    ->registerConnection($this->connection2);

$result = $txManager->atomic(function () {
    $this->connection->exec("INSERT INTO test (c_unique) VALUES ('val1')");
    $this->connection2->exec("INSERT INTO test (c_unique) VALUES ('val2')");
    return true;
});

这样,如果第一个或第二个 INSERT 出现问题,两个连接中的事务都将回滚,不会插入任何行。另一方面,如果一切顺利,两个连接中的事务都将提交。

事务管理器支持嵌套事务,tinyorm\Db 类也支持它们。

方法

我使用了一种类似于 Zend Framework 2 的方法( http://framework.zend.com/manual/current/en/user-guide/database-and-models.html )。实体类只是简单的数据容器,没有数据库连接/持久化逻辑。然而,最终,tinyorm 实体对其与存储层的关系有最小“了解”。首先,它们有 getSourceName() 方法,本质上是为了返回存储表/集合名称。其次,有 getPK()setPK() 方法来访问主键。主键列的名称存储在受保护的 pkName 属性中。最后,实体有 getSequenceName()。我这样做是为了简化,为了避免引入更多的类。tinyorm 只支持 AUTO_INCREMENT 主键。与 Zend Framework 2 相比,所有与持久化相关的只是几个类/接口

  • DbInterface - 数据库连接器的接口
  • Db - PDO 的包装器
  • persistence\Driver - 持久化驱动程序的接口
  • 持久化数据库驱动程序:使用Db/PDO(因此是RDBMS)作为后端的数据持久化驱动程序。虽然仅与MySQL进行了测试,但也应该可以很好地与Postgres和Sqlite一起工作。
  • 持久化数据库驱动程序:使用handlersocket作为后端的数据持久化驱动程序。

持久化数据库驱动程序在实体上操作。在ZF2的情况下,我们可以将它们的表网关视为持久化数据库驱动程序。请参阅上面的链接以获取参考。在tinyorm中,事情要简单得多。您只需创建一个持久化数据库驱动程序实例,并调用其save()insert()update()delete()方法,提供实体作为参数。

对于查询对象,我研究了Phalcon框架(https://docs.phalconphp.com/en/latest/api/Phalcon_Mvc_Model_Query_Builder.html)。然而,我稍微修改了接口,因此我觉得它更好一些。

我还实现了一个能够处理多个数据库连接的数据库事务管理器。

致谢

感谢RasmiKanta Moharana(https://github.com/rashmi8105)对早期反馈和发现示例应用程序中的错误!