我有一个Message类,并希望扩展一个Ticket类,它将成为某种支持票类,因此它们可能有另一个名为' status'的字段。
父类:
@Override
public int getCount() {
if(messagesItems.size() <= maxRowsShow){
return messagesItems.size();
}else{
offset = messagesItems.size() - maxRowsShow;
return maxRowsShow;
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
position = position + offset;
...}
正如您所看到的,它与字段接收者和发件人上的User类有多对一的关系。这个类生成得很好。
我想从Message类扩展的子类:
namespace PrivateMessageBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use MedApp\CrudBundle\Entity\User;
/**
* Message
*
* @ORM\Table()
* @ORM\Entity
*/
class Message
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="title", type="string", length=50)
*/
protected $title;
/**
* @ORM\ManyToOne(targetEntity="MedApp\CrudBundle\Entity\User")
* @ORM\JoinColumn(referencedColumnName="id")
*/
protected $receiver;
/**
* @ORM\ManyToOne(targetEntity="MedApp\CrudBundle\Entity\User")
* @ORM\JoinColumn(referencedColumnName="id")
*/
protected $sender;
/**
* @var string
*
* @ORM\Column(name="content", type="string", length=2000)
*/
protected $content;
/**
* @var \DateTime
*
* @ORM\Column(name="date", type="datetime")
*/
protected $date;
/**
* @var boolean
*
* @ORM\Column(name="is_spam", type="boolean")
*/
protected $is_spam=false;
/**
* @var \DateTime
*
* @ORM\Column(name="seen_at", type="datetime",nullable=true)
*/
protected $seen_at=null;
//autogenerated functions here
}
这门课有一些问题。它是空的,但我使用doctrine生成了字段和函数:generate:entities SupportMessageBundle。
首先,它生成字段private,并在schema:update I get
namespace SupportMessageBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use PrivateMessageBundle\Entity\Message;
/**
* Ticket
*
* @ORM\Table()
* @ORM\Entity
*/
class Ticket extends Message
{
/**
* @var integer
*/
private $id;
/**
* @var string
*/
private $title;
/**
* @var string
*/
private $content;
/**
* @var \DateTime
*/
private $date;
/**
* @var boolean
*/
private $is_spam;
/**
* @var \DateTime
*/
private $seen_at;
/**
* @var \MedApp\CrudBundle\Entity\User
*/
private $receiver;
/**
* @var \MedApp\CrudBundle\Entity\User
*/
private $sender;
//auto generated functions
}
所以我将所有字段更改为protected并在数据库中生成我的表,但没有发送方和接收方ID。任何想法我怎样才能做到呢?或者为什么我的领域首先是私人的?
请注意,我希望Ticket仍然有Message +的字段,我不希望我的部分邮件成为故障单。
答案 0 :(得分:1)
这样的事情会做到这一点。但您应该关注@StuBez评论并阅读https://doctrine-orm.readthedocs.org/en/latest/reference/inheritance-mapping.html
这是一个JOINED例子,在某些用例中具有性能影响。
<?php
namespace PrivateMessageBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"ticket" = "Ticket")
*/
class Message
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="title", type="string", length=50)
*/
protected $title;
// ...
}
/** @ORM\Entity */
class Ticket extends Message
{
// ... New fields don't repeat parent one
}
答案 1 :(得分:1)
它总是取决于您想要设计的内容。首先让我们说,发电机不适用于您的建议,所以我建议,在这种情况下不使用它。
我改变了一些事情:
正确的类定义,如果要使用继承映射:
<?php
namespace Acme\PrivateMessageBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\User;
/**
* Message
*
* @ORM\Table(name="message")
* @ORM\Entity()
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"message"="Message", "ticket" = "Acme\PrivateTicketBundle\Entity\Ticket"})
*
*/
class Message
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="title", type="string", length=50)
*/
protected $title;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
* @ORM\JoinColumn(referencedColumnName="id")
*/
protected $receiver;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
* @ORM\JoinColumn(referencedColumnName="id")
*/
protected $sender;
/**
* @var string
*
* @ORM\Column(name="content", type="string", length=2000)
*/
protected $content;
/**
* @var \DateTime
*
* @ORM\Column(name="date", type="datetime")
*/
protected $date;
/**
* @var boolean
*
* @ORM\Column(name="is_spam", type="boolean")
*/
protected $isSpam = false;
/**
* @var \DateTime
*
* @ORM\Column(name="seen_at", type="datetime",nullable=true)
*/
protected $seenAt = null;
// [...] skip constructor, getter, setter and other methods
}
Ticket类看起来像这样
<?php
namespace Acme\PrivateTicketBundle\Entity;
use Acme\PrivateMessageBundle\Entity\Message;
use Doctrine\ORM\Mapping as ORM;
/**
* Ticket extending Message
*
* @ORM\Table(name="ticket")
* @ORM\Entity()
*/
class Ticket extends Message
{
/**
* @var string
* @ORM\Column(name="status", type="string")
*/
protected $status;
/**
* Set status
*
* @param string $status
* @return Ticket
*/
public function setStatus($status)
{
$this->status = $status;
return $this;
}
/**
* Get status
*
* @return string
*/
public function getStatus()
{
return $this->status;
}
}
这将生成以下表格:
CREATE TABLE message (id INTEGER NOT NULL, receiver_id INTEGER DEFAULT NULL, sender_id INTEGER DEFAULT NULL, title VARCHAR(50) NOT NULL, content VARCHAR(2000) NOT NULL, date DATETIME NOT NULL, is_spam BOOLEAN NOT NULL, seen_at DATETIME DEFAULT NULL, discr VARCHAR(255) NOT NULL, PRIMARY KEY(id));
CREATE TABLE ticket (id INTEGER NOT NULL, status VARCHAR(255) NOT NULL, PRIMARY KEY(id));
一个用于消息实体,其中包含为消息定义的所有字段,以及一个带有和id的表的表(它将始终与消息表中的相应id相同)和额外的字段状态。
这也可以使用特征: 消息实体:
<?php
namespace Acme\PrivateMessageBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Message
*
* @ORM\Table(name="message")
* @ORM\Entity()
*/
class Message
{
// Use the MessageTraid
use MessageTrait;
}
(你必须保留use Doctrine\ORM\Mapping as ORM;
!)
票务实体:
<?php
namespace Acme\PrivateTicketBundle\Entity;
use Acme\PrivateMessageBundle\Entity\MessageTrait;
use Doctrine\ORM\Mapping as ORM;
/**
* Ticket extending Message
*
* @ORM\Table(name="ticket")
* @ORM\Entity()
*/
class Ticket
{
// Use the MessageTraid
use MessageTrait;
/**
* @var string
* @ORM\Column(name="status", type="string")
*/
protected $status;
/**
* Set status
*
* @param string $status
* @return Ticket
*/
public function setStatus($status)
{
$this->status = $status;
return $this;
}
/**
* Get status
*
* @return string
*/
public function getStatus()
{
return $this->status;
}
}
这是特质:
<?php
namespace Acme\PrivateMessageBundle\Entity;
trait MessageTrait
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="title", type="string", length=50)
*/
protected $title;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
* @ORM\JoinColumn(referencedColumnName="id")
*/
protected $receiver;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\User")
* @ORM\JoinColumn(referencedColumnName="id")
*/
protected $sender;
/**
* @var string
*
* @ORM\Column(name="content", type="string", length=2000)
*/
protected $content;
/**
* @var \DateTime
*
* @ORM\Column(name="date", type="datetime")
*/
protected $date;
/**
* @var boolean
*
* @ORM\Column(name="is_spam", type="boolean")
*/
protected $isSpam = false;
/**
* @var \DateTime
*
* @ORM\Column(name="seen_at", type="datetime",nullable=true)
*/
protected $seenAt = null;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* @param string $title
* @return Message
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set content
*
* @param string $content
* @return Message
*/
public function setContent($content)
{
$this->content = $content;
return $this;
}
/**
* Get content
*
* @return string
*/
public function getContent()
{
return $this->content;
}
/**
* Set date
*
* @param \DateTime $date
* @return Message
*/
public function setDate($date)
{
$this->date = $date;
return $this;
}
/**
* Get date
*
* @return \DateTime
*/
public function getDate()
{
return $this->date;
}
/**
* Set isSpam
*
* @param boolean $isSpam
* @return Message
*/
public function setIsSpam($isSpam)
{
$this->isSpam = $isSpam;
return $this;
}
/**
* Get isSpam
*
* @return boolean
*/
public function getIsSpam()
{
return $this->isSpam;
}
/**
* Set seenAt
*
* @param \DateTime $seenAt
* @return Message
*/
public function setSeenAt($seenAt)
{
$this->seenAt = $seenAt;
return $this;
}
/**
* Get seenAt
*
* @return \DateTime
*/
public function getSeenAt()
{
return $this->seenAt;
}
/**
* Set receiver
*
* @param \AppBundle\Entity\User $receiver
* @return Message
*/
public function setReceiver(\AppBundle\Entity\User $receiver = null)
{
$this->receiver = $receiver;
return $this;
}
/**
* Get receiver
*
* @return \AppBundle\Entity\User
*/
public function getReceiver()
{
return $this->receiver;
}
/**
* Set sender
*
* @param \AppBundle\Entity\User $sender
* @return Message
*/
public function setSender(\AppBundle\Entity\User $sender = null)
{
$this->sender = $sender;
return $this;
}
/**
* Get sender
*
* @return \AppBundle\Entity\User
*/
public function getSender()
{
return $this->sender;
}
}
请注意,在特征中没有关于ORM的任何使用声明。
Doctrine将使用您班级中定义的ODM名称空间。
这将产生两个表:
CREATE TABLE message (id INTEGER NOT NULL, receiver_id INTEGER DEFAULT NULL, sender_id INTEGER DEFAULT NULL, title VARCHAR(50) NOT NULL, content VARCHAR(2000) NOT NULL, date DATETIME NOT NULL, is_spam BOOLEAN NOT NULL, seen_at DATETIME DEFAULT NULL, PRIMARY KEY(id));
CREATE TABLE ticket (id INTEGER NOT NULL, receiver_id INTEGER DEFAULT NULL, sender_id INTEGER DEFAULT NULL, status VARCHAR(255) NOT NULL, title VARCHAR(50) NOT NULL, content VARCHAR(2000) NOT NULL, date DATETIME NOT NULL, is_spam BOOLEAN NOT NULL, seen_at DATETIME DEFAULT NULL, PRIMARY KEY(id));
快乐编码
在此示例中,如果使用$em->getRepository('AcmePrivateMessageBundle:Message')->findAll();
搜索邮件,您还将获得Ticket实体,因为创建的查询如下所示:
SELECT
t0.id AS id2,
t0.title AS title3,
t0.content AS content4,
t0.date AS date5,
t0.is_spam AS is_spam6,
t0.seen_at AS seen_at7,
t0.receiver_id AS receiver_id8,
t0.sender_id AS sender_id9,
t0.discr,
t1.status AS status10
FROM
message t0
LEFT JOIN ticket t1 ON t0.id = t1.id
(注意LEFT JOIN
)
但是如果你用$entities = $em->getRepository('AcmePrivateTicketBundle:Ticket')->findAll();
搜索门票,你会发现Ticket只是因为生成的sql看起来有点不同:
SELECT
t1.id AS id2,
t1.title AS title3,
t1.content AS content4,
t1.date AS date5,
t1.is_spam AS is_spam6,
t1.seen_at AS seen_at7,
t0.status AS status8,
t1.receiver_id AS receiver_id9,
t1.sender_id AS sender_id10,
t1.discr
FROM
ticket t0
INNER JOIN message t1 ON t0.id = t1.id
要仅获取消息,您必须使用查询构建器:
$query = $em->createQuery("SELECT message FROM Acme\PrivateMessageBundle\Entity\Message message WHERE message INSTANCE OF Acme\PrivateMessageBundle\Entity\Message");
$entities = $query->getResult();
这将生成此查询:
SELECT
m0_.id AS id0,
m0_.title AS title1,
m0_.content AS content2,
m0_.date AS date3,
m0_.is_spam AS is_spam4,
m0_.seen_at AS seen_at5,
t1_.status AS status6,
m0_.discr AS discr7,
m0_.receiver_id AS receiver_id8,
m0_.sender_id AS sender_id9
FROM
message m0_
LEFT JOIN ticket t1_ ON m0_.id = t1_.id
WHERE
m0_.discr IN ('message')