首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >原则2:对关系使用默认0值而不是null

原则2:对关系使用默认0值而不是null
EN

Stack Overflow用户
提问于 2013-03-19 22:36:20
回答 1查看 4.4K关注 0票数 6

对于Doctrine 2的关系(多对一、一对一),是否可以使用值0而不是null?

现在我有很多非空列,我可能不会将它们更改为空值。将MySQL中的缺省值更改为0本身并不是解决方案,因为发布原则总是设置用于插入/更新行的列。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-03-20 06:27:21

不,这不可能。

NULL在SQL中有一个非常特殊的含义。它表示“没有值”,您可以验证您的逻辑即使在SQL级别也无法工作:

代码语言:javascript
复制
CREATE TABLE foo (
    `id` INT(11) PRIMARY KEY AUTO_INCREMENT,
    `bar_id` INT(11)
);

CREATE TABLE `bar` (`id` INT(11) PRIMARY KEY AUTO_INCREMENT);

ALTER TABLE foo ADD FOREIGN KEY `bar_id_fk` (`bar_id`) REFERENCES `bar` (`id`);

INSERT INTO `bar` VALUES (NULL);
INSERT INTO `bar` VALUES (NULL);
INSERT INTO `bar` VALUES (NULL);
INSERT INTO `foo` VALUES (NULL, 1);
INSERT INTO `foo` VALUES (NULL, 2);
INSERT INTO `foo` VALUES (NULL, 3);
INSERT INTO `foo` VALUES (NULL, 0);

/*
    ERROR 1452 (23000): 
        Cannot add or update a child row: a foreign key constraint fails
        (`t2`.`foo`, CONSTRAINT `foo_ibfk_1` FOREIGN KEY (`bar_id`) 
        REFERENCES `bar` (`id`))
*/

INSERT INTO `foo` VALUES (NULL, 4);

/*
    ERROR 1452 (23000): 
        Cannot add or update a child row: a foreign key constraint fails
        (`t2`.`foo`, CONSTRAINT `foo_ibfk_1` FOREIGN KEY (`bar_id`) 
        REFERENCES `bar` (`id`))
*/

INSERT INTO `foo` VALUES (NULL, NULL); /* VALID! */

所以,你不能让Doctrine ORM的行为使得0被解释为NULL,因为这是关系型数据库本身不允许的。

你可以做的就是在你的数据库中插入“假的”引用的条目,当它被合并为实体时,它将充当null object

代码语言:javascript
复制
INSERT INTO `bar` VALUES (NULL);
UPDATE `bar` SET `id` = 0 WHERE `id` = 4;

INSERT INTO `foo` VALUES (NULL, 0); /* now works! */

在实体方面,它看起来非常相似。

(请注意,public属性仅在Doctrine ORM2.4中受支持,该版本尚未发布。不过,它们让这里的内容更容易阅读。)

Foo.php:

代码语言:javascript
复制
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity()
 * @ORM\Table(name="foo")
 */
class Foo
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id()
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    public $id;

    /**
     * @ORM\ManyToOne(targetEntity="Bar")
     * @ORM\JoinColumn(name="bar_id", referencedColumnName="id", nullable=false)
     */
    public $bar;
}

Bar.php:

代码语言:javascript
复制
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity()
 * @ORM\Table(name="bar")
 */
class Bar
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id()
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    public $id;
}

然后是生成新Foo实例的代码:

代码语言:javascript
复制
$nullBar  = $entityManager->find('Bar', 0);
$foo      = new Foo();
$foo->bar = $nullBar;

$em->persist($foo);
$em->flush();
票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15502408

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档