В этой статье описывается метод операции Hibernate Pactor. Поделитесь этим для вашей ссылки, следующим образом:
Обработка с зимней партией
Hibernate управляет базой данных полностью ориентированным на объектно. Когда постоянный объект работает объектно-ориентированным способом в программе, он будет автоматически преобразован в операцию в базе данных. Например, при вызове метод Session () для удаления постоянного объекта Hibernate будет отвечать за удаление соответствующих записей данных; При выполнении метода SET постоянного объекта Hibernate будет автоматически конвертировать в соответствующий метод обновления и изменить соответствующие записи базы данных.
Вопрос заключается в том, нужно ли 100 000 записей одновременно обновлять, нужно ли вам загружать 100 000 записей один за другим, а затем вызовать метод SET в свою очередь - это не только громоздкий, но и производительность доступа к данным очень плохая. Для этого сценария обработки пакетов Hibernate предоставляет решение для обработки партии. Следующее представляет, как столкнуться с этой ситуацией с обработкой партии из трех аспектов: вставка партии, обновление партии и удаление партии.
1 пакетная вставка
Если вам нужно вставить 100 000 записей в базу данных, Hibernate обычно может использовать следующее:
Session Session = sessionFactory.Opensession (); Transaction tx = session.beginTransaction (); for (int i = 0; i <100000; i ++) {user u = новый пользователь (......); session.save (customer);} tx.commit (); session.close ();Но по мере того, как эта программа работает, в какой -то момент она всегда будет терпеть неудачу, и выброшено OutofmemoryException. Это связано с тем, что сеанс Hibernate содержит требуемый кэш уровня 1, и все экземпляры пользователей будут кэшированы в области кэша на уровне сеанса.
Чтобы решить эту проблему, есть очень простая идея: регулярно освещать данные, кэшированные сеансом в базу данных, а не всегда кэшировать их на уровне сеанса. Вы можете рассмотреть вопрос о разработке аккумулятора, который увеличивается на 1 для каждого сохраненного экземпляра пользователя. Определите, должны ли данные в кэше сеанса промыть в базу данных на основе значения аккумулятора.
Вот фрагмент кода, который добавляет 100 000 экземпляров пользователей:
private void testuser () бросает исключение {// открыть сеанс сеанса = hibernateutil.currentsession (); // начало транзакции транзакции tx = session.beginTransaction (); // цикл 100 000 раз и вставьте 100 000 записей для (int i = 0; i <1000000; i ++) {// Создать пользователь пользователь u1 = new user (); u1.setName ("xxxxx" + i); u1.setage (i); U1.SetNationality («Китай»); // cach сеанс экземпляра пользователя.save (u1); // всякий раз, когда аккумулятор составляет 20, промывает данные в сеансе в базу данных и очистите кэш сеанса if (i % 20 == 0) {session.flush (); session.clear (); tx.commit (); tx = session.beginTransaction (); }} // Commit Transaction tx.commit (); // закрыть транзакцию hibernateutil.closesession ();}В приведенном выше коде, когда i%20 == 0 кэшированные данные на сеансе записываются вручную в базу данных, и транзакция представлена вручную. Если транзакция не будет представлена, данные по -прежнему будут кэшированы в офисе транзакций - она не ввела в базу данных, что также вызовет исключение из переполнения памяти.
Это обработка кэша на уровне сеанса, и вторичный кэш SessionFactory также следует отключить через следующую конфигурацию.
hibernate.cache.use_second_level_cache false
ПРИМЕЧАНИЕ. В дополнение к вручную очистку кэша на уровне сеанса, лучше всего отключить вторичный кэш на уровне SessionFactory. В противном случае, даже если кэш на уровне сеанса очищен вручную, может быть брошено исключение, потому что на уровне SessionFactore все еще есть кэш.
2 обновления партии
Метод, описанный выше, также подходит для данных обновления партии. Если вам нужно вернуть несколько строк данных, вы можете использовать метод Scroll () для полного использования преимуществ производительности, представленных серверными курсорами. Вот фрагмент кода для обновлений партии:
private void testuser () бросает исключение {// открыть сеанс сеанса = hibernateutil.currentsession (); // запустить транзакцию транзакции tx = session.beginTransaction (); // Запрос всех записей в пользовательской таблице ScollableResults users = session.createquery ("from user") .setCachemode (cachemode.ignore) .scroll (scrollmode.forward_only); int count = 0; // транзакция Все записи в таблице пользователя while (users.next ()) {user u = (user) users.get (0); U.SetName ("Новое имя пользователя" + count); // Когда счет равен 20, промыть обновленный результат от сеанса в базу данных if (++ count % 20 == 0) {session.flush (); session.clear (); }} tx.commit (); Hibernateutil.closesession ();} Таким образом, хотя обновления партий могут быть выполнены, эффект очень плохой. Эффективность выполнения не высока, и сначала требуется запрос данных, а затем выполняется обновление данных. Это обновление будет обновлением строк за строкой, то есть каждый раз, когда обновляется ряд записей, необходимо выполнить оператор обновления, а производительность очень низкая.
Чтобы избежать этого, Hibernate предоставляет синтаксис HQL, аналогичный SQL для обновлений партии и удаления партии.
3 SQL-пакетное обновление/удаление в стиле SQL
Операторы HQL, предоставленные Hibernate, также поддерживают обновление партии и удаление синтаксиса.
Синтаксический формат обновления пакетного обновления и удаления операторов выглядит следующим образом:
Обновление | Удалить из? Classname [где_кондиция]
Есть четыре балла, которые стоит отметить в отношении вышеуказанного синтаксического формата:
● В предложении From Ключевое слово не является обязательным. То есть вы не можете писать из ключевых слов вообще.
● В предложении From Class может быть только одно имя класса, и имя класса не может иметь псевдоним.
● Вы не можете использовать подключения в пакетных операторах HQL, ни явного, ни неявного. Но подразделы могут быть использованы в предложении, где.
● Все, где пункт не является обязательным.
Предполагая, что вам необходимо привести к изменению атрибута имени экземпляра класса пользователя, вы можете использовать следующий фрагмент кода:
private void testuser () бросает исключение {// открыть сеанс сеанса = hibernateutil.currentsession (); // начало транзакции транзакции tx = session.beginTransaction (); // Определите обновление пакетного обновления HQL String string hqlupdate = "Обновление набор пользователя name =: newName"; // Выполнить Update int updateEnties = session.createquery (hqlupdate) .setString ("newName", "Новое имя") .exeCuteUpdate (); // Комплект транзакции tx.commit (); Hibernateutil.closesession ();}Как видно из приведенного выше кода, этот синтаксис очень похож на синтаксис executeUpdate подготовленного. Фактически, это партийное обновление HQL напрямую заимствует из оператора обновления SQL Syntax.
Примечание. При использовании этого синтаксиса обновления пакетного обновления вам обычно нужно выполнить оператор SQL Update только один раз, чтобы заполнить все обновления, которые соответствуют условным записям. Но также может потребоваться выполнение нескольких операторов обновления, поскольку существуют особые случаи, такие как отображение наследования, такие как экземпляр человека, который имеет экземпляр подкласса клиента. Когда пакетные обновления экземпляров человека также необходимо обновить экземпляр клиента. Если вы используете стратегию картирования объединенного SUBClass или Union-Subclass, экземпляры человека и клиента сохраняются в разных таблицах, так что могут потребоваться несколько операторов обновления.
Выполните удаление HQL и используйте метод Query.executeUpdate (). Ниже приведен фрагмент кода, который удаляет все записи выше сразу:
private void testuser () выбрасывает Exception {// Открыть сеанс сеанса сеанса = hibernateutil.currentsession (); // начало транзакции транзакции tx = session.beginTransaction (); // определить пакетное удаление оператора HQL string hqlupdate = "Удалить пользователь"; // Выполнение удаления пакетов int updatedEnties = session.createquery (hqlupdate) .executeUpdate (); // Комплект транзакции tx.commit (); // закрыть сеанс hibernateutil.closesession ();}Возвращает целочисленное значение методом Query.executeUpdate (), который представляет собой количество записей, затронутых этой операцией. На самом деле, основные операции Hibernate выполняются через JDBC. Поэтому, если есть партии операций обновления или удаления, которые преобразуются в несколько операторов обновления или удаления, метод возвращает количество записей, затронутых последним оператором SQL.
Я надеюсь, что описание в этой статье будет полезно для каждого Java -программирования на основе пластинга Hibernate.