如何在ZendDb(Zend Framework 2)中处理多对多关系


How to work with many to many relations in ZendDb (Zend Framework 2)

我有一个ZF2应用程序,它有用于posts的数据库表和具有多对多关系的散列标记。表格定义为:

CREATE TABLE `hash_tag` (
    `id` int(11) NOT NULL,
    `tag` varchar(255) NOT NULL
)
CREATE TABLE `post` (
    `id` int(11) NOT NULL,
    `text` varchar(255)NOT NULL,
    `addedOn` datetime NOT NULL
)
CREATE TABLE `post_hashtag` (
    `post_id` int(11) NOT NULL,
    `hashtag_id` int(11) NOT NULL
)

我还按照ZF2文档的用户指南中解释的模式创建了模型。HashTag模型如下:

namespace Application'Model;
use Application'Model'Post;
class HashTag
{
    public $id;
    public $tag;
    protected $posts = array();
    public function exchangeArray($data)
    {
        $this->id = empty($data['id']) ? null : $data['id'];
        $this->tag = empty($data['tag']) ? null : $data['tag'];
    }
    public function getPosts()
    {
        return $this->posts;
    }
    public function addPost(Post $post)
    {
        $this->posts[] = $post;
        return $this;
    }
}

虽然指南对如何处理基本数据库模型给出了很好的解释,但我希望做一些更复杂的事情。

基本上,当我检索哈希标签记录时,我还想检索它们相关的帖子,并以某种方式将它们存储在每个单独的HashTag对象中。执行普通的联接查询会为每个哈希标记及其附带的post生成一个新记录,这并没有真正的帮助。文档中也没有详细介绍如何做到这一点,我在谷歌上也找不到任何关于它的像样的例子。

我过去使用过条令2,通常会继续这样做。然而,我正在为一份新工作做准备,我的新雇主使用Zend''Db。我这样做基本上是为了练习在不使用Doctrine的情况下处理数据库操作。

遇到了同样的问题,我仍然不知道我的方法是否是一个好方法,但它有效。我为每个需要处理m-m关系的实体创建了一个"映射器"(Generic names ftw)。这里有一些例子:

class AddresseeMapper {
private $resultSet;
private $addresseeArray = array();
private $addreseeObjectsArray = array();
public function __construct($resultSet)
{
    $this->resultSet = $resultSet;
}
public function init()
{
    foreach($this->resultSet as $key => $result)
    {
        $addressee = array();
        if(!empty($this->addresseeArray[$result['AddresseeID']]))
        {
            $addressee = $this->addresseeArray[$result['AddresseeID']];
        }
        else
        {
            $addressee['id'] = $result['AddresseeID'];
            $addressee['documentID'] = $result['AddresseeDocumentID'];
            $addressee['communicationID'] = $result['AddresseeCommunicationID'];
            $addressee['addressID'] = (!empty($result['AddresseeAddressID'])) ? $result['AddresseeAddressID'] : null;
            $addressee['salutation'] = (!empty($result['AddresseeSalutation'])) ? $result['AddresseeSalutation'] : null;
            $addressee['tempEmail'] = (!empty($result['AddresseeTempEmail'])) ? $result['AddresseeTempEmail'] : null;
            if((!empty($result['ContactID'])) && $result['ContactID'])
            {
                $addressee['Contact'] = $this->setContact($this->resultSet);
            }
            if((!empty($result['MailingListID'])) && $result['MailingListID'])
            {
                $addressee['MailingList'] = $this->exchangeMailingList($result);
            }
        }
        $this->addresseeArray[$result['AddresseeID']] = $addressee;
    }
}
private function setContact($resultSet)
{
    $contactMapper = new ContactMapper($resultSet);
    $contactMapper->init();
    $contactMapper->serilizeObjects();
    return $contactMapper->getContact();
}
private function exchangeMailingList($result)
{
    $mailingList = new MailingList();
    $mailingList->exchangeArray($result);
    return $mailingList;
}
public function serilizeObjects()
{
    foreach($this->addresseeArray as $addresseeArray)
    {
        $addressee = new Addressee();
        $addressee = $this->loop($addresseeArray, $addressee);
        $this->addreseeObjectsArray[] = $addressee;
    }
}
private function loop($array, $object)
{
    foreach($array as $key => $value)
    {
        if(is_array($value) && is_object($object->$key))
        {
            $object->$key = $this->deepLoop($value, $object->$key);
        }
        elseif(is_array($object->$key))
        {
            foreach($value as $key2 => $value2)
            {
                array_push($object->$key, $value2);
            }
        }
        else
        {
            $object->$key = $value;
        }
    }
    return $object;
}
private function deepLoop($array, $object)
{
    foreach($array as $key => $value)
    {
        //var_dump($key);
        //var_dump($value);
        $object->$key = $value;
    }
    return $object;
}
public function getAddressees()
{
    return $this->addreseeObjectsArray;
}
public function getAddressee()
{
    foreach($this->addreseeObjectsArray as $addressee)
    {
        return $addressee;
    }
    return false;
}

}