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'))
。