我正在考虑将doctrine用于我正在处理的应用程序 - 但在阅读完文档之后,我无法概念化如何表示我们在实体方面的数据库结构。
我有很多表都有合作伙伴表,其中包含翻译数据,如下所示....
我希望有一个实体(导航元素)可以访问“标签”字段,具体取决于我在应用程序中设置的语言。 Doctrine文档中的以下内容似乎表明您需要定义一个用于持久化实体的(单个)表
http://www.doctrine-project.org/docs/orm/2.0/en/reference/basic-mapping.html 默认情况下,实体将是 坚持到一张桌子一样 将name命名为类名。为了 改变这一点,你可以使用@Table 注释如下:
或者我是否需要定义两个实体并将它们链接起来(或允许转换表继承元素表)。
我将使用什么策略来始终将一个language_id子句插入Join(以确保我为当前设置的语言提取正确的标签)。这是我在实体本身或其他地方定义的东西吗?
答案 0 :(得分:2)
这似乎适合One-To-Many Bidirectional association。这是从该页面转换为您的情况的场景:
/** @Entity */
class NavigationElement
{
// ...
/**
* @OneToMany(targetEntity="NavigationElementTranslation", mappedBy="navigationElement")
*/
private $translations;
// ...
public function __construct() {
$this->translations = new \Doctrine\Common\Collections\ArrayCollection();
}
}
/** @Entity */
class NavigationElementTranslation
{
// ...
/**
* @ManyToOne(targetEntity="NavigationElement", inversedBy="translations")
* @JoinColumn(name="navigation_element_id", referencedColumnName="id")
*/
private $navigationElement;
// ...
}
您可以向NavigationElement实体添加getLabel($languageId)
方法,搜索翻译以获取正确的标签:
public function getLabel($languageId) {
foreach($this->translations as $trans) {
if($trans->languageId == $languageId)
return $trans->label;
}
throw new InvalidArgumentException();
}
您可以使用以下DQL来确保只将所需的翻译加载到$translations
属性中:
$query = $em->createQuery(
"SELECT ne, net
FROM Entity\NavigationElement ne
JOIN ne.translations net WITH net.languageId = :langId"
);
$query->setParameter('langId', $languageId);
$navigationElements = $query->execute();
这种情况听起来像是你想要积极缓存的情况。确保您也查看Doctrine 2's caching机制。
此外,如果您发现翻译的连接表开始变得无法管理,则可以使用gettext在PHP中合理地处理国际化。
答案 1 :(得分:0)
我还会指示任何必须解决同一问题的人来看看下面的学说扩展。
http://www.gediminasm.org/article/translatable-behavior-extension-for-doctrine-2