Zend DB表和模型一对一

时间:2012-11-07 18:27:11

标签: zend-framework model zend-db-table

我用外键表示用户模型的类是图片的id。

class Model_User extends Model_AbstractEntity
{
    protected $u_id;
    protected $u_email;
    protected $u_firstname;
    protected $u_lastname;
    protected $u_password;
    protected $u_salt;
    protected $u_created_at;
    protected $u_updated_at;
    protected $u_fb;
    protected $u_status;
    protected $u_r_id;
    protected $u_p_id;
}

Class with负责图片模型的样子如下:

class Model_Picture extends Model_AbstractEntity
{
    protected $p_id;
    protected $p_created_at;
    protected $p_updated_at;
    protected $p_caption;
    protected $p_name;
    protected $p_basePath;
    protected $p_available;
    protected $p_u_id;
}

这只是从数据库获取数据的模型部分。 Foreing键是u_p_id,键入的是p_id 我的问题是,当通过Zend db table执行select()时,它使用外键返回数据,但是如何知道返回数据的哪一部分是图片部分来设置正确的图片模型....如何以正确的方式执行不为用户做2个查询,为图片创建2个关联对象。 我现在正在谈论关于一个人的关系,但也许会是一对一......

1 个答案:

答案 0 :(得分:1)

通常,您的实体模型将不存在,它们将与某种类型的Data Mapper模型一起存在。 Mapper通常负责从任何来源收集数据,然后构建实体模型。

例如,我有一个有专辑实体的音乐集:

<?php
class Music_Model_Album extends Model_Entity_Abstract implements Interface_Album
{
    //id is supplied by Entity_Abstract
    protected $name;
    protected $art;
    protected $year;
    protected $artist; //alias of artist_id in Database Table, foreign key
    protected $artistMapper = null;

    /**
     * Constructor, copied from Entity_Abstract
     */
    //constructor is called in mapper to instantiate this model
    public function __construct(array $options = null)
    {         
        if (is_array($options)) {
            $this->setOptions($options);
        }
    }

  /**
   * Truncated for brevity.
   * Doc blocks and normal getters and setters removed
   */


    public function getArtist() {
        //if $this->artist is set return
        if (!is_null($this->artist) && $this->artist instanceof Music_Model_Artist) {
            return $this->artist;
        } else {
            //set artist mapper if needed
            if (!$this->artistMapper) {
                $this->artistMapper = new Music_Model_Mapper_Artist();
            }
            //query the mapper for the artist table and get the artist entity model
            return $this->artistMapper->findById($this->getReferenceId('artist'));
        }
    }
    //set the artist id in the identity map
    public function setArtist($artist) {
        //artist id is sent to identity map. Can be called later if needed - lazy load
        $this->setReferenceId('artist', $artist);
        return $this;
    }


    //each album will have multiple tracks, this method allows retrieval as required.
    public function getTracks() {
        //query mapper for music track table to get tracks from this album
        $mapper = new Music_Model_Mapper_Track();
        $tracks = $mapper->findByColumn('album_id', $this->id, 'track ASC');

        return $tracks;
    }
}

在映射器中,我将构建实体模型,如:

 //excerpt from Model_Mapper_Album
 //createEntity() is declared abstract in Model_Mapper_Abstract
 public function createEntity($row)
    {
        $data = array(
            'id'     => $row->id,
            'name'   => $row->name,
            'art'    => $row->art,
            'year'   => $row->year,
            'artist' => $row->artist_id,//
        );

        return new Music_Model_Album($data);
    }

在mapper方法中使用此方法,可能如下所示:

 //this is actually from Model_Mapper_Abstract, b ut give the correct idea and will work in any of my mappers.
 //this returns one and only one entity
 public function findById($id)
    {
        //if entity id exists in the identity map
        if ($this->getMap($id)) {
            return $this->getMap($id);
        }
        //create select object
        $select = $this->getGateway()->select();
        $select->where('id = ?', $id);
        //fetch the data
        $row = $this->getGateway()->fetchRow($select);
        //create the entity object
        $entity = $this->createEntity($row);
        //put it in the map, just in case we need it again
        $this->setMap($row->id, $entity);
        // return the entity
        return $entity;
    }

我见过以不同方式构建的实体和映射器,找到你喜欢的方法并享受乐趣。

许多代码已被排除在此演示之外,因为它并不真正适用于该问题。如果您需要查看完整代码,请参阅GitHub.