Hibernate performance optimization-lazy loading (lazy loading)
Implemented through two packages, asm and cglib
1. When session.load (), the system does not directly access the database, but instead creates a proxy object through new (the proxy object will not be empty and cannot be determined).
Proxy Object Restriction: Cannot be used until the session associated with the proxy is closed
User.getname () or user.getBirthday () and the initialization method Hibernate.initialize (user), hibernate will only access the database, and the select statement will be output
User.getClass () and user.getId () do not access the database
public static User getUser (int id) {
Session session = null;
try {
session = HibernateUtil.getSession ();
Class clazz = User.class;
// Useruser = (User) session.get (clazz, id);
User user = (User) session.load (clazz, id);
System.out.println (user.getClass ());
//user.getBirthday ();
Hibernate.initialize (user);
// --- persistent state
return user;
} finally {
if (session! = null)
session.close ();
}
2. There is an association between objects
(1) One-to-one relationship
Three conditions must be met to achieve lazy loading
1) Lazy! = False 2) constrained = ”true” 3) fetch = select
When we queried the main object, we made an outer join between person and idcard, and queried person and idcard. No lazy loading. (Because the main table cannot have constrained = true, the main table is not lazy loaded)
static Person query (int id) {
Session s = null;
Transaction tx = null;
try {
s = HibernateUtil.getSession ();
tx = s.beginTransaction ();
//Inquire
IdCard idCard = null;
Person p = (Person) s.get (Person.class, id); // Check that the main object is not lazy loaded
tx.commit ();
return p;
} finally {
if (s! = null)
s.close ();
}
}
When querying the slave object, the person object associated with idcard is lazy loaded.
static IdCard query (int id) {
Session s = null;
Transaction tx = null;
try {
s = HibernateUtil.getSession ();
tx = s.beginTransaction ();
//Inquire
IdCard idCard = (IdCard) s.get (IdCard.class, id);
Hibernate.initialize (idCard.getPerson ());
tx.commit ();
return idCard;
} finally {
if (s! = null)
s.close ();
}
}
(2) One-to-many
1) lazy! = False 2) fetch = select
(3) Many to one
1) lazy! = False 2) fetch = select
(4) Many-to-many
1) lazy! = False 2) fetch = select
Lazy: refers to when the associated attributes are fetched
Fetch: What method is used to fetch select secondary select statement query Join join query, the lazy attribute does not work
Crawl strategy
The fetch strategy directly affects the execution efficiency of the session's get () or load () method. There are two main situations
1. Crawling strategies on single-ended associations (<many-to-one>, <one-to-one>)
Fetch attributes can be added to single-ended associated mapping elements. Fetch property may have two values
Select: As the default, its strategy is to send a separate select statement to grab the data of the associated object of the current object when the data of the associated object is needed. That is, lazy loading.
Join: Its strategy is to use inner join in the same select statement to obtain the data of the object and its associated objects. At this time, the lazy loading of the associated objects fails.
2.Fetching strategy on collection attributes
The fetch attribute can be added to the mapping element of the collection attribute, which has three optional values.
Select: As the default value, its strategy is to send a separate select statement to grab the current object's associated collection when it needs to use the data of the associated collection, that is, lazy loading.
Join: Use inner join in the same select statement to obtain the associated set of objects. At this time, the lazy on the associated set will fail.
Subselect: Send another query (or subquery) to grab the association set of all entity objects that were previously queried. This strategy also works for HQL queries.
Turn off lazy loading
Lazy loading does bring benefits to the query efficiency of the program, but sometimes it is clear that the data needs to be loaded immediately. If Hibernate first uses lazy loading by default, and then has to go to the database to load, it will reduce efficiency. Therefore, you need to flexibly control whether to use lazy loading according to the actual situation of the application. In Hibernate, you only need to modify the corresponding configuration to enable or disable the function of lazy loading.
1. When loading a single entity, if you don't need lazy loading, you can use the session's get () method.
2. When the session loads an entity, there is no need to delay loading the collection attribute values in this entity, but to load immediately. At this time, you can add the attribute lazy = false to the configuration elements (<set>, <bag>, <list> ...) of the collection in the mapping file.
3. When the session loads an entity, there is no need to delay the loading of another entity object associated with the single-end of this entity, you can target the configuration element (<ont-to-one>, <many-to-one>) Add the attribute lazy = false.