我使用Symfony 3,Doctrine ORM和SonataAdminBundle。如何在数据库级别实现接口(Symfony3,Doctrine ORM,SonataAdminBundle)?
有一个任务,可以通过在代码级别上实现一些接口来解决,但我不知道如何正确地将这种结构的数据存储在数据库中,并在管理面板中编辑这些数据。
假设有这样的初始条件。
有一个“电影”原则实体。数据库中的表film
。
/**
* @ORM\Table(name="film")
* @ORM\Entity
*/
class Film
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
...
}
有一个“用户”原则实体。数据库中的表user
。
/**
* @ORM\Table(name="user")
* @ORM\Entity
*/
class User
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
...
}
有一个“电影”原则实体。数据库中的表cinema
。
/**
* @ORM\Table(name="cinema")
* @ORM\Entity
*/
class Cinema
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var Town
*
* @ORM\ManyToOne(targetEntity="Town")
* @ORM\JoinColumn(name="town_id", referencedColumnName="id", nullable=false)
*/
private $town;
/**
* @return Town
*/
public function getTown()
{
return $this->town;
}
...
}
正如我们所看到的,“电影院”有一个“镇”字段,它决定了电影院位于哪个城镇。所以还有一个“城镇”主义实体。数据库中的表town
。
/**
* @ORM\Table(name="town")
* @ORM\Entity
*/
class Town
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
...
}
下,有必要从这些数据中创建一个“视图日志”,即数据存储有关的实体“查看”每个视图(无关MVC的视图)。数据库中的表view
。
/**
* @ORM\Table(name="view")
* @ORM\Entity
*/
class View
{
/**
* @var User
*
* @ORM\ManyToOne(targetEntity="User")
* @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false)
*/
private $user;
/**
* @var Film
*
* @ORM\ManyToOne(targetEntity="Film")
* @ORM\JoinColumn(name="film_id", referencedColumnName="id", nullable=false)
*/
private $film;
/**
* @var Cinema
*
* @ORM\ManyToOne(targetEntity="Cinema")
* @ORM\JoinColumn(name="cinema_id", referencedColumnName="id", nullable=false)
*/
private $cinema;
/**
* @return Cinema
*/
public function getCinema()
{
return $this->cinema;
}
...
}
一个相当简单的方案。
假设在我们的业务逻辑中,非常重要的是用户在哪个城镇观看了电影。要找到一个小镇,我们可以这样做:$ view-> getCinema() - > getTown(),并获得需要的“Town”对象。
但突然发现用户不仅可以在电影院观看电影,还可以在电视上看到: - - 通过电脑。
在代码级别,解决方案看起来非常简单:声明具有getTown()方法并在“Cinema”,“TV”,“Computer”类中实现此接口的“ViewPlaceInterface”。
interface ViewPlaceInterface
{
/**
* @return Town
*/
public function getTown();
}
class View
{
...
/**
* @var ViewPlaceInterface
*/
private $viewPlace;
/**
* @return ViewPlaceInterface
*/
public function getViewPlace()
{
return $this->viewPlace;
}
...
}
class Cinema implements ViewPlaceInterface
{
/**
* @return Town
*/
public function getTown()
{
...
}
}
class TV implements ViewPlaceInterface
{
/**
* @return Town
*/
public function getTown()
{
...
}
}
class Computer implements ViewPlaceInterface
{
/**
* @return Town
*/
public function getTown()
{
...
}
}
这使我们可以调用$视图 - > getViewPlace() - > getTown(),并获得了 “镇” 的对象。
我的问题:如何在Symfony 3,Doctrine ORM,SonataAdminBundle中实现?应该创建什么表和实体?应如何配置原则ORM?如何配置sonata-admin?
谢谢。