php – 在Doctrine 2中使用类表继承时:如何编写将从子类返回结
对类表继承层次结构执行本机SQL查询是
mentioned in the examples in the docs,但我将在此处生成相关示例:
<?php use DoctrineORMQueryResultSetMapping; // Equivalent DQL query: "select u from User u where u.name=?1" // User is a mapped base class for other classes. User owns no associations. $rsm = new ResultSetMapping; $rsm->addEntityResult('User','u'); $rsm->addFieldResult('u','id','id'); $rsm->addFieldResult('u','name','name'); $rsm->addMetaResult('u','discr','discr'); // discriminator column $rsm->setDiscriminatorColumn('u','discr'); $query = $this->_em->createNativeQuery('SELECT id,name,discr FROM users WHERE name = ?',$rsm); $query->setParameter(1,'romanb'); $users = $query->getResult(); 从示例:
上述查询的问题是,如果您希望从子类返回上述示例中不返回它们的字段,它将从父类User返回字段.我们如何做到这一点? 在我继续前进之前,我花时间创建了一些示例类(一个是父项,另一个是子项),这应该适用于上面的示例查询.让我为你提供: /** * @ORMTable(name="users",* @ORMEntity * @ORMInheritanceType("JOINED") * @ORMDiscriminatorColumn(name="discr",type="string") * @ORMDiscriminatorMap({ * "regular_user" = "RegularUser",* "administrator" = "Administrator",* }) */ class User { /** * @ORMId * @ORMGeneratedValue(strategy="AUTO") */ protected $id; /** * @ORMColumn(name="name",type="string") */ protected $name; } 和: /** * @ORMTable(name="regular_users",* @ORMEntity */ class RegularUser extends User { /** * @ORMColumn(name="phone_number",type="string") */ protected $phoneNumber; } 所以我们有一个父类User,它有两个子类RegularUser和Administrator(注意:我只提供了一个子类RegularUser,但我确实提供了子类Administrator的鉴别器映射). 考虑一下:我们不想使用名为’romanb’的用户查询数据库(如上图所示),而是使用像Solr这样的全文搜索引擎来索引数据库.我们查询Solr for romanb,它返回一个用户id的数组,用户名为romanb,按相关性排序.使用这些有序ID,我们想查询数据库并返回常规用户列表,完全水合(即包括他们的电话号码),并按照与Solr返回的id相同的顺序排序.我们应该怎么做? Doctrine不支持自定义排序,因为它不受所有SQL引擎的支持. MySQL支持它,它恰好是我们正在使用的数据库. 请考虑以下Native SQL Query: $rsm = new ResultSetMapping; $rsm->addEntityResult('User','discr'); $rsm->setDiscriminatorColumn('u','discr'); $rsm->addFieldResult('u','phone_number','phoneNumber'); // How do we map this result? // Returned by Solr $userIds = array(22,3,88,109,12); $sql = <<<SQL SELECT u.id,u.name,u.discr,r.phone_number FROM users u INNER JOIN regular_users r ON users.id = regular_users.id WHERE u.id IN (?) ORDER BY FIELD(u.id,?); # Custom SQL logic that will return an ordered set SQL; $query = $this->_em->createNativeQuery($sql,$userIds); $query->setParameter(2,$userIds); $users = $query->getResult(); 虽然SQL很好,但上面的查询将失败并出现错误.如果我们注释掉$rsm-> addFieldResult(‘u’,’phone_number’,’phoneNumber’)它会工作,并且会在结果中返回一个RegularUser对象(因为所有id都属于普通用户,我们定义了discriminator列在结果集映射中)但这些RegularUser对象都不包含电话号码. 反正有没有做一个返回完全水合的RegularUser对象的查询? 谢谢阅读. 解决方法
有时候在stackoverflow上写出问题的好处是它可以帮助你更好地思考这个问题,这可以帮助你找到解决方案.
这是上面的一个有效的Native SQL查询: <?php $rsm = new ResultSetMapping; $rsm->addEntityResult('RegularUser','r'); $rsm->addFieldResult('r','id'); $rsm->addFieldResult('r','name'); $rsm->addFieldResult('r','phoneNumber'); $userIds = array(22,12); $sql = <<<SQL SELECT r.id,r.phone_number FROM regular_users r INNER JOIN users u ON r.id = u.id WHERE u.id IN (?) ORDER BY FIELD(u.id,$rsm); $query = $this->_em->createNativeQuery($sql,$userIds); $users = $query->getResult(); 基本上没有必要涉及鉴别器映射,假设您知道要查询的ID是ConstantUser类. 我希望这有助于其他人(我知道边缘情况). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |