原则2,查询内部实体 [英] Doctrine 2, query inside entities

查看:91
本文介绍了原则2,查询内部实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在实体中执行查询?

 命名空间Entities\Members; 

/ **
* @Entity(repositoryClass =\Entities\Member\MembersRepository)
* @Table(name =Members)
* @HasLifecycleCallbacks
* /
类成员扩展\Entities\AbstractEntity
{
/ **
* @Id @Column(name =id ,type =bigint,length = 15)
* @GeneratedValue(strategy =AUTO)
* /
protected $ id;

/ **
* @Column(name =userid,type =bigint,length = 26,nullable = true)
* /
protected $用户ID;

/ **
* @Column(name =fname,type =string,length = 255,nullable = true)
* /
protected $ FNAME;

/ **
* @OneToMany(targetEntity =\Entities\Users\Wall,mappedBy =entry,cascade = {persist})
* /
protected $ commententries;

public function __construct()
{
$ this-> commententries = new \Doctrine\Common\Collections\ArrayCollection();
}
}

示例我想在此实体内部有一个函数调用: filter()
,我想要能够过滤 commententries 集合。它应该返回一个特定条件的集合,例如 id = 1 。基本上它应该是过滤从连接查询中收到的数据。



所以这样的东西:

  $ this-> commententries-> findBy(array('id'=> 1)); 

但显然这不起作用。

解决方案

一般来说,你不应该这样做。



实体根据经验,不应该知道实体管理者(直接或通过一些中间对象)。



这样做的原因主要是可测试性,但根据我的经验,它有助于使事情以其他方式进行组织。 >

我会通过设计一个处理查找的服务类来处理它。您的控制器(或其他)将驱动它:

 <?php 
//创建一个新服务,注入实体管理员。如果你以后想要
//开始缓存一些东西,你也可以注入缓存驱动程序。
$ member = $ em-> find('Member',$ member_id); //获取会员,一些如何。
$ svc = new MemberService($ em);

$ favoriteCommentaries = $ svc-> getFavoriteCommentaries($ member);

正如我在评论中暗示的,如果您稍后决定要添加缓存(通过memcached,例如)为避免频繁查找,您可以在附近或此服务类中的某个地方执行此操作。这样可以让您的实体变得简单易用,易于测试。由于您在建设时将实体管理员注入到服务中,您可以根据需要嘲笑。



getFavoriteCommentaries()可以使用各种实现。一个琐碎的人将会将其代理给Member :: getFavoriteCommentaries(),这实际上将加载所有内容,然后过滤掉最喜爱的。这可能不会特别好,所以你可以通过使用EM来获取所需的数据来改善它。


How do I perform queries in an entity?

namespace Entities\Members;

/**
 * @Entity(repositoryClass="\Entities\Member\MembersRepository")
 * @Table(name="Members")
 * @HasLifecycleCallbacks
 */
class Members extends \Entities\AbstractEntity
{
    /**
     * @Id @Column(name="id", type="bigint",length=15)
     * @GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /** 
     * @Column(name="userid", type="bigint", length=26, nullable=true) 
     */
    protected $userid;

    /** 
     * @Column(name="fname", type="string", length=255,nullable=true) 
     */
    protected $fname;

    /**
     *  @OneToMany(targetEntity="\Entities\Users\Wall", mappedBy="entry", cascade={"persist"}) 
     */
    protected $commententries;

    public function __construct()
    {
        $this->commententries = new \Doctrine\Common\Collections\ArrayCollection();
    }
}

Example I would like to have a function inside this entity called: filter() and I want to be able to filter the commententries collection. It should return a collection with a certain condition such id=1. Basically it should be filtering the data received from the join query.

So something like this:

$this->commententries->findBy(array('id' => 1));

But obviously this does not work.

解决方案

Generally speaking, you shouldn't do this.

Entities, as a rule of thumb, should not know about the entitymanager (directly, or via some intermediary object).

The reason for this is mostly testability, but in my experience, it helps keeps things organized in other ways.

I'd approach it by designing a service class that handles the lookups for you. Your controller (or whatever) would drive it like this:

<?php
// create a new service, injecting the entitymanager.  if you later wanted 
// to start caching some things, you might inject a cache driver as well.
$member = $em->find('Member',$member_id); //get a member, some how.
$svc = new MemberService($em);

$favoriteCommentaries = $svc->getFavoriteCommentaries($member);

As I hint in the comment, if you decide later that you want to add caching (via memcached, for instance) to avoid frequent lookups, you'd do that somewhere near or in this service class. This keeps your entities nice and simple, and easily testable. Since you inject your entitymanager into the service at construction-time, you can mock that as needed.

getFavoriteCommentaries() could use various implementations. A trivial one would be to proxy it to Member::getFavoriteCommentaries(), which would actually load everything, and then filter out the "favorite" ones. That probably won't scale particularly well, so you could improve it by using the EM to fetch just the data you need.

这篇关于原则2,查询内部实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆