1. The life cycle of the persistent object
After the application uses the Hibernate framework, the persistent objects created by the application will go through a complete set of life cycles to complete the database operations, among which the three main states are transient, persistence, and detached. The transitions of these three states can be controlled in the application, as shown in the figure below:
In order to clearly understand these states, here is an example to view the differences between objects in these states. The following codes in the states are as follows:
(1) Create a Hibernate_session assembly and add a corresponding jar package;
(2) Configure Hibernate, add the corresponding entity User class, and its mapping files, and configure the corresponding database connection;
User class file mapping file User.hbm.xml code:
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2014-4-30 15:39:33 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.hibernate.User"> <id name="id"> <generator/> </id> <property name="name"/> <property name="password"/> <property name="createTime"/> <property name="expireTime"/> </class> </hibernate-mapping>
Hibernate database connection configuration code:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_session</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">ab12</property> <!-- dialect:Dialect, the encapsulated underlying API, similar to Runtime, converts the database into the corresponding language in the configuration--> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <mapping resource="com/hibernate/User.hbm.xml"/> </session-factory> </hibernate-configuration>
(3) Add a public class of the static member sessionfactory to create a SessionFactory and its Session object;
package com.hibernate; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class session { private static SessionFactory factory; //Declare static local variable SessionFactory, database mirror static{ try{ //Create and get the configuration file for the configuration database, and obtain hibernate.cfg.xml Configuration cfg=new Configuration().configure(); factory=cfg.buildSessionFactory(); //Build a database image}catch(Exception e){ e.printStackTrace(); //Print error message} } public static Session getSession(){ return factory.openSession(); //Return the created session object} public static SessionFactory getSessionFactory(){ return factory; //Return the corresponding SessionFactory } //Close the session object public static void closeSession(Session session){ if(session != null){ if(session.isOpen()){ session.close(); } } } } }(4) Add a Source Folder, and add a package named com.hibernate in the folder, and add a class file named SessionTest to the package.
package com.hibernate; import java.util.Date; import junit.framework.TestCase; import org.hibernate.Session; import org.hibernate.Transaction; public class SessionTest extends TestCase { } 2. State conversion method
1. The object directly enters the Persistent state
1.1 get method
Get a row of information from the database and synchronize the information into the created object. This method returns an Object object and returns null if no content is found. The following example uses the Session get method to obtain an object and convert the object into an instance.
public void testGet1(){ Session session=null; Transaction tx = null; try{ session=HibernateUtils.getSession(); //Open transaction tx= session.beginTransaction(); //The object loaded by get is a persistent object//Execute get to issue a query statement immediately, and if it does not exist, it will return null User user=(User)session.get(User.class,"ff80808145bc28cc0145bc28ce020002"); System.out.println(user.getName()); // persistent state// object with persistent state changes when the object's properties change //Hibernate will synchronize user.setName("Zhao Liu"); session.getTransaction().commit(); }catch(Exception e){ e.printStackTrace(); if(tx != null){ tx.rollback(); } } finally{ HibernateUtils.closeSession(session); } } Set breakpoints to get the User object.
This object is obtained and a user object is obtained after casting. The setName method is added to the program, which means that the name in the database will be updated. After the execution is completed, the database will be checked, as shown in the figure below to update the results.
1.2 load method
The function is similar to the get method, and it also obtains data from the database and synchronizes it into the object. This method supports lazy operation. It returns a persistent Object object or a proxy, so it needs to be converted.
public void testLoad1(){ Session session=null; try{ session=HibernateUtils.getSession(); //The query statement will not be immediately checked because load supports lazy (delay load/lazy load) //What to teach lazy? Only when this object is truly used and then created, will the query statement be issued for Hibernate. It is mainly to improve performance. lazy is a very important feature in Hibernate. How is the lazy of Hibernate implemented? Implemented by proxy objects. The proxy objects mainly use // generated by the CGLIB library instead of the dynamic proxy of JDK, because the dynamic proxy of JDK can only generate proxy for classes that implement excuses. CGLIB can generate // proxy for classes. It adopts the inheritance method User user=(User)session.load(User.class,"8a1b653745bcc7b50145bcc7b7b7140001"); System.out.println(user.getName()); // persistent state// objects with persistent state, when the object's properties change // Hibernate will synchronize user.setName("zhaoliu"); session.getTransaction().commit(); }catch(Exception e){ e.printStackTrace(); } finally{ HibernateUtils.closeSession(session); } } Query to obtain the User object as shown in the figure below:
Analyzing the above figure, the obtained User object is not complete, or there is no common User object, but it is a proxy. It uses CGLIB to preload the object and is only truly created when using the object.
1.3 Get Vs load
Get and load methods are very important. They are often taken during interviews with Hibernate. The following is a comparison of the following two.
Similarities:
(1) The functions are the same, and the relationship data is converted into objects;
(2) The usage method is the same, and two differences in parameters are also required:
(1) The load method supports lazy operation, preloads the object, and is created only when used. Get directly converts relational data into objects;
(2) If the load load object does not exist, an objectNotFoundException will be thrown, and if the get does not get the data, it will return null.
2. Manually construct detached objects
There is another method to obtain an object. It is different from the get and load methods. It is a manual method. First, an object is common, and then the data of the object is obtained by formulating an id. The method is as follows:
public void testUer(){ Session session=null; try{ session=HibernateUtils.getSession(); session.beginTransaction(); //Manually construct detached objectUser user=new User(); user.setId("8a1b653745bcc7b50145bcc7b7b7140001"); // persistent state// object with persistent state, when the object's properties change // Hibernate will synchronize session.getTransaction().commit() with the database when cleaning the cache (dirty data check); }catch(Exception e){ e.printStackTrace(); } finally{ HibernateUtils.closeSession(session); } } View the obtained result diagram:
The analysis result diagram is used in the code to set the id number for the object. After the id number is formulated, the object can be operated. After the transaction is submitted, it is synchronized to the database, and manual specification is used to manually specify the object information.
2.1 Delete method
To delete the object specified in the database, the object must be converted to the Persistent state before deleting it. You can use get, load or manual methods to specify the object. The method is as follows:
session=HibernateUtils.getSession(); session.beginTransaction(); User user=(User)session.load(User.class,"8a1b653745bcc6d50145bcc6d67a0001"); //It is recommended to use this method to delete, load first and then delete session.delete(user);
2.2 Update
Update the data, this method will modify the data in the database. When using it, there will be a situation in the quantity, which will update the value of a certain field in the database or update the entire row of the database.
2.2.1 Update a field value
If you only want to update the value of a certain field, before updating, you need to use load or get to convert the object into a persistent status code as follows:
//Get session object session=HibernateUtils.getSession(); //Open transaction session.beginTransaction(); //Or you can use another method to enable //session.getTransaction().begin(); //Load to get User object//Method 1: Use load method//User user=(User)session.load(User.class, "8a1b653745bcc7b50145bcc7b7b7140001"); //Method 2: Manually obtain User user=new User(); user.setId("8a1b653745bcc7b50145bcc7b7b7140001"); //Update the name user.setName("zhangsan"); session.update(user); session.getTransaction().commit();2.2.2 Update the entire line <br />If you want to update the data of the entire line, you can manually convert the state to the detached state and manually specify the id value of the object. The code is as follows:
//Get session object session=HibernateUtils.getSession(); //Open transaction session.beginTransaction(); //Or can use another method to enable //session.getTransaction().begin(); //Manually get User user=new User(); user.setId("8a1b653745bcc7b50145bcc7b7b7140001"); //Update the name user.setName("zhangsan"); session.update(user); session.getTransaction().commit(); View update results:
Analyzing the update results, it actually updates the entire row of data in the database. There are too many uncertainties in this update operation and is not recommended to use it.
2.3 save method
Insert data. When executing the save method, the database insert statement is called to add a new row to the database. The saved object will be converted into persistent state. In this state, the object can update the object again and will be updated to the database with changes when the transaction is finally submitted. as follows:
public void testSave2(){ Session session=null; Transaction tx = null; try{ session=HibernateUtils.getSession(); //Open transaction tx= session.beginTransaction(); //Transient status User user=new User(); user.setName("zhangsi"); user.setPassword("123"); user.setCreateTime(new Date()); user.setExpireTime(new Date()); // persistent state// object with persistent state changes when the object's properties change // Hibernate will synchronize session.save(user); user.setName("lisi"); tx.commit(); }catch(Exception e){ e.printStackTrace(); if(tx != null){ tx.rollback(); } } finally{ HibernateUtils.closeSession(session); } //detached status} View the previous example run result view:
Analysis result: Session actually does two operations when submitting the transaction. Combined with the update process in the code, firstly, a new User object is added, and then a save operation is executed. It will call the insert statement, then a setName operation is done in the code, and the name is re-modified. However, it has not been synchronized to the database at this time but is in memory. At this time, there will be two states. We say that the data bits at this time are dirty data, and finally update to the database when submitting the transaction.