blackshawk/flipper

执行查询并将结果映射到一个或多个对象,无需定义对象之间的关系。

dev-master 2013-03-19 21:13 UTC

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 发出查询,并自动将其映射到请求的对象。

以下是项目的设计目标。

  1. 数据源无关。
  2. 尽可能减少对 SQL 的干预。
  3. 不要试图成为 Doctrine、Propel 或其他重型 ORM。
  4. 提供一个简单的方法来拆分结果集,而无需指定这些对象之间的关系。
  5. 与现有的 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。

功能

  1. 几乎可以将任何数据源扔给它——Flipper 都可以与之协同工作。这包括数组以及实现 Iterator 或 IteratorAggregate 接口的东西。如果它可以用 foreach() 使用,它就可以与 Flipper 一起使用。
  2. 将结果映射到一个对象——或者多个。Flipper 不关心。
  3. 当与 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给你提供了一个隧道。

  1. 抽象我们所有的数据库写入是好的——它促进了数据完整性。
  2. 抽象我们所有的读取可能是不好的。

需要更多信息?维基百科有更多细节。