Home  >  Article  >  Backend Development  >  load and get in session

load and get in session

巴扎黑
巴扎黑Original
2016-12-20 17:13:581357browse

1. Get does not support lazy, load supports lazy.

2. Use get to load data. If there is no matching data, null will be returned, and load will throw an exception.

3. When executing load(), first check whether the current object exists from the Session. If it does not exist, query it from the database. If this record does not exist, an exception will be thrown; when executing get(), regardless of Whether the current object exists in the Session is directly queried from the database. If it does not exist, null is returned.

4. The load() method can return the proxy class instance of the entity, while get() always only returns the entity class.

get example:

1public void testGetMethod() {
2 Session session = null;
3 try {
4  session = HibernateUtils.getSession();
5  session.beginTransaction();
6   
7    //Right away Issue the query sql and load the User object
8  User user = (User)session.get(User.class, "402880d01b9bf210011b9bf2c2ff0002");
9  System.out.println("user.name=" + user.getName());
10   
11  user.setName("张三");
12  session.getTransaction().commit();
13  }catch(Exception e) {
14  e.printStackTrace();
15  .getTransaction() .rollback();
16 }finally {
17  HibernateUtils.closeSession(session);
18  }
19 }

PS: When executing the 8th line statement, if the database has relevant records, the sql statement will be issued immediately , even if there is no user.getName() method call in line 9, if there is no matching record, a null will be returned.

load method example:

1public void testLoadMethod() {
2 Session session = null;
3 try {
4  session = HibernateUtils.getSession();
5  session.beginTransaction();
6    
7   ///No Query sql will be issued because the load method implements lazy (lazy loading or lazy loading)
8   // Delayed loading: Only when this object is actually used, will it be loaded (sql statement issued)
9   //The implementation principle of hibernate lazy loading is Proxy method
10  User user = (User)session.load(User.class, "402880d01b9bf210011b9bf2b2ff0002");
11  System.out.println("user.name=" + user.getName());
12  user.setName ("李思");
13 session.getTransaction().commit();
14 }catch(Exception e) {
15 e.printStackTrace();
16 session.getTransaction().rollback();
17 }finally {
18   HibernateUtils.closeSession(session);
19  }
20 }

PS: The sql statement was not issued immediately when 10 lines of code were executed. Since load implements lazy lazy loading, lazy loading can only be used in real life. The object is loaded only when the object is loaded, and the sql statement is issued. The key is 11 lines of code. If the id in the load method is not related in the database table, an ObjectNotFoundException exception will be issued.

PS: You can set breakpoints and use debug to track changes in related variables and objects, so that you can clearly understand the load and get methods.

hibernate, the object from session load is

Persistent state: Objects establish corresponding relationships with database records and maintain synchronization. The object is bound to the persistence context, and any future state changes and data changes will be under the management of the work unit. This is the persistence state. Session.load is the default delayed loading method provided in hibernate3.2. I think what is loaded is a proxy, which can also be said to be persistent state (I understand it this way, please ask an expert to correct me if I am wrong).





Understanding lazy loading will help to understand lazy loading:

The lazy loading mechanism is proposed to avoid unnecessary performance overhead. The so-called lazy loading means that the data loading operation is only performed when the data is actually needed. Hibernate provides lazy loading of entity objects and lazy loading of collections. In addition, Hibernate3 also provides lazy loading of properties. Below we will introduce the details of these types of lazy loading respectively.

A. Lazy loading of entity objects:

If you want to use lazy loading for entity objects, you must configure it accordingly in the entity's mapping configuration file, as shown below:



< ;class name=”com.neusoft.entity.User” table=”user” lazy=”true”>

……





Enable the lazy loading feature of the entity by setting the lazy attribute of the class to true. If we run the following code:

User user=(User)session.load(User.class,”1”); (1)

System.out.println(user.getName()); (2)

When running to (1), Hibernate does not initiate a query for data. If we use some debugging tools (such as the Debug tool of JBuilder2005) to observe the memory snapshot of the user object at this time, we will be surprised to find that, What is returned at this time may be an object of type User$EnhancerByCGLIB$$bede8986, and its attribute is null. What is going on? Remember that I mentioned earlier that the session.load() method will return the proxy class object of the entity object. The object type returned here is the proxy class object of the User object. In Hibernate, CGLIB is used to dynamically construct a proxy class object of the target object, and the proxy class object contains all properties and methods of the target object, and all properties are assigned null. Through the memory snapshot displayed by the debugger, we can see that the real User object at this time is contained in the CGLIB$CALBACK_0.target attribute of the proxy object. When the code runs to (2), user.getName( is called at this time ) method, at this time, through the callback mechanism given by CGLIB, the CGLIB$CALBACK_0.getName() method is actually called. When calling this method, Hibernate will first check whether the CGLIB$CALBACK_0.target attribute is null. If it is not null, then Call the getName method of the target object. If it is empty, a database query will be initiated and a SQL statement similar to this is generated: select * from user where id='1'; to query the data, construct the target object, and assign it to CGLIB $CALBACK_0.target attribute.

In this way, through an intermediate proxy object, Hibernate implements lazy loading of entities. Only when the user actually initiates an action to obtain the attributes of the entity object, the database query operation will actually be initiated. Therefore, the lazy loading of entities is completed through the intermediate proxy class, so only the session.load() method will use the lazy loading of entities, because only the session.load() method will return the proxy class object of the entity class.

B. Delayed loading of collection types:

In Hibernate's delayed loading mechanism, the application of collection types is of the greatest significance, because it is possible to greatly improve performance, and Hibernate has done a lot of work for this purpose. Our efforts include the independent implementation of JDK Collection. In one-to-many relationships, the Set collection we define to accommodate the associated objects is not the java.util.Set type or its subtype, but net.sf. hibernate.collection.Set type, Hibernate implements lazy loading of collection types by using the implementation of custom collection classes. In order to use lazy loading for collection types, we must configure the association part of our entity class as follows:





…..













Enable the lazy loading feature of the collection type by setting the lazy attribute of the element to true. Let’s look at the following code:

User user=(User)session.load(User.class,”1”);

Collection addset=user.getAddresses(); (1)

Iterator it=addset.iterator( ); (2)

while(it.hasNext()){

Address address=(Address)it.next();

System.out.println(address.getAddress());

}

When the program executes to (1), the association will not be initiated at this time Data query is used to load related data. Only when it reaches (2), the real data reading operation will start. At this time, Hibernate will search for qualified entity objects based on the qualified data index in the cache.

Here we introduce a new concept - data index. Let's first take a look at what data index is. When caching a collection type in Hibernate, it is cached in two parts. First, the id list of all entities in the collection is cached, and then the entity objects are cached. The id list of these entity objects is the so-called data index. When searching for a data index, if the corresponding data index is not found, a select SQL will be executed to obtain qualified data, construct a collection of entity objects and a data index, then return a collection of entity objects, and add the entity object and data indexes into Hibernate's cache. On the other hand, if the corresponding data index is found, the id list is taken out from the data index, and then the corresponding entity is searched in the cache according to the id. If found, it is returned from the cache. If not found, a select SQL query is initiated. Here we see another problem that may have an impact on performance, which is the caching strategy of the collection type. If we configure the collection type as follows:





…..















Here we apply the configuration. If this strategy is used to configure the collection type, Hibernate will only The data index is cached, but the entity objects in the collection are not cached. As configured above, we run the following code:

User user=(User)session.load(User.class,”1”);

Collection addset=user.getAddresses();

Iterator it=addset.iterator() ; println("Second query...");

User user2=(User)session.load(User.class,"1");

Collection it2=user2.getAddresses();

while(it2.hasNext( )){

Address address2=(Address)it2.next();

System.out.println(address2.getAddress());

}

Run this code, you will get output similar to the following:

Select * from user where id='1';

Select * from address where user_id='1';

Select * from address where id='2';

Tianjin

Dalian

We see that when the query is executed for the second time, two query operations on the address table are executed. Why is this? This is because when the entity is loaded for the first time, according to the configuration of the collection type caching strategy, only the collection data index is cached, but the entity objects in the collection are not cached. Therefore, when the entity is loaded again for the second time, Hibernate found the data index of the corresponding entity, but based on the data index, it could not find the corresponding entity in the cache. Therefore, Hibernate initiated two select SQL query operations based on the found data index. This caused a waste of performance. How? How can we avoid this situation? We must also specify a caching strategy for the entities in the collection type, so we need to configure the collection type as follows:





…..















At this time, Hibernate will also cache the entities in the collection type. If you run the above code again according to this configuration, you will get output similar to the following:

Select * from user where id='1';

Select * from address where user_id='1';At this time, there will no longer be SQL statements to query based on the data index, because the entity objects stored in the collection type can be obtained directly from the cache.

C、 Property lazy loading:

In Hibernate3, a new feature is introduced - lazy loading of properties. This mechanism provides a powerful tool for obtaining high-performance queries. When we talked about reading big data objects earlier, there is a resume field in the User object. This field is a java.sql.Clob type and contains the user's resume information. When we load the object, we have to load it every time. This field must be loaded regardless of whether we really need it, and the reading of this large data object itself will bring a lot of performance overhead. In Hibernate2, we can only solve this problem by decomposing the User class through the granular segmentation of performance as we mentioned earlier (please refer to the discussion in that section), but in Hibernate3, we can use the attribute lazy loading mechanism , so that we can obtain the ability to read the data of this field only when we really need to operate this field. To do this, we must configure our entity class as follows:





……







Enable lazy loading of properties by setting true to the lazy attribute of the element. In order to implement lazy loading of properties in Hibernate3, a class enhancer is used To enhance the Class file of the entity class, through the enhancement of the enhancer, the callback mechanism logic of CGLIB is added to the entity class. Here we can see that the delayed loading of attributes is still implemented through CGLIB. CGLIB is an open source project of Apache. This class library can manipulate the bytecode of Java classes and dynamically construct class objects that meet the requirements based on the bytecode. Based on the above configuration, we run the following code:

String sql=”from User user where user.name='zx' ”;

Query query=session.createQuery(sql); (1)

List list=query .list();

for(int i=0;i
User user=(User)list.get(i);

System.out.println(user. getName());

System.out.println(user.getResume()); (2)

}

When execution reaches (1), a SQL statement similar to the following will be generated:

Select id, age,name from user where name='zx';

At this time, Hibernate will retrieve the field data corresponding to all non-lazy loading attributes in the User entity. When executing (2), a SQL statement similar to the following will be generated:

Select resume from user where id='1';



1. Loading a non-existent record
Employee employee2 = (Employee) session.load(Employee.class, new Integer(100));
will throw net.sf.hibernate.ObjectNotFoundException.
If you don’t want to throw this Exception, you should use session.get(Class clazz, Serializable id);

2. Load a record that exists in the database
1) If it exists in the session’s Cache, then return the reference directly.
Session session = HibernateSessionFactory.currentSession();
Transaction tx = session.beginTransaction();
Employee employee1 = new Employee();
employee1.setAge((byte)10);
employee1.setBirthDay(new Date()) ;
employee1.setEmployeeName("HairRoot");
employee1.setGender('m');
employee1.setMarried(false);
session.save(employee1);
System.out.println(employee1);

/ /employ1 has been saved
Employee employee2 = (Employee) session.load(Employee.class, new Integer(/*employee1.getId()*/100));
System.out.println(employee2);
tx.commit ();
session.close();

You can find that employee1 and employee2 are the same reference. When you turn on show_sql=true, you will also find that hibernate does not send a select statement to the database.

2) If the session does not exist in the Cache, a select will be sent immediately.
Session session = HibernateSessionFactory.currentSession();
Transaction tx = session.beginTransaction();
Employee employee = (Employee) session.load(Employee.class, new Integer(100));
System.out.println(employee );
tx.commit();
session.close();

Backend:Hibernate: select employee0_.id as id0_, employee0_.age as age0_, employee0_.birthDay as birthDay0_, employee0_.employeeName as employee4_0_, employee0_.gender as gender0_, employee0_.married as married0_ from MWS_TEST_EMPLOYEE employee0_ where employee0_.id=?



At this time, the actual reading operation of the resume field data will be initiated.


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn