Object state
Status of objects in Hibernate:
- Temporary/transient status
- Persistent state
- Free State
Learning Hibernate's object state is to better understand Hibernate's design ideas, and is the basis of a first-level cache ... Of course, it's a little bit of knowledge.
Temporary/transient status
When we come directly to the new object is the temporary/instantaneous state .
- The object has not been persisted "not saved in the database"
- Not subject to session management
Persistent state
When the object that is saved in the database is persisted
- The object is persisted when calling the Save/saveorupdate/get/load/list method of the session.
- have corresponding data in the database
- Managed by the session
- When you make changes to an object's properties, it is reflected in the database!
Let's test it: when the object property is changed, it is reflected in the database!
session.save(idCard); idCard.setIdCardName("我是测试持久化对象");
Free State
When the session is closed, the persisted object becomes free ...
- Management that is not in session
- There are corresponding records in the database
First-level caching
Hibernate has a first-level cache and a level two cache, which focuses on the first level of caching
What is a first-level cache?
The hibenate cache, also called session cache, can reduce the number of database accesses within the session range! Only valid in session range! Session closed, first-level cache failed!
As long as the state of the persisted objects are managed by the session, that is, in the session cache!
The session cache is maintained by hibernate, the user cannot manipulate the cached content, and if you want to manipulate the cache content, you must do so through the Evit/clear method provided by Hibernate .
Why use caching?
Reduce the number of accesses to the database! To improve hibernate execution efficiency!
Test
Let's take a look at how hibernate reduces the number of database accesses.
Now my user table has such a record:
//把数据放进cache User user = (User) session.get(User.class1); //发现要修改的字段和cache一样,不执行 user.setUserName("你好2");
The same is true for data fetching.
null; user = (User) session.get(User.class1); user = (User) session.get(User.class1);
Caching-related methods
There are three common methods associated with caching:
null; user = (User) session.get(User.class1); //清除缓存,那么下面获取的时候,就不能从缓存里面拿了 session.clear(); user = (User) session.get(User.class1);
In the case of a cache, modify the data of the same record, whichever is the last ... So there's only one update
null; user = (User) session.get(User.class1); user.setUserName("我是第一"); user = (User) session.get(User.class1); user.setUserName("我是第二");
I let it be forced to synchronize with the database, there are two update
null; user = (User) session.get(User.class1); user.setUserName("我是第一"); session.flush(); user = (User) session.get(User.class1); user.setUserName("我是第二");
In general, we will use the batch process , because the cache is also size, if 1000 of data are inserted into the cache, then hibernate may be collapsed ...
- Synchronize flush () with database at every certain number of records
- Then empty the cache clear ()
It is important to note that different sessions do not share the cache!
Iterator and List
When we use HQL to query all the data, we can use list () to get all the data, or we can use iterator () to get an iterator, and then traverse the iterator ... What difference do they have?
。。。。 When I watched the video, I said:
But I was in the test:list can also get cached data
Of course, iterator is also able to get cached data
Therefore, it is convenient to use list () when getting data.
Lazy Loading
lazy Loading is when the data is used to get the data, execute the corresponding SQL statement ... when the data is not used, it does not load the corresponding data!
The main purpose is to improve hibernate performance and improve execution efficiency !
- Get: Load in a timely manner, just call the Get method to query the database immediately
- Load: Lazy loading is used by default and queries to the database when data is used.
Lazy Loading re-experience
User user = (User) session.load(User.class1); System.out.println("________"); System.out.println(user);
We can set the corresponding configuration file with the usual lazy property
To turn off lazy loading:
<class name="IdCard" table="IdCard" lazy="false">
There are three properties of lazy:
- True Use lazy loading
- False off Lazy loading
- Extra (improves efficiency when lazy loading of collection data) "is only used in set, list, and other collection tags"
- SQL that sends queries to the database when the data is actually used;
- If you call the collection of the size ()/isempty () method, just statistics, do not really query the data!
Lazy Loading exception
When the session is closed, you cannot use lazy loading, or you will report an exception
"main" org.hibernate.LazyInitializationException: could not initialize proxy - no Session
Reported this anomaly, we have 4 ways to solve:
- Mode 1: Use the data first
- Mode 2: Force proxy object Initialization
- Hibernate.initialize (dept);
- Mode 3: Turn off lazy loading
- Mode 4: After using the data, then close the session!
Hibernate level Two Cache
We have already explained the first level cache, the cache is the session cache, only within the scope of the session is valid ... The action time is in the scope of the session, the range is relatively small
Hibernate provides us with a level two cache feature: The level two cache is application-based caching, and all sessions can be used
- Hibernate provides a two level cache with a default implementation and is a pluggable caching framework ! If the user wants to use a level two cache, it needs only to be configured in Hibernate.cfg.xml , not to be removed directly, without affecting the code.
- If the user feels that Hibernate provides a framework that is not good enough, you can switch to another cache framework or implement your own caching framework .
Hibernate level Two cache: commonly used classes are stored
Configuring Level Two Caching
Now that the level two cache is hibernate, we can find the corresponding information in the Hibernate.properties file .
- Hibernate.cache.use_second_level_cache false "level two cache is not turned on by default and needs to be turned on manually"
- Hibernate.cache.use_query_cache true "Open query Cache"
- Choose a cache implementation "two-level caching framework Implementation"
- Hibernate.cache.provider_class Org.hibernate.cache.EhCacheProvider
- Hibernate.cache.provider_class Org.hibernate.cache.EmptyCacheProvider
- Hibernate.cache.provider_class Org.hibernate.cache.HashtableCacheProvider Default implementation
- Hibernate.cache.provider_class Org.hibernate.cache.TreeCacheProvider
- Hibernate.cache.provider_class Org.hibernate.cache.OSCacheProvider
- Hibernate.cache.provider_class Org.hibernate.cache.SwarmCacheProvider
Through the configuration file we can find that the level two cache is not open by default, we need to manually open the following steps:
- 1) Turn on level two cache
- 2) Specify the caching framework
- 3) Specify which classes are added to level two cache
turn on level two caching
Turn on level two caching in the Hibernate.cfg.xml file
<!-- a. 开启二级缓存 --> <property name="hibernate.cache.use_second_level_cache">true</property>
specifying the cache framework
Specify the two-level cache framework that hibernate comes with.
<!-- b. 指定使用哪一个缓存框架(默认提供的) --> <property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
specify which classes are added to level two cache
<!-- c. 指定哪一些类,需要加入二级缓存 --> <class-cache usage="read-write" class="zhongfucheng.aa.Monkey"/> <class-cache usage="read-only" class="zhongfucheng.aa.Cat"/>
Test :
We know that the primary cache is the session cache, then we test the level two cache with two sessions. If the second session gets the cached data, then it proves that the level two cache is useful.
Package Zhongfucheng.aa;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.classic.Session; Public classAPP5 { Public Static void Main(string[] args) {//Get load Configuration management classConfiguration Configuration =NewConfiguration ();//Load the mapping file for the class! Configuration.Configure().AddClass(Animal.class);//Create Session factory objectSessionfactory factory = Configuration.buildsessionfactory();//Get Session ObjectSession Session1 = Factory.opensession();//using Hibernate to operate the database, open the transaction to get the transaction objectTransaction Transaction = Session1.gettransaction();//Open transactionTransaction.begin(); Monkey Monkey = (Monkey) session1.Get(Monkey.class,"40283f815be67f42015be67f43240001"); System. out.println(Monkey.GetName()); System. out.println("-----------------------"); Session Session2 = Factory.opensession(); Transaction Transaction2 = Session2.gettransaction(); Transaction2.begin(); Monkey Monkey2 = (Monkey) session1.Get(Monkey.class,"40283f815be67f42015be67f43240001"); System. out.println(Monkey2.GetName());//Commit a transactionTransaction.Commit(); Transaction2.Commit();//Close SessionSession1.Close(); Session2.Close(); }}
Get the cache data!
Caching policies
When we put the animal class in the level two cache, the usage is read-only
That is, it can only be read, not written, let's see what happens to the write:
monkey2.setName("小猴子");
Throws an exception ....
There are 4 types of usage properties:
<class-cache usage="read-only"/>Put the two-level cache object, read-only;
<class-cache usage="nonstrict-read-write"/>Non-strict reading and writing
<class-cache usage="read-write"/>Read and write the objects that are placed in level two cache;
<class-cache usage="transactional"/>(Transaction-based policy)
Collection Cache
If the data we query in the database is a collection ... hibernate defaults to not set level two cache for collection data ... So you still need to read and write information about the database.
Next, let's look at what it does to set the collection to a level two cache:
- The collection in the configuration object in Hibernate.cgf.xml is a level two cache
<!-- 集合缓存[集合缓存的元素对象,也加加入二级缓存] --> <collection-cache usage="read-write" collection="cn.itcast.b_second_cache.Dept.emps"/>
Public void Testcache() {Session session1 = sf.opensession(); Session1.BeginTransaction();//A. Query onceDept Dept = (Dept) session1.Get(Dept.class,Ten); Dept.Getemps().size();//CollectionSession1.gettransaction().Commit(); Session1.Close(); System. out.println("------");//second sessionSession session2 = sf.opensession(); Session2.BeginTransaction();//A. Query onceDept = (Dept) session2.Get(Dept.class,Ten);///Two-level cache configuration OK; database is not queried hereDept.Getemps().size(); Session2.gettransaction().Commit(); Session2.Close(); }
Query cache
List () and iterator () will place the data in a first-level cache, but the first-level cache is only valid in the scope of the session ... set the query cache if you want to use it across sessions
We also see in the configuration file that the query cache is such a configuration :
#hibernate.cache.use_query_cache true 【开启查询缓存】
In other words, the default query data is not placed in the level two cache , if we want to put the queried data into the level two cache, we need to open in the configuration file
<!-- 开启查询缓存 --> <property name="hibernate.cache.use_query_cache">true</property>
- When you use a program query, you also call the Setcacheable () method, which is set to query caching.
@Test Public void Listcache() {Session session1 = sf.opensession(); Session1.BeginTransaction();//HQL query "setcacheable Specifies to be found from a level two cache, or into a level two cache"Query q = session1.CreateQuery("from Dept").setcacheable(true); System. out.println(Q.List()); Session1.gettransaction().Commit(); Session1.Close(); Session session2 = sf.opensession(); Session2.BeginTransaction(); Q = session2.CreateQuery("from Dept").setcacheable(true); System. out.println(Q.List());//Do not query database: Need to open query cacheSession2.gettransaction().Commit(); Session2.Close(); }
If the article is wrong, welcome to correct, we communicate with each other. Accustomed to look at technical articles, want to get more Java resources of students, can pay attention to the public number: Java3y
Hibernate "Caching" knowledge essentials