Sql 使用Doctrine2管理多对多标签
我对标签的工作原理很感兴趣。到目前为止,我的想法是: 我有三个数据库表Sql 使用Doctrine2管理多对多标签,sql,doctrine-orm,symfony,Sql,Doctrine Orm,Symfony,我对标签的工作原理很感兴趣。到目前为止,我的想法是: 我有三个数据库表Bookmarkstags->has($tag)之前进行检查$this->tags->add($tag)。这只是为了建立关系。如果你说的是标签表,那么这个检查应该已经在控制器中做过了。但是重复检查会打破模型和控制器之间的界限。您将无法“重用”模型,因为缺少一些逻辑。如何防止向数据库中添加两次标记?定义title列unique不起作用,因为它会破坏重复标记上的脚本。在存储之前检查标记不是原子操作。请在调用$this->tags-
Bookmarks
标签
id | title |和Bookmarks|u标签(mxm,3NF)。我的第一个测试将只是一个单用户系统,所以我不必处理特定用户拥有的标签
存储书签:uri
(字符串)+tags
(字符串,例如Lorem Ipsum,Hello
应产生两个标记:Lorem Ipsum
和Hello
)
问题:我应该在哪里以及如何创建缺少的标记
并加载已知的标记
可以在模型中创建标记(请参见下面的Bookmark::setTags()。在模型中加载和链接似乎是不可能的,因为ORM在类中不可用(或者是否有用于获取ORM的静态资源?是否建议这样做?)
我可以加载现有标记并在控制器
中创建标记,但我认为标记应该是模型的工作
我将Symfony2与Doctrine2一起使用
书签类/表
* @ORM\Table()
* @ORM\Entity(repositoryClass="X\BookmarksBundle\Entity\BookmarkRepository")
*/
class Bookmark
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string $title
*
* @ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* @var string $uri
*
* @ORM\Column(name="uri", type="string", length=255)
*/
private $uri;
/**
* @var datetime $created_at
*
* @ORM\Column(name="created_at", type="datetime")
*/
private $created_at;
/**
* @var datetime $deleted_at
*
* @ORM\Column(name="deleted_at", type="datetime")
*/
private $deleted_at;
/** @ORM\ManyToMany(targetEntity="Tag", cascade={"persist", "remove"}) */
private $tags;
public function __construct()
{
$this->tags = new ArrayCollection();
}
public function getTags () {
if ($this->tags->isEmpty()) {
return "NO TAGS";
}
// TODO load tags from db
return "TODO: TAGS FOUND";
}
public function setTags ($tags) {
// TODO create and load/link existing tags
$tag = new Tag();
$tag->setTitle("test tag");
$this->tags->add($tag);
}
/* setters and getters for other private variables here */
* @ORM\Table()
* @ORM\Entity(repositoryClass="X\BookmarksBundle\Entity\TagRepository")
*/
class Tag
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string $title
*
* @ORM\Column(name="title", type="string", length=64)
*/
private $title;
/**
* @var datetime $created_at
*
* @ORM\Column(name="created_at", type="datetime")
*/
private $created_at;
/**
* @var datetime $deleted_at
*
* @ORM\Column(name="deleted_at", type="datetime", nullable=true)
*/
private $deleted_at;
public function __construct () {
$this->created_at = new \DateTime('now');
}
/* setters and getters for other private variables here */
标记类/表
* @ORM\Table()
* @ORM\Entity(repositoryClass="X\BookmarksBundle\Entity\BookmarkRepository")
*/
class Bookmark
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string $title
*
* @ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* @var string $uri
*
* @ORM\Column(name="uri", type="string", length=255)
*/
private $uri;
/**
* @var datetime $created_at
*
* @ORM\Column(name="created_at", type="datetime")
*/
private $created_at;
/**
* @var datetime $deleted_at
*
* @ORM\Column(name="deleted_at", type="datetime")
*/
private $deleted_at;
/** @ORM\ManyToMany(targetEntity="Tag", cascade={"persist", "remove"}) */
private $tags;
public function __construct()
{
$this->tags = new ArrayCollection();
}
public function getTags () {
if ($this->tags->isEmpty()) {
return "NO TAGS";
}
// TODO load tags from db
return "TODO: TAGS FOUND";
}
public function setTags ($tags) {
// TODO create and load/link existing tags
$tag = new Tag();
$tag->setTitle("test tag");
$this->tags->add($tag);
}
/* setters and getters for other private variables here */
* @ORM\Table()
* @ORM\Entity(repositoryClass="X\BookmarksBundle\Entity\TagRepository")
*/
class Tag
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string $title
*
* @ORM\Column(name="title", type="string", length=64)
*/
private $title;
/**
* @var datetime $created_at
*
* @ORM\Column(name="created_at", type="datetime")
*/
private $created_at;
/**
* @var datetime $deleted_at
*
* @ORM\Column(name="deleted_at", type="datetime", nullable=true)
*/
private $deleted_at;
public function __construct () {
$this->created_at = new \DateTime('now');
}
/* setters and getters for other private variables here */
从数据库中获取实体时,Doctrine2不提供POPO实体,而是提供一个“代理”。此代理能够从数据库加载缺少的元素。因此,您不必实现从数据库检索缺失数据的逻辑 顺便说一句,您也可以创建此方法:
public function addTag(Tag $tag)
{
$this->tags->add($tag);
}
从数据库中获取实体时,Doctrine2不提供POPO实体,而是提供一个“代理”。此代理能够从数据库加载缺少的元素。因此,您不必实现从数据库检索缺失数据的逻辑 顺便说一句,您也可以创建此方法:
public function addTag(Tag $tag)
{
$this->tags->add($tag);
}
如何防止向数据库中添加两次标记?定义title列unique不起作用,因为它会破坏重复标记上的脚本。在存储之前检查标记不是原子操作。请在调用
$this->tags->has($tag)
之前进行检查$this->tags->add($tag)
。这只是为了建立关系。如果你说的是标签表,那么这个检查应该已经在控制器中做过了。但是重复检查会打破模型和控制器之间的界限。您将无法“重用”模型,因为缺少一些逻辑。如何防止向数据库中添加两次标记?定义title列unique不起作用,因为它会破坏重复标记上的脚本。在存储之前检查标记不是原子操作。请在调用$this->tags->has($tag)
之前进行检查$this->tags->add($tag)
。这只是为了建立关系。如果你说的是标签表,那么这个检查应该已经在控制器中做过了。但是重复检查会打破模型和控制器之间的界限。您将无法“重用”模型,因为缺少一些逻辑。