我想用前缀定义一些id。
例如,对于一个订单实体,它:“OR17000001” 在此示例中,前缀为“OR17”
所以我声明了我的id实体:
/**
* @var string
*
* @ORM\Column(name="id", type="string", length=8)
* @ORM\Id
* @ORM\GeneratedValue(strategy="CUSTOM")
* @ORM\CustomIdGenerator(class="My\Bundle\Generator\OrderCodeGenerator")
*/
private $id;
我的发电机是:
<?php
namespace My\Bundle\Generator;
use Doctrine\ORM\Id\AbstractIdGenerator;
use Doctrine\ORM\EntityManager;
use My\Bundle\Entity\Order;
class OrderCodeGenerator extends AbstractIdGenerator
{
/**
* Format :
* $prefix - string
* $year - take 2 first letters (17)
* $increment - Take the last code + 1
*
* @param EntityManager $em
* @param \Doctrine\ORM\Mapping\Entity $entity
* @return bool|string
*/
public function generate(EntityManager $em, $entity)
{
if ($entity instanceof Order) {
$now = new \DateTime();
$year = $now->format('y');
$prefix = 'OR';
$maxCode = $em->getRepository('MyRepo:Order')->findMaxCode($year, $prefix);
if ($maxCode) {
$increment = substr($maxCode[1], -4);
$increment = (int)$increment + 1;
} else
$increment = 0;
$code = $prefix . $year . sprintf('%04d', $increment);
return $code;
}
return false;
}
}
不要忘记方法findMaxCode:
public function findMaxCode($year, $prefix)
{
$qb = $this->createQueryBuilder('entity');
$qb->where($qb->expr()->like('entity.id', ':code'))
->setParameter('code', '%' . $prefix . $year . '%');
$qb->select($qb->expr()->max('entity.id'));
return $qb->getQuery()->getOneOrNullResult();
}
这很好用=)
我的问题是当我尝试同时添加一些实体时。 我的情况是:
所以我需要使用此策略自定义项目订单ID。问题是找到最大代码。我有这个错误:
SQLSTATE [23000]:完整性约束违规:1062 Duplicata du 冠军'IT170000001'pour la clef'PRIMARY'
生成器无法找到生成第二项的最大代码,因为没有刷新。
如何在刷新之前将增量值保存在2 id之间?
解决方案:
我保留了我的物品的数字ID。它对我的Order实体很有用,它比简单的int更具可读性。但我不关心物品。
致Honza Rydrych
答案 0 :(得分:2)
查询DB以获取最后插入的ID,然后插入“+ one”并不是可靠的解决方案。 我对这种情况的解决方案是让doctrine以标准方式生成ID,并在需要提供数据时添加前缀“OR / Year /”。
(Optionaly你可以编写自定义的Twig扩展来呈现ID http://symfony.com/doc/current/templating/twig_extension.html)