Doctrine orm 原则2 ORM标识符中的日期时间字段

Doctrine orm 原则2 ORM标识符中的日期时间字段,doctrine-orm,Doctrine Orm,在我们的数据库表中,refID和date列是一个复合主键,标识符的一个字段映射为datetime: class-corpWalletJournal { /** *@ORM\Column(name=“refID”,type=“bigint”,nullable=false) *@ORM\Id *@ORM\GeneratedValue(strategy=“NONE”) */ 私人的$refID; /** *@ORM\Column(name=“date”,type=“datetime”,nullable

在我们的数据库表中,
refID
date
列是一个复合主键,标识符的一个字段映射为
datetime

class-corpWalletJournal
{
/**
*@ORM\Column(name=“refID”,type=“bigint”,nullable=false)
*@ORM\Id
*@ORM\GeneratedValue(strategy=“NONE”)
*/
私人的$refID;
/**
*@ORM\Column(name=“date”,type=“datetime”,nullable=false)
*@ORM\Id
*@ORM\GeneratedValue(strategy=“NONE”)
*/
私人$日期;
公共函数setRefID($refID)
{
$this->refID=$refID;
}
公共函数setDate(\DateTime$date)
{
$this->date=$date;
}
}
若我们在实体中将它们描述为@ORM\Id,则此代码将返回异常“无法将datetime转换为字符串”

$filter=array(
“日期”=>$this->stringToDate($loopData['date']),
'refID'=>$loopData['refID']
));
$oCorpWJ=$this->em->getRepository('EveDataBundle:corpWalletJournal')->findOneBy($filter);
// ...
$oCorpWJ->setDate($this->stringToDate($loopData['date']);
// ...
如果我们把
corpWalletJournal#date
描述为一个简单的专栏,代码就可以正常工作。为什么?

我们怎么处理呢?我们需要在主键中同时包含
date
refID

添加:

所以我创建了一个新类

use \DateTime;

class DateTimeEx extends DateTime
{

public function __toString()
{
    return $this->format('Y-m-d h:i:s');
}

}
和它的新类型

use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Eve\DataBundle\Entity\Type\DateTimeEx;

class DateTimeEx extends Type
{
    const DateTimeEx = 'datetime_ex';

    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
    {
        return 'my_datetime_ex';
    }

    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        return new DateTimeEx($value);
    }

    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        return $value->format('Y-m-d h:i:s');
    }

    public function getName()
    {
        return self::DateTimeEx;
    }

    public function canRequireSQLConversion()
    {
        return true;
    }

}
如何在实体中使用它们

我的(编辑的)类型类

    use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;

class DateTimeEx extends Type
{
    const DateTimeEx = 'datetime_ex';

    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
    {
        return 'my_datetime_ex';
    }

    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        return $value;
    }

    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        return $value;
    }

    public function getName()
    {
        return self::DateTimeEx;
    }

}

条令2 ORM需要将标识符字段转换为中的字符串。这是使
EntityManager
能够跟踪对象更改所必需的

由于类型为
DateTime
的对象不以本机方式实现方法,因此将它们转换为字符串并不像将它们转换为字符串那样简单

因此,默认的
日期
日期时间
时间
类型

要处理它,您应该定义自己的
mydatetime
映射到自己的
mydatetime
类,该类实现了
\uuuu-toString
。这样,如果标识符包含对象,ORM也可以处理标识符

下面是该类的示例:

类MyDateTime扩展\DateTime
{
公共函数
{
返回$this->format('U');
}
}
下面是一个自定义DBAL类型的示例:

使用条令\DBAL\Types\DateTimeType;
使用条令\DBAL\Platforms\AbstractPlatform;
类MyDateTimeType扩展了DateTimeType
{
公共函数convertToPHPValue($value,AbstractPlatform$platform)
{
$dateTime=parent::convertToPHPValue($value,$platform);
如果(!$dateTime){
返回$dateTime;
}
返回新的MyDateTime('@'.$dateTime->格式('U');
}
公共函数requireSqlCommentHint(AbstractPlatform$platform)
{
返回true;
}
公共函数getName()
{
返回“mydatetime”;
}
}
然后在引导过程中将其注册到ORM配置中(取决于您使用的框架)。在symfony中,它记录在

之后,您可以在实体中使用它:

class-corpWalletJournal
{
// ...
/**
*@ORM\Column(name=“date”,type=“mydatetime”,nullable=false)
*@ORM\Id
*@ORM\GeneratedValue(strategy=“NONE”)
*/
私人$日期;
小心

return new DateTimeEx('@' . $dateTime->format('U'));
时区不好。你应该:

$val = new DateTimeEx('@' . $dateTime->format('U'));
$val->setTimezone($dateTime->getTimezone());

return $val;

你能解释一下,我需要在哪里以及如何更改类DateTime吗?以及如何在我的示例中使用它吗?你只需要用你自己的
类MyDateTime extends\DateTime{public function\uu toString(){return$this->format('U');}}
来扩展
类。我更新了答案。其余的都在链接文档中(链接到自定义字段类型:)我在top post中添加了代码\类,你能解释一下我如何使用它们吗?@user1954544我添加了完整的示例我注意到了一些副作用:1)doctrine:schema:update工具不断尝试更新自定义日期字段,因为doctrine的
比较器在数据库中看到
DateTime
,在本地代码中看到
MyDateTime
。2)必须将用于查询此字段的任何值转换为与自定义类型相同的类型,例如
$queryBuilder->set参数('date',new MyDateTime('@'.$dateTime->format('U'))