Hibernate Batch Add Modify Delete

Source: Internet
Author: User

Batch processing of 4.2 hibernate

Hibernate operates the database entirely in an object-oriented manner, and is automatically converted to operations on the database when it is manipulated in an object-oriented manner. For example, by calling the session's Delete () method to delete the persisted object, hibernate will be responsible for deleting the corresponding data record, and when executing the persisted object's set method, Hibernate will automatically convert to the corresponding Update method and modify the corresponding record of the database.

The problem is that if you need to update the 100?000 record at the same time, it is not necessary to load the 100?000 records one after the other, and then call the set method in turn-this is not only tedious, but also bad for data access. For this batch processing scenario, Hibernate provides a batch processing solution, which describes how to deal with this batch process in 3 ways, from BULK INSERT, batch update, and bulk Delete.

4.2.1 BULK INSERT
== session.begintransaction ();  for int i=0; i<100000; i++ ) {    new  User (...);    Session.save (customer);} Tx.commit (); Session.close ();

But as this program runs, it always fails at some point and throws OutOfMemoryException (memory overflow exception). This is because Hibernate's session holds a required first-level cache, and all user instances are cached at the session level of the buffer.

To solve this problem, there is a very simple idea: timed to flush the session cache data into the database, rather than always at the session level cache. Consider designing an accumulator that increments by 1 for each user instance saved. Determines whether the data in the session cache needs to be brushed into the database, depending on the value of the accumulator.

The following is a code snippet that adds 100?000 user instances:

Private voidTestUser ()throwsexception{//Open SessionSession Session=hibernateutil.currentsession (); //Start a transactionTransaction TX=session.begintransaction (); //loop 100 000 times, insert 100 000 records     for(inti = 0; i < 1000000; i++ )    {        //Create a User instanceUser U1=NewUser (); U1.setname ("XXXXX" +i);        U1.setage (i); U1.setnationality ("China"); //Cache user Instances at session levelSession.save (U1); //whenever the accumulator is a multiple of 20, the data in the session is flushed into the database and the session cache is emptied        if(i% 20 = = 0) {Session.flush ();            Session.clear ();            Tx.commit (); TX=session.begintransaction (); }    }    //Commit a transactionTx.commit (); //Close Transactionhibernateutil.closesession ();}

In the above code, when i%20 = = 0 o'clock, manually write the cached data at the session to the database and commit the transaction manually. If you do not commit the transaction, the data will still be cached at the transaction--without entering the database, and will also cause a memory overflow exception.

This is the processing of the session level cache, and the sessionfactory level two cache should also be turned off with the following configuration.

Hibernate.cache.use_second_level_cache false

Note: In addition to manually emptying the session-level cache, it is a good idea to turn off level two cache at sessionfactory. Otherwise, an exception can be thrown even if the session-level cache is manually emptied, but because there is also a cache at the sessionfactory level.

4.2.2 Batch Update

The methods described above also apply to batch update data, and if you need to return multiple rows of data, you can use the scroll () method to take advantage of the performance benefits of server-side cursors. Here is the code snippet for bulk update:

Private voidTestUser ()throwsexception{//Open SessionSession Session=hibernateutil.currentsession (); //Start a transactionTransaction TX=session.begintransaction (); //querying all records in the user tableScrollableresults Users= Session.createquery ("From User"). Setcachemode (Cachemode.ignore). Scroll (scrollmode.forward_only); intCount=0; //traverse all records in the user table     while(Users.next ()) {User U= (User) users.get (0); U.setname ("New user name" +count); //flush the updated results from the session to the database when count is a multiple of 20        if(++count% 20 = = 0) {Session.flush ();        Session.clear ();    }} tx.commit (); Hibernateutil.closesession ();}

Of course, you can also use Hibernate configuration to achieve the same functionality:

Insert in Hibernate.cfg.xml:

<property name= "hibernate.jdbc.batch_size" >50</property>//<property name= " Hiberante.cache.use_second_level_cache ">false</property>//

In this way, although batch updates can be performed, the effect is very bad. Execution is inefficient, and you need to perform a data query before you perform the data update, and the update will be a progressive update that requires an UPDATE statement to be executed for every row of records, with very low performance.

To avoid this, Hibernate provides a SQL-like bulk update and a bulk-delete hql syntax.

4.2.3 SQL-style batch update/delete

The HQL statement provided by Hibernate also supports batch update and delete syntax.

The syntax format for bulk UPDATE and DELETE statements is as follows:

UPDATE | DELETE from? ClassName [WHERE Where_conditions]

The following four points are worth noting about the syntax format above:

In the FROM clause, the FROM keyword is optional. That is, you can completely not write the FROM keyword.

There can be only one class name in the FROM clause, and the class name cannot have an alias.

You cannot use a connection in a bulk HQL statement, either explicitly or implicitly. However, you can use subqueries in the WHERE clause.

The entire WHERE clause is optional.

It is assumed that the Name property of the user class instance needs to be changed in bulk and can be done with the following code snippet:

Private voidTestUser ()throwsexception{//Open SessionSession Session=hibernateutil.currentsession (); //Start a transactionTransaction TX=session.begintransaction (); //define HQL Statements for bulk updatesString hqlupdate= "Update User set name =: NewName"; //Perform the update    intUpdatedentities =session.createquery (hqlupdate). setString ("NewName", "New name"). Executeupdate (); //Commit a transactionTx.commit (); Hibernateutil.closesession ();}

As can be seen from the above code, this syntax is very similar to PreparedStatement's executeupdate syntax. In fact, this batch update of HQL is a direct reference to the SQL syntax of the UPDATE statement.

Note: When using this bulk update syntax, it is usually only necessary to execute the SQL UPDATE statement once, so that all updates that satisfy the condition record can be completed. However, you may also need to execute multiple UPDATE statements, because there are special cases such as inheritance mappings, such as having a person instance, which has a subclass instance of customer. When you bulk update a person instance, you also need to update the customer instance. If the Joined-subclass or Union-subclass mapping policy is used, the person and customer instances are saved in separate tables, so multiple UPDATE statements may be required.

Execute a HQL Delete, also use the Query.executeupdate () method, and the following is a code snippet that deletes all of the above records at once:

Private voidTestUser ()throwsexception{//Open Session InstanceSession Session=hibernateutil.currentsession (); //Start a transactionTransaction TX=session.begintransaction (); //Define Bulk-deleted HQL statementsString hqlupdate= "Delete User"; //Perform bulk Delete    intUpdatedentities =session.createquery (hqlupdate). Executeupdate (); //Commit a transactionTx.commit (); //Close Sessionhibernateutil.closesession ();}

The Query.executeupdate () method returns an integer value that is the number of records affected by this operation. In fact, the underlying operation of hibernate is done through JDBC. Therefore, if a batch update or delete operation is converted to multiple update or DELETE statements, the method returns the number of record rows affected by the last SQL statement.

4.2.4 can also be bulk-inserted with Preparedstatemen,

The following example:

Session session =hibernateutil.getsessionfactory (). Getcurrentsession (); Transaction Tran=session.begintransaction ();         Session.setcachemode (Cachemode.ignore);         PreparedStatement stmt; Try{stmt= Session.connection (). Preparestatement ("INSERT into EVENTS (event_date, title) VALUES (?,?)");  for(inti = 0; I &lt; 200000; i++) {Stmt.settimestamp (1,NewTimestamp (NewDate (). GetTime ())); Stmt.setstring (2, "title[" +i+ "]");             Stmt.addbatch ();         } stmt.executebatch (); } Catch(SQLException e) {e.printstacktrace ();         Tran.rollback ();         } tran.commit ();         Session.close (); Hibernateutil.getsessionfactory (). Close (); 

Hibernate Batch Add Modify Delete

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.