php:将多任务选择划分为多个对象/对象结构


php: dividing a multitable select into several objects / object structure

首先让我声明我们使用php和postgre数据库。在我们的项目中,我们决定不使用任何ORM,因为它的sql查询过载,我们正在采取oposite的方式。

假设您从几个表中选择了一个,比方说在id列上联接。例如:

  • 表:用户(id,名称)、项目(id,姓名,描述)、评论(user_id,item_id,text,rating)

所以基本上你有一个用户表,一个项目表和一个评论表,它们与一个用户和一个项目有关。

您创建了两个对象——用户和表示其表行的项。然后您想要创建一个注释对象。在ORM中,它将包含对象user和item,它们将用查询加载自己,但这将是两个查询,您正在思考。。。嗯,但我可以用一个查询来选择数据。。。但是怎么做呢?

想象一下,你有这样的选择:

  • SELECT * FROM comments JOIN users ON comments.user_id = users.id JOIN items ON comments.item_id = items.id

(您还可以想象一个带有指定项目id或用户id等的WHERE子句。)

那么,你将如何将这样一个选择的结果划分为这个类结构,比如说你想要一个注释对象列表:

  • 用户
  • 项目
  • 注释(包含对用户和项目对象的引用)

到目前为止,我们的理论解决方案是用固定前缀为列的名称加前缀:),然后将结果传播到对象结构中,每个对象从select中获取所需内容。还有其他解决方案吗?让我们说更复杂?

谢谢你的任何想法

PS:很明显,我用了一个非常简单的例子,但试着想象问题要大得多,结构也要复杂得多。

首先,您可能会从查看数据映射器模式中受益。一个简单的用例如下:

$user = new User;
$mapper = new UserMapper( $db );
$user->setName('foobar');
$mapper->fetch( $user );
if ( $user->isBanned() )
{
    throw new Exception('get out !');
}
$user->setLastActive( time() );
$mapper->store( $user );

至于带有数据的单个查询:这不是重要的部分。您只需根据需要ALIAS(哦……我希望您没有使用*来选择行)。重要的一点是根据所选数据创建对象图。那是你使用建筑商/工厂的地方。

//the rest of PDO-related code 
$data = $statement->fecth(PDO::FETCH_ASSOC);
$comment = $commentFactory->build($data);

其中$commentFactoryCommentFactory:的实例

class CommentFactory
{
    public function build( $params )
    {
        $author = new User;
        $subject = new Item;
        $comment = new Comment( $author, $subject );
        $author->setId( $params['user_id']);
        $author->setName( $params['user_name']);
        $subject->setId( $param['item_id']);
        $comment->setContent( $param['content']);
        return $comment;
    }
}

此外,通过这样的设置,您可以很容易地更改$comment的生成方式,只需更改$commentFactory是其实例的类即可。