2013-02-24 63 views
2

在我的PHP MVC应用程序中,我有三个主要实体:组织,雇员和角色。每个组织都有很多员工,每个员工都有一个角色。显示清单:集合与阵列

对于给定的组织,我想显示员工列表。对于每位员工,我将显示姓名,地址详细信息和角色名称。

现在,据我所知,最有效的方法是为我的服务层返回一个员工列表作为一个数组,其中每个元素是一个数组字段(而不是一个对象)。在映射器中,我将角色表加入到employee表中,因此正确的角色名称将位于初始结果集中,并且不需要再次查询数据库。

另一种方法是我的服务层返回一个Employee对象集合。然而,在这种情况下,每个Employee对象都需要查询数据库以找到它的角色的正确名称(假设角色被延迟加载)。这会非常低效,但不知何故似乎更“面向对象”。

每当员工实例化时,我都可以考虑加载角色名称作为员工的一个属性,但是我仍然需要保留对唯一角色ID的引用,因此我立即有同步注意事项。

什么是解决这个问题的典型方法?我相信它已经解决了数百万次!

谢谢!

+1

体面的ORM应该能够获得有关员工名单及其角色的信息,并返回一个Employee对象列表,每个Employee都有一个Role类型的字段,其中包含有关其角色的信息。 – 2013-02-24 09:09:59

+1

没有什么能够阻止你使用第一个替代方法而不是数组。 Voilá,高效*和*面向对象。 – 2013-02-24 09:30:40

+0

你好,我该怎么办?同时生成一个Employee集合和一个相关的Role集合? – 2013-02-24 10:43:11

回答

1

确实,这个东西是非常标准的。但我仍然与它斗争。

我首先想到的是要建立这样的:

class Employee 
{ 
    protected $name; //etc 

    /** 
    * @var Organization 
    */ 
    protected $organization; 

    /** 
    * @var Role 
    */ 
    protected $role; 

    // And then getters/setters for Role and Organization 
} 

然后一个EmployeeMapper类似:

class EmployeeMapper 
{ 
    /** 
    * @Var DB 
    */ 
    protectd $db; 

    public function __construct(DB $db) 
    { 
     $this->db = $db 
    } 

    public function getEmployeesByOrganization($orgId) 
    { 
     // query here that joins employees, roles, and organizations 
    } 
} 

这令我干净,代表你所描述的结构。

但问题是,当EmployeeMapper必须构造Employee对象 时,他需要知道连接查询结果中的角色字段和组织字段如何映射到角色和组织字段对象。对我而言,这些知识应该严格限制在RoleMapper和OrganizationMapper中。因此,也许这些映射器需要使这个映射功能可用作为公共方法,并且我们需要有一种方法将RoleMapper和OrganizationMapper实例注入到EmployeeMapper中以供使用。有关基于ZF的示例,请参阅Surviving The Deep End

此外,似乎有时候 - 例如您提供的“员工视图列表” - 您想要获得有关角色和组织实体附加信息。在这种情况下,加入和构建对象图的开销是合理的(当然比为角色和组织进行单独的查询循环更好)。但在其他情况下,您确实只需要为单个员工提供一些简单的员工信息,例如他的姓名或电话号码。在后一种情况下,为什么会产生加入和构建完整对象图的开销?

这些问题有架构解决方案,通常使用代理对象(代表角色和组织对象,并在需要时延迟加载它们)和自定义存储库对象(您要强制连接的位置)。

但我觉得自己构建这一切是一种痛苦。最后,我发现一个像Doctrine这样的ORM已经完全掌握了它,并为我提供了上述功能(代理,自定义存储库等)。

+0

真棒大卫,非常感谢。 – 2013-02-25 04:13:11