Отримати останній вставний ідентифікатор із доктриною 2?


76

Як я можу отримати останній вставний ідентифікатор за допомогою доктрини 2 ORM? Я не знайшов цього в документації доктрини, чи можливо це взагалі?


спробуйте це, в кінці вставки поверніть id ... як поверніть $ this-> id;
Manie

Відповіді:


178

Мені довелося використовувати це після змиву, щоб отримати останній ідентифікатор вставки:

$em->persist($user);
$em->flush();
$user->getId();

2
Не можу це використовувати. Отримання помилки Виклик невизначеного методу Test \ Entity \ Test :: getId () у "Моєму проекті"
noobie-php

@ noobie-php Вам потрібно визначити загальнодоступний для вашого ідентифікатора (якщо цей приватний, як і має бути)
cheesemacfly

@cheesemacfly: Я вже це розібрав, ця помилка генерується (у моєму сценарії), коли ми не можемо змити () з будь-якої причини, як тільки Flush () успішно виконаний getID () починає працювати, припускаючи, що getter і setters не є проблемою тут
noobie-php

1
Що робити, якщо я persist()сутність в циклі і flush()після цього? Я намагаюся це зрозуміти, але поки що не везе.
Nat Nydenova

призначити ідентифікатор змінній: code$ id = $ user-> getId (); code
Джосія

40

Ви можете отримати доступ до ідентифікатора після виклику методу persist менеджера сутності.

$widgetEntity = new WidgetEntity();
$entityManager->persist($widgetEntity);
$entityManager->flush();
$widgetEntity->getId();

Ви дійсно повинні флеш, щоб отримати цей ідентифікатор.

Виправлення помилки синтаксису: Додано крапку з комою після виклику $ entityManager-> flush ().


6
Мені довелося промити, щоб повернути значення. Збереження було недостатньо, оскільки елементи насправді не записуються в базу даних, поки ви не очистите.
Джеремі Хікс,

29

Якщо ви використовуєте не сутності, а власний SQL, як показано тут, ви можете отримати останній вставлений ідентифікатор, як показано нижче:

$entityManager->getConnection()->lastInsertId()

Для баз даних із послідовностями, таких як PostgreSQL, зверніть увагу, що ви можете вказати ім'я послідовності як перший параметр lastInsertIdметоду.

$entityManager->getConnection()->lastInsertId($seqName = 'my_sequence')

Для отримання додаткової інформації подивіться на код на GitHub тут і тут .


Це може працювати не з усіма СУБД. Наприклад, це не працює з Postgres (через послідовності)
paul.ago

Чудово !! Я годинами шукав цей маленький фрагмент.
MikeGA

4
@ paul.ago Вам просто потрібно знати назву послідовності, наприклад:lastInsertId('articles_id_seq')
ChocoDeveloper

1
Ви також можете отримати назву послідовності так: $conn = $this->getDoctrine()->getConnection(); $metadata = $em->getClassMetadata('\App\Entity\YourClass'); $seqName = $metadata->getSequenceName($conn->getDatabasePlatform());Works :-)
Hugues D

10

Виклик flush () може потенційно додати багато нових сутностей, тому насправді не існує поняття "lastInsertId". Однак Doctrine заповнює поля ідентичності щоразу, коли вони генеруються, тому доступ до поля id після виклику флешу завжди буде містити ідентифікатор нещодавно "збереженої" сутності.


2

Трохи пізно відповісти на питання. Але,

Якщо це база даних MySQL

повинен $doctrine_record_object->idпрацювати, якщо AUTO_INCREMENTце визначено у базі даних та у визначенні вашої таблиці.


0

Тут я розміщую свій код, після того, як я наполягав на одному робочому дні для пошуку цього рішення.

Функція отримання останнього збереженого запису:

private function getLastId($query) {
        $conn = $this->getDoctrine()->getConnection();
        $stmt = $conn->prepare($query);
        $stmt->execute();
        $lastId = $stmt->fetch()['id'];
        return $lastId;
    }

Ще одна функція, яка викликає вищевказану функцію

private function clientNum() {
        $lastId = $this->getLastId("SELECT id FROM client ORDER BY id DESC LIMIT 1");
        $noClient = 'C' . sprintf("%06d", $lastId + 1); // C000002 if the last record ID is 1
        return $noClient;
    }

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.