Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Когда и зачем использовать em.clear() в МикроОрм

Автор вопроса: YunhaiОтветов: 2

Я немного запутался в том, что em.clear() делает в MikroOrm или любом подобном менеджере сущностей. https://mikro-orm.io/docs/entity-manager ссылка для clear() метод.

Кажется, некоторые из ответов stackoverflow относительно общего EntityManager сказали, что мне нужно вызывать clear() после каждого persist/remove and flush, чтобы избежать проблем с памятью.

Чтобы сделать этот вопрос более конкретным для моего случая, предположительно я создаю конечную точку Graphql в своем приложении. Есть некоторые общие функции CRUD для вызова пользователями, каждая функция создаст MikroOrm entity, используя некоторые функции MikroOrm, такие как findOne() и т. д., для выполнения некоторой общей операции CRUD в базе данных.

Означает ли это, что мне нужно вызывать clear() каждый раз после persist/remove and flush (если есть какая-то операция CUD) и даже только читать данные? А что произойдет, если я не вызову этот метод?

mikro-ormentitymanager

Ответы

Ответ 1 · рейтинг 2 · Martin Adámek

em.clear() предназначен для тестирования, поэтому вы можете имитировать несколько независимых запросов с помощью одного экземпляра EM:

const book1 = await em.findOne(Book, 1); // now book 1 will be loaded
const book2 = await em.findOne(Book, 1); // as book 1 is already loaded, this won't query the db
expect(book1).toBe(book2); // and we will get identity here
em.clear(); // but when we clear the identity map
const book3 = await em.findOne(Book, 1); // this will query the db as the state is now gone
expect(book1).not.toBe(book3); // and identity is gone

Вы можете добиться того же, используя em.fork(), используя несколько EM вместо одного.

Память должна освобождаться автоматически при сборке мусора, вам не нужен метод em.clear() в обычном (прикладном) коде. Код вашего приложения должен использовать либо вспомогательную функцию RequestContext, либо разветвление вручную (см. https://mikro-orm.io/docs/identity-map). После завершения запроса не должно быть ссылок на этот старый контекст, и он должен быть удален сборщиком мусора (но имейте в виду, что это происходит недетерминировано, например, когда JS-движку так хочется :]).

Ответ 2 · рейтинг 1 · fyn matt 881

Есть 2 метода, которые мы должны сначала описать, чтобы понять, как работает сохранение в MikroORM: em.persist() и em.flush().

em.persist(entity, flush?: boolean) используется для обозначения новых объектов для сохранения в будущем. Это сделает сущность управляемой данным EntityManager, и после вызова сброса она будет записана в базу данных. Второй логический параметр может использоваться для немедленного вызова сброса. Его значение по умолчанию настраивается с помощью опции autoFlush.

Чтобы понять flush, давайте сначала определим, что такое управляемый объект: объект является управляемым, если он получен из базы данных (через em.find(), em.findOne() или через другой управляемый объект) или зарегистрирован как новый через em.persist().

em.flush() будет проходить через все управляемые объекты, вычислять соответствующие наборы изменений и выполнять соответствующие запросы к базе данных. Поскольку сущность, загруженная из базы данных, становится управляемой автоматически, вам не нужно вызывать для них persist, и для их обновления достаточно flush.

const book = await orm.em.findOne(Book, 1);
book.title = 'How to persist things...';

// no need to persist `book` as its already managed by the EM
await orm.em.flush();

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы