Doctrine 2 和 MySQL:table 和视图之间的关联映射
Doctrine 2 and MySQL: association mapping between a table and a view
我正在尝试在 2 个实体之间建立关联。左边一个是table表示。右边是视图表示。
我刚刚成功地建立了这个关系,但是在使用 php vendor/bin/doctrine orm:schema-tool:create
创建模式时遇到了问题。
下面是尝试它所需的全部代码:
SQL
CREATE TABLE IF NOT EXISTS `demo` (
`id` int(11) NOT NULL,
`name` varchar(30) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `demo` (`id`, `name`) VALUES
(1, 'demo 1'),
(2, 'demo 2'),
(3, 'demo 3'),
(4, 'demo 4');
CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `demo_metadata` AS select `se`.`id` AS `demo_id`,12 AS `demo_count` from `demo` `se`;
演示Table实体
/**
* @Entity
* @Table(name="demo")
*/
class Demo {
/**
* @Id
* @Column(type="integer")
* @GeneratedValue
*/
private $id;
/**
* @Column(type="string", length=30)
*/
private $name;
/**
* @OneToOne(targetEntity="DemoMetadata")
* @JoinColumn(name="id", referencedColumnName="demo_id")
*/
private $metadata;
public function getMetadata() {
return $this->metadata;
}
}
演示视图实体
/**
* @Entity
* @Table(name="demo_metadata")
*/
class DemoMetadata {
/**
* @Id
* @Column(type="integer")
* @var int
*/
private $demo_id;
/**
* @Column(type="integer")
* @var int
*/
private $demo_count;
public function getDemoCount() {
return $this->demo_count;
}
}
查询和获取数据
$qb = $em->createQueryBuilder();
$qb
->select('d')
->from('Demo', 'd')
->leftJoin('d.metadata', 'dm')
->where('d.id = ?0')
->setParameter(0, 1);
$demo_object = $qb->getQuery()->getSingleResult();
var_dump($demo_object->getMetadata()->getDemoCount());
// display: int(12)
正如我们所见,演示实体的元数据 属性 填充了来自视图的数据。一切正常,符合预期。
但是使用这样的配置,当运行 cli 命令删除模式,然后重新创建它时,会发生错误,因为demo_metadata
table 已经存在。
最后,我不是在寻找一种自动创建视图的方法。我有 SQL 个脚本,我可以调用这些脚本来创建视图。我想知道是否有办法不尝试为某些实体创建 table?
[Doctrine\ORM\Tools\ToolsException]
Schema-Tool failed with Error 'An exception occurred while executing 'CREATE TABLE demo_metadata (demo_id INT NOT NULL, demo_count INT NOT NULL, PRIMARY KEY(demo_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8 _unicode_ci ENGINE = InnoDB':
SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'demo_metadata' already exists' while executing DDL: CREATE TABLE demo_metadata (demo_id INT NOT NULL, demo_count INT NOT NULL, PRIMARY KEY(demo_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB
这只是为了方便,因为视图已经存在并且不会被 cli drop 命令删除。
是否唯一的解决方法是:
- 删除模式(原则 cli)
- 删除
demo_metadata
视图
- 创建模式(原则 cli)
- 删除
demo_metadata
table
- 创建
demo_metadata
视图
谢谢
编辑
最后,我使用这段代码过滤了我需要的实体:
<?php
class UpdateSchema extends \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand {
/**
* {@inheritdoc}
*/
protected function executeSchemaCommand(
InputInterface $input,
OutputInterface $output,
SchemaTool $schemaTool,
array $metadatas) : int
{
$entities = array_filter($metadatas, function ($m) {
return !$m->isReadOnly;
});
return parent::executeSchemaCommand($input, $output, $schemaTool, $entities);
}
}
除了create
和drop
命令外,还有一个update
命令。如果数据库已经存在,那是你应该使用的那个
错误答案,正确见评论
我正在尝试在 2 个实体之间建立关联。左边一个是table表示。右边是视图表示。
我刚刚成功地建立了这个关系,但是在使用 php vendor/bin/doctrine orm:schema-tool:create
创建模式时遇到了问题。
下面是尝试它所需的全部代码:
SQL
CREATE TABLE IF NOT EXISTS `demo` (
`id` int(11) NOT NULL,
`name` varchar(30) COLLATE utf8_unicode_ci NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `demo` (`id`, `name`) VALUES
(1, 'demo 1'),
(2, 'demo 2'),
(3, 'demo 3'),
(4, 'demo 4');
CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `demo_metadata` AS select `se`.`id` AS `demo_id`,12 AS `demo_count` from `demo` `se`;
演示Table实体
/**
* @Entity
* @Table(name="demo")
*/
class Demo {
/**
* @Id
* @Column(type="integer")
* @GeneratedValue
*/
private $id;
/**
* @Column(type="string", length=30)
*/
private $name;
/**
* @OneToOne(targetEntity="DemoMetadata")
* @JoinColumn(name="id", referencedColumnName="demo_id")
*/
private $metadata;
public function getMetadata() {
return $this->metadata;
}
}
演示视图实体
/**
* @Entity
* @Table(name="demo_metadata")
*/
class DemoMetadata {
/**
* @Id
* @Column(type="integer")
* @var int
*/
private $demo_id;
/**
* @Column(type="integer")
* @var int
*/
private $demo_count;
public function getDemoCount() {
return $this->demo_count;
}
}
查询和获取数据
$qb = $em->createQueryBuilder();
$qb
->select('d')
->from('Demo', 'd')
->leftJoin('d.metadata', 'dm')
->where('d.id = ?0')
->setParameter(0, 1);
$demo_object = $qb->getQuery()->getSingleResult();
var_dump($demo_object->getMetadata()->getDemoCount());
// display: int(12)
正如我们所见,演示实体的元数据 属性 填充了来自视图的数据。一切正常,符合预期。
但是使用这样的配置,当运行 cli 命令删除模式,然后重新创建它时,会发生错误,因为demo_metadata
table 已经存在。
最后,我不是在寻找一种自动创建视图的方法。我有 SQL 个脚本,我可以调用这些脚本来创建视图。我想知道是否有办法不尝试为某些实体创建 table?
[Doctrine\ORM\Tools\ToolsException]
Schema-Tool failed with Error 'An exception occurred while executing 'CREATE TABLE demo_metadata (demo_id INT NOT NULL, demo_count INT NOT NULL, PRIMARY KEY(demo_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8 _unicode_ci ENGINE = InnoDB':
SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'demo_metadata' already exists' while executing DDL: CREATE TABLE demo_metadata (demo_id INT NOT NULL, demo_count INT NOT NULL, PRIMARY KEY(demo_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB
这只是为了方便,因为视图已经存在并且不会被 cli drop 命令删除。
是否唯一的解决方法是:
- 删除模式(原则 cli)
- 删除
demo_metadata
视图 - 创建模式(原则 cli)
- 删除
demo_metadata
table - 创建
demo_metadata
视图
谢谢
编辑
最后,我使用这段代码过滤了我需要的实体:
<?php
class UpdateSchema extends \Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand {
/**
* {@inheritdoc}
*/
protected function executeSchemaCommand(
InputInterface $input,
OutputInterface $output,
SchemaTool $schemaTool,
array $metadatas) : int
{
$entities = array_filter($metadatas, function ($m) {
return !$m->isReadOnly;
});
return parent::executeSchemaCommand($input, $output, $schemaTool, $entities);
}
}
除了create
和drop
命令外,还有一个update
命令。如果数据库已经存在,那是你应该使用的那个
错误答案,正确见评论