假设我有一个视图表,并且我想将数据从它传递到一个实体中。 我能否(以及如何)创建实体类来完成此操作(无需保存操作)? 我只想显示它们。
假设你已经有了一个视图表,你可以通过创建一个新的实体类来获取该视图表中的数据。实体类不需要任何保存操作,只需用属性来映射视图表的列即可。在显示数据时,您可以使用该实体类并访问其属性来获取所需的数据。假设我有一个视图表,并且我想将数据从它传递到一个实体中。 我能否(以及如何)创建实体类来完成此操作(无需保存操作)? 我只想显示它们。
假设你已经有了一个视图表,你可以通过创建一个新的实体类来获取该视图表中的数据。实体类不需要任何保存操作,只需用属性来映射视图表的列即可。在显示数据时,您可以使用该实体类并访问其属性来获取所需的数据。接受的答案是正确的,但我想提供一些额外的建议,供您考虑:
将您的实体标记为只读。
使构造函数私有化,这样只有Doctrine才能创建实例。
/**
* @ORM\Entity(readOnly=true)
* @ORM\Table(name="your_view_table")
*/
class YourEntity {
private function __construct() {}
}
在查询视图方面并没有什么特别的 — 它只是一个虚拟表。按照以下方式设置实体的表格,然后享受它:
/**
* @ORM\Entity
* @ORM\Table(name="your_view_table")
*/
class YourEntity {
// ...
}
schema:update
,它会失败.../**
* @ORM\Entity(readOnly=true)
* @ORM\Table(name="your_view_table")
*/
class YourEntity {
private function __construct() {}
}
src/Acme/CoreBundle/Command/DoctrineUpdateCommand.php:
<?php
namespace Acme\CoreBundle\Command;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\Tools\SchemaTool;
class DoctrineUpdateCommand extends \Doctrine\Bundle\DoctrineBundle\Command\Proxy\UpdateSchemaDoctrineCommand {
protected $ignoredEntities = array(
'Acme\CoreBundle\Entity\EntityToIgnore'
);
protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas) {
/** @var $metadata \Doctrine\ORM\Mapping\ClassMetadata[] */
$newMetadatas = array();
foreach ($metadatas as $metadata) {
if (!in_array($metadata->getName(), $this->ignoredEntities)) {
array_push($newMetadatas, $metadata);
}
}
parent::executeSchemaCommand($input, $output, $schemaTool, $newMetadatas);
}
}
除了上述答案之外,如果您正在使用Doctrine迁移来更新模式,则以下配置完美适用。
/**
* @ORM\Entity(readOnly=true)
* @ORM\Table(name="view_table_name")
*/
class YourEntity {
private function __construct() {}
}
到这里和以上的答案是一样的。在这里,你需要配置Doctrine不绑定模式。
doctrine:
dbal:
schema_filter: ~^(?!view_)~
上述过滤器定义过滤所有以“view_”为前缀的表和视图,并可使用正则表达式进行扩展。只需确保您已将视图命名为“view_”前缀即可。
但是,doctrine:schema:update --dump-sql仍然显示了视图,希望他们也能将相同的过滤器集成到模式更新中。
我希望这个解决方案能帮助其他人。
来源:http://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html#manual-tables
schema_filter: ~^(?!view_)~
我花了一整天的时间,因为需要在Zend实现中引入一个视图到我的数据库中。
正如之前所说,您应该创建一个实体,这个实体必须有Id()
注释:
/**
* @Doctrine\ORM\Mapping\Table(name="your_view")
* @Doctrine\ORM\Mapping\Entity(readOnly=true)
*/
class YourViewEntity
{
/**
* @var SomeEntityInterface
* @Doctrine\ORM\Mapping\Id()
* @Doctrine\ORM\Mapping\OneToOne(targetEntity="SomeMainEntity", fetch="LAZY")
* @Doctrine\ORM\Mapping\JoinColumn(nullable=false, referencedColumnName="id")
*/
protected $some;
/**
* @var AnotherEntityInterface
* @Doctrine\ORM\Mapping\ManyToOne(targetEntity="AnotherEntity", fetch="LAZY")
* @Doctrine\ORM\Mapping\JoinColumn(nullable=false, referencedColumnName="id")
*/
protected $another;
// Make the constructor private so that only Doctrine can create instances.
private function __construct() {}
}
同时,还可以使用私有构造函数,如Ian Phillips的回答所述。然而,这并不能防止orm:schema-tool:update
基于新实体创建表格,试图覆盖我们的视图...尽管在生产环境中应该避免使用orm:schema-tool:update
,而应该使用迁移脚本,但对于开发目的来说,这非常有用。
由于schema_filter: ~^(?!view_)~
似乎都不起作用了,而且已经过时了,我设法在Kamil Adryjanek页面上找到了一个技巧,它提供了向实体管理器添加EventListener
或Subscriber
的选项,这将防止为我们创建表格。我的实现如下:
class SkipAutogenerateTableSubscriber implements EventSubscriber
{
public const CONFIG_KEY = "skip_autogenerate_entities";
private $ignoredEntities = [];
public function __construct($config)
{
if (array_key_exists(self::CONFIG_KEY, $config)) {
$this->ignoredEntities = (array) $config[self::CONFIG_KEY];
}
}
public function getSubscribedEvents()
{
return [
ToolEvents::postGenerateSchema
];
}
public function postGenerateSchema(GenerateSchemaEventArgs $args)
{
$schema = $args->getSchema();
$em = $args->getEntityManager();
$ignoredTables = [];
foreach ($this->ignoredEntities as $entityName) {
$ignoredTables[] = $em->getClassMetadata($entityName)->getTableName();
}
foreach ($schema->getTables() as $table) {
if (in_array($table->getName(), $ignoredTables)) {
$schema->dropTable($table->getName());
}
}
}
}
这不仅解决了orm:schema-tool
的问题,也解决了doctrine/migrations
模块的migrations:diff
问题。
class DoctrineUpdateCommand extends UpdateSchemaDoctrineCommand{
protected function executeSchemaCommand(InputInterface $input, OutputInterface $output, SchemaTool $schemaTool, array $metadatas) {
$container = $this->getApplication()->getKernel()->getContainer();
$filterExpr = $container->get('doctrine')->getEntityManager()->getConnection()->getConfiguration()->getFilterSchemaAssetsExpression();
$emptyFilterExpression = empty($filterExpr);
/** @var $newMetadatas \Doctrine\ORM\Mapping\ClassMetadata */
$newMetadatas = array();
foreach ($metadatas as $metadata) {
if(($emptyFilterExpression||preg_match($filterExpr, $metadata->getTableName()))){
array_push($newMetadatas, $metadata);
}
}
parent::executeSchemaCommand($input, $output, $schemaTool, $newMetadatas);
}
}