php – 使用复合主键生成自动增量ID

发布时间:2022-04-30 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了php – 使用复合主键生成自动增量ID脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
我想给一个实体(发票,订单,预订等)一个唯一的序列号,但在那一年内只是唯一的.因此,每年(或其他字段,如客户)启动的第一张发票的ID为1.这意味着可以有复合主键(年份,ID)或一个主键(即invoice_id)和另外两个列.独特的.

我的问题:使用Doctrine2和Symfony2为对象提供自动生成的ID和其他值的唯一组合的最佳方法是什么

复合键的学说限制

Doctrine无法为具有复合主键的实体分配自动生成的ID(http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/composite-primary-keys.html):

手动设置序列号

所以我必须手动分配ID.为了做到一点,我试图在某一年寻找最高的ID并给出ID为1的新实体.我怀疑这是最好的方式,即使它是,我也没有找到最好的(DRY) )这样做的方式.由于我认为这是一个通用问题,我想阻止XY-problem,我已经开始提出这个问题了.

香草选择:仅限MyISam

找到了基于this answer的’vanilla’MysqL / MyISAM解决方案:

CREATE TABLE IF NOT EXISTS `invoice` (
  `year` int(1) NOT NULL,`id` mediumint(9) NOT NULL AUTO_INCREMENT,Primary KEY (`year`,`id`)
) ENginE=MyISAM;

由于Doctrine2的局限性,这是行不通的,所以我正在寻找一个类似于这个vanilla MysqL解决方案的Doctrine ORM.

其他方案

InnoDB也有一个解决方案:Defining Composite Key with Auto Increment in MySQL

@H_126_23@
链接的预插入触发器解决方案的ORM等效项将是生命周期回调.你可以阅读更多关于他们 here.

一个天真的解决方案看起来像这样.

services.yML

services:
    invoice.listener:
        class: MyCompany\CompanyBundle\EventListener\InvoiceListener
        tags :
            - { name: doctrine.event_subscriber,connection: default }

InvoiceListener.PHP

<?PHP

namespace MyCompany\CompanyBundle\EventListener;

use Symfony\component\EventDispatcher\EventDispatcherInterface;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\OnFlushEventargs;
use Doctrine\ORM\Event\PostFlushEventArgs;

use MyCompany\CompanyBundle\EntITy\Invoice;

class InvoiceListener implements EventSubscriber {

    PRotected $invoices;

    public function getSubscribedEvents() {
        return [
            'onFlush','postFlush'
        ];
    }

    public function onFlush(OnFlushEventArgs $event) {
        $this->invoices = [];
        /* @VAR $em \Doctrine\ORM\EntityManager */
        $em = $event->getEntityManager();
        /* @var $uow \Doctrine\ORM\UnitOfWork */
        $uow = $em->getUnitOfWork();

        foreach ($uow->getScheduledEntityInsertions() as $entity) {
            if ($entity instanceof Invoice) {
                $this->invoices[] = $entity;
            }
        }
    }

    public function postFlush(PostFlushEventArgs $event) {
        if (!empty($this->invoices)) {

            /* @var $em \Doctrine\ORM\EntityManager */
            $em = $event->getEntityManager();

            foreach ($this->invoices as $invoice) {
                // Get all invoices already in the database for the year in question
                $invoicesToDate = $em
                    ->getRepository('MyCompanyCompanyBundle:Invoice')
                    ->findBy(array(
                        'year' => $invoice->getYear()
                        // You Could include e.g. clientID here if you wanted
                        // to generate a different sequence PEr client
                    );
                // Add your sequence number
                $invoice->setSequenceNum(count($invoicesToDate) + 1);

                /* @var $invoice \MyCompany\CompanyBundle\Entity\Invoice */
                $em->persist($invoice);
            }

            $em->flush();
        }
    }
}

脚本宝典总结

以上是脚本宝典为你收集整理的php – 使用复合主键生成自动增量ID全部内容,希望文章能够帮你解决php – 使用复合主键生成自动增量ID所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。