【问题标题】:php: dividing a multitable select into several objects / object structurephp:将一个多表选择分成几个对象/对象结构
【发布时间】:2012-03-26 10:56:49
【问题描述】:

首先让我声明我们使用 php 和 postgre 数据库。在我们的项目中,由于 sql 查询过载,我们决定不使用任何 ORM,我们采取了相反的方式。

假设您从多个表中进行选择,假设加入了 id 列。例如:

  • 表:users(id, name), items(id, name, description), cmets(user_id, item_id, text, rating)

所以基本上你有一个用户表、一些项目表和一个与一个用户和一个项目相关的 cmets 表。

您创建两个对象 - 用户和项目代表他们的表格行。然后你想创建一个评论对象。在 ORM 中,它将包含对象 user 和 item 并且他们会用他们的查询加载自己,但这将是两个查询,你在想......嗯,但我可以用一个查询选择那个数据......但是如何?

想象一下你有这个选择:

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

(你也可以想象一个 WHERE 子句带有指定的 item id 或 user id 等)

那么你如何将这样一个选择的结果拆分到这个类结构中,假设你想要一个评论对象列表:

  • 用户
  • 项目
  • 评论(包含对用户和项目对象的引用)

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

感谢您的任何想法

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

【问题讨论】:

    标签: php oop select orm


    【解决方案1】:

    首先,您可能会从Data Mapper 模式中受益。一个简单的用例如下所示:

    $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 的实例是什么类。

    【讨论】:

    • 别担心,我不会在 select 语句中使用 * :) 我只是懒得写示例中的每一列或任何子集。谢谢你,这就是我所说的,甚至更多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-26
    • 2013-10-12
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多