douzhong1907 2011-10-28 20:45
浏览 66
已采纳

PHP ORM和优化的关系查询

I need a PHP ORM to work with relations well. Please consider code below in Zend:

$persons = new Persons();
$person = $persons->find(5)->current();
echo 'Name: '.$person->fullname;

$phones = $person->findDependentRowset('Phones');
foreach($phones as $phone)
    echo 'Phone: '.$phone->phonenumber; 

Or code below in xPDO:

$person = $xpdo->getObject('Persons', 5);
echo 'Name: '.$person->get('fullname');

$phones = $person->getMany('Phones');
foreach($phones as $phone)
    echo 'Phone: '.$phone->get('phonenumber');

in both scripts, ORMs executes two queries as below:

SELECT * FROM persons WHERE id=5;
SELECT * FROM phones WHERE person=5;

It means one query for main object and one query for each relation but what i need is using ONE query for main object and its relations! xPDO can do it as below:

$person = $xpdo->getObjectGraph('Persons', '{"Phones":{}}', 5);
echo 'Name: '.$person->get('fullname');

foreach($person->Phones as $phone)
    echo 'Phone: '.$phone->get('phonenumber');

which executes this query:

SELECT * FROM persons
LEFT JOIN phones ON phones.person=persons.id
WHERE persons.id=5

This is great but its not possible to set fields to get from tables! it means in this case xPDO use "SELECT * " so if i get an object and its 4 relations, i will get all fields of all these tables!

So i need an ORM to execute query below for example above:

SELECT persons.fullname , phones.phonenumber FROM persons
LEFT JOIN phones ON phones.person=persons.id
WHERE persons.id=5

Doctrine can do it via DQL but i think Doctrine is not good for personal projects. Is there any PHP ORM to do this?

Thanks AHHP

  • 写回答

3条回答 默认 最新

  • douhunbei0166 2013-05-18 23:30
    关注

    xPDO can do it. You just have to adjust your thinking and your request.

    Remember the objectGraph utilizes the class name of the object, where as the relationships in the graph are used in the graph and query.

     $criteria = $this->xpdo->newQuery('prefixClient');
                if (!empty($limit))
                    $criteria->limit($limit);
                $criteria->where(array('Child.planid' => $this->getPrimaryKey(),
                                       'Child.active' => true,
                                       'GrandChild.someAttribute' => true,
                                       'GreatGrandChild.someOtherAttribute' => true,
                                       'suspended' => false
                                 ));
    
                $out = $this->xpdo->getCollectionGraph('prefixClient', '{"Child":{"GrandChild":{"GreatGrandChild":{}}}}', $criteria);
    

    You set the WHERE on any aspect of the relation, including the current object as show in the suspended => false line.

    My book might help you a little in establishing your schema and relations. Objects should always be singular in nomenclature, whereas their relations can be plural (1:M) or singular (1:1).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥20 给自己本科IT专业毕业的妹m找个实习工作
  • ¥15 用友U8:向一个无法连接的网络尝试了一个套接字操作,如何解决?
  • ¥30 我的代码按理说完成了模型的搭建、训练、验证测试等工作(标签-网络|关键词-变化检测)
  • ¥50 mac mini外接显示器 画质字体模糊
  • ¥15 TLS1.2协议通信解密
  • ¥40 图书信息管理系统程序编写
  • ¥20 Qcustomplot缩小曲线形状问题
  • ¥15 企业资源规划ERP沙盘模拟
  • ¥15 树莓派控制机械臂传输命令报错,显示摄像头不存在
  • ¥15 前端echarts坐标轴问题