Что касается проблемы спящего режима, с которой вчера столкнулись мои коллеги. Это самая основная вещь в спящем режиме. Я понимаю, что многие люди сталкивались с этой проблемой и она очень распространена, но они часто приходят в замешательство, столкнувшись с ней.
Чтобы углубить впечатление, знайте, что это такое и почему это так.
После этого я просто использовал исходную среду Hibernate для некоторой проверки, открыл консоль распечатки выполнения SQL и пришел к выводу:
Предполагается, что в середине одной и той же транзакции:
1. Используйте оператор sql session.createSQLQuery(sql).executeUpdate() для вставки, и станция вывода распечатает оператор вставки sql, а затем использует оператор sql для выполнения session.createSQLQuery(sql).uniqueResult(); ; и SQL-запрос также будет напечатан, проблем нет, и данные можно запрашивать.
2. Используйте спящий режим для инкапсуляции операции и используйте session.save(entity); Консоль вывода не распечатывает вставленный оператор SQL. Затем используйте метод session.get(entity,id); он также не распечатывает оператор SQL-запроса, но данные можно запросить. Когда выполняется оператор фиксации транзакции, вставленный оператор SQL распечатывается.
3. Используйте hibernate session.save(entity); для вставки, а затем используйте оператор «HQL» для запроса. Эффект тот же, что и во втором пункте выше.
4. Используйте session.save(entity) hibernate для вставки, но консоль вывода не распечатывает вставленный оператор SQL. Затем используйте оператор sql для выполнения session.createSQLQuery(sql).uniqueResult(), и оператор запроса SQL будет напечатан. Произошла проблема, данные не могут быть запрошены. В этом случае используйте метод session.flush(), выполните методlush() перед запросом, и консоль вывода распечатает вставленный оператор SQL. Если вы сделаете запрос еще раз, у вас будут данные.
После завершения проверки я проверил приведенную выше информацию. Что касается четвертого пункта, он часто появлялся в процессе разработки. Я думаю, что многие люди сталкивались с этим, но многие продолжают путаться. Это только углубило впечатление.
Из SQL консоли печати мы можем увидеть процесс работы базового метода сохранения в спящем режиме:
1. Определить, находится ли уже сохраняемый экземпляр в постоянном состоянии, и если нет, поместить его в кэш;
2. Запланируйте оператор вставки sql на основе сохраняемого экземпляра. Обратите внимание, что он только планируется, но не выполняется;
3. Ранее запланированный оператор вставки выполняется при фиксации транзакции;
Замените tx.commit() на session.flush. В этот момент элемент управления распечатывает оператор вставки, но новые записи в базу данных не добавляются.
Основная функция метода очистки — очистка кеша и принудительная синхронизация базы данных с кешем Hibernate для обеспечения согласованности данных. Его основное действие — отправить серию операторов SQL в базу данных и выполнить эти операторы SQL, но он не отправит их в базу данных. Метод фиксации сначала вызовет метод сброса, а затем зафиксирует транзакцию. Вот почему запись не вставляется в базу данных, когда мы просто вызываем флеш, потому что обновления в базе данных не будут сохранены до тех пор, пока транзакция не будет зафиксирована. Поскольку метод фиксации неявно вызывает метод сброса, мы обычно не вызываем метод сброса явно.
Это механизм очистки спящего режима. В процессе обновления и сохранения некоторых сложных объектов необходимо учитывать, влияют ли изменения порядка операций с базой данных и отложенные сбросы на результаты работы программы. Если влияние действительно есть, вы можете добавить сброс там, где вам нужно поддерживать порядок операций, чтобы заставить Hibernate сбрасывать операции, записанные в кеше, в базу данных. Это может выглядеть некрасиво, но это очень эффективно.
Вопрос: Метод session.save помещен в кеш и не может быть обнаружен с помощью SQL, напрямую запрашивающего базу данных.
После методаlush() выполненный SQL будет напечатан, но его еще нет в базе данных. Прямой SQL-запрос может найти данные.
1. Где хранятся данные объекта после сброса()? Кэш аналогичен методу save(), поэтому SQL не сможет его получить.
2. Поскольку данные не попали в базу данных после метода очистки, SQL можно запросить напрямую с помощью session.createSQLQuery(sql) для запроса. Следует напрямую проверить, что это не база данных. Какое место он запрашивает?