blackshawk / flipper
执行查询并将结果映射到一个或多个对象,无需定义对象之间的关系。
Requires
- php: >=5.4
- doctrine/dbal: 2.3.*
This package is not auto-updated.
Last update: 2024-09-14 14:34:49 UTC
README
Flipper 是一种简单的方法来编写 SQL 并将其映射到对象。您可以使用它将数据映射到任何类型的类;甚至您的 Doctrine 或 Propel 实体!它是在对必须指定 Doctrine 实体之间的复杂关联以构建复杂报告感到沮丧的情况下诞生的。
该项目仍在积极开发中!某些方面可能会发生重大变化,甚至完全消失!请谨慎操作!
安装
Flipper 可以通过 Composer 轻松安装和加载。您正在使用 Composer,对吧?
{
"require": {
"blackshawk/flipper": "dev-master@dev"
}
}
另一个 ORM?!
首先:**Flipper 并非旨在取代您的 ORM**。将 Flipper 视为日常 ORM 的可爱伴侣。它让您能够直接使用常规 SQL 并快速将结果映射到现有的实体(或您处理模型的方式)。
无需定义关系,也没有特殊的查询语法。只需编写一个返回响应的查询,并告诉 Flipper 您希望它去哪里。
Flipper 类本身是一个薄层,它使用 DBAL 数据库连接作为其构造函数。到那时,您可以通过 Flipper 发出查询,并自动将其映射到请求的对象。
以下是项目的设计目标。
- 数据源无关。
- 尽可能减少对 SQL 的干预。
- 不要试图成为 Doctrine、Propel 或其他重型 ORM。
- 提供一个简单的方法来拆分结果集,而无需指定这些对象之间的关系。
- 与现有的 ORM(如 Doctrine 和 Propel)完全兼容。您永远不需要 Flipper 特定的代码或类。
别再说了,给我看看代码。
这是一个最简单的 Flipper 示例——从一个数据库中查询单行。
require_once('vendor/autoload.php'); use \Flipper\Flipper; $flipper = new Flipper($connection); //where $connection is a DBAL instance $post = $flipper->queryOne('Post', 'select * from post where post_id = :id', ['id' => 35487]); //print_r result /** ..Post Object ( [id] => 35487 [title] => Call of the Wild [body] => Dark spruce forest frowned on either side the frozen waterway. ) **/
这是一个极其简单的示例,也可以用 PDO 完成。假设我们想要获取帖子的作者信息?
$query = 'select * from post p left join author a on p.author_id = a.author_id where p.post_id = :id'; $result = $flipper->queryOne(['Post', 'Author'], $query, ['id' => 35487], $split = 'author_id'); //print_r result /** Array ( [post] => Post Object ( [post_id] => 35487 [author_id] => 1 [created_date] => 2013-01-01 [title] => Call of the Wild [body] => Dark spruce forest frowned on either side the frozen waterway. ) [author] => Author Object ( [author_id] => 1 [first_name] => Jack [last_name] => London ) ) **/
一开始,$split 参数可能会让人困惑。Flipper 在您的数据上操作,而不是在您的对象上操作。在我们之前的例子中,我们已经指定了我们希望创建两个不同的类并填充数据。使用 split 参数,我们告诉 Flipper 哪里停止填充第一个对象,并开始填充第二个。通常,您需要为请求的每个附加对象指定一个 split。
功能
- 几乎可以将任何数据源扔给它——Flipper 都可以与之协同工作。这包括数组以及实现 Iterator 或 IteratorAggregate 接口的东西。如果它可以用
foreach()使用,它就可以与 Flipper 一起使用。 - 将结果映射到一个对象——或者多个。Flipper 不关心。
- 当与 Doctrine 实体一起工作时,Flipper 将尊重您的 ORM 注释,如
column_name。这样,您就可以返回post_id,并且它仍然可以无缝地映射到实体的id(仍在开发中!)。
常见问题解答
我的 ORM 已经可以做到所有这些!我只需要在这里指定这个关系...
是的,您可以在您喜欢的 ORM 中轻松指定一个关系来处理上述示例中的查询。问题是,其他 ORM 的复杂性会随着数据库的复杂性成比例增加。您有多少次不得不进入您的注释或 YAML/XML 配置中,寻找为什么某些东西行为不正常的原因?
Flipper始终保持简单,因为它不关心你的数据库看起来如何。你的查询复杂性无关紧要,因为Flipper永远不会操作比数组(array(), …)更复杂的东西。
查询构建器在哪里?
Flipper没有内置查询构建器。外面有成千上万种。只要你的首选实现了__toString(),当执行时,Flipper会为你将对象转换为SQL字符串。
我的ORM已经允许我直接使用原生SQL。
太好了!就像之前说的,Flipper并不打算取代你日常使用的ORM。然而,如果它像Doctrine的Native-SQL实现一样,你可能想更仔细地看看Flipper。
你是如何使用Flipper的?
目前,Flipper被用来处理在Doctrine中变得难以管理的查询。到目前为止,它已经是一个完美的补充。我的基本原则是,如果Doctrine在实体生成期间没有为我配置它,那么我就使用Flipper。
为了完成我对Flipper的愿景,还有很多开发工作要做,但它的起步很好,已经非常有用了。
我可以发出插入/更新/删除语句吗?
目前还不行。这在未来很容易添加,但我决定现在不为此费心,因为我非常乐意让Doctrine为我处理这些事情。此外,你还可以获得像生命周期回调等功能的全部好处,而这些在Flipper中是不可能的。
Flipper是如何处理像生命周期回调这样的东西的?
它不处理。
Flipper提供任何自动生成工具吗?
没有。虽然Doctrine在这方面做得很好。
Flipper能做“x”吗?
可能不行!
我应该移除所有我的(插入-ORM-here)内容并改用Flipper吗?
不。
Flipper的目的是什么?
Flipper是从我对像Doctrine这样的大型ORM的挫败感中诞生的。虽然它是一个了不起的项目,但我感觉在一些领域抽象已经开始过度。抽象可以是强大的,但当你开始看到完全围绕你的抽象出现一个全新的环境时,就有点问题。突然间我们进入了完全不同的氛围。程序员们从学习编写SQL(这是一种非常有用的技能)转变为学习如何不断地抽象,以避免编写SQL的需要。我们为了避开一个小土堆而建造了一条五十英里的绕行道。Flipper给你提供了一个隧道。
- 抽象我们所有的数据库写入是好的——它促进了数据完整性。
- 抽象我们所有的读取可能是不好的。
需要更多信息?维基百科有更多细节。