Hibernate uses cache (level 1, level 2, and query) to improve system performance and hibernate system performance

Source: Internet
Author: User

Hibernate uses cache (level 1, level 2, and query) to improve system performance and hibernate system performance
In hibernate, we usually use three types of caches: level-1 cache, level-2 cache, and query cache. Below we will analyze the usage of these three caches in the project, as well as their advantages and disadvantages.

The function of caching is to improve the performance of the system. data between the application system and the database exists in the memory or disk.

The programming mode is usually the page --> filter --> action --> server --> dao --> db, which can be added to the cache at any point in the request process, in the previous article, we introduced adding cache at the server layer: service uses aop to add cache.

Add cache for pages: Add cache for pages

First, let's take a look at the level 1 cache which is enabled by default and is very common.


Level 1 Cache


The same cache can often have several names. This is the result from different perspectives. From the perspective of the cache lifecycle, a level-1 cache can also be called: sessin cache, thread-level cache, and transaction-level cache. In our programming, the three concepts of thread, transaction, and session are bound together and put into threadlocal. At the same time, when the thread is enabled and disabled, that is, the same life and death are also called request-per-session-transaction programming;
When the session is closed, the cached objects will be lost. That is to say, the cached data in two different sessions is different, and the cached data cannot be accessed across sessions.

Cached data type

Objects are cached in the first-level cache. session cache is queried first when you use the get (), load (), and iterate () query methods, if an object exists, it is retrieved from the cache. if the object is not in the cache, It is queried in the database.
Load () test: The test notes must be in the same transaction. When I test the session managed by Spring, I call load () twice and always query twice to issue two SQL statements, I thought session-level cache didn't work. It turned out that after hibernate integrated spring, transactions and sessions were all managed by spring, and the first-level Sessions of the transaction before and after each call were automatically opened and closed, so I could not control the intermediate process myself, so removing spring from the original hibernate session, and manually developing and closing the transaction can ensure that the operation method in the same session and transaction is indeed sending an SQL statement, see the following code:
Load (), get () method:

    @Test    public void testLoad()    {        Session session=sf.openSession();        session.beginTransaction();                Category category1=(Category)session.load(Category.class,1);        Category category2=(Category)session.load(Category.class,1);        System.out.println(category1);        System.out.println(category2);                session.getTransaction().commit();        session.close();    }


Result
Hibernate: select category0_.id as id0_0_, category0_.name as name0_0_ from Category category0_ where category0_.id=?hibernate.Category@10efd7chibernate.Category@10efd7c


The result not only sends a statement, but also prints out the two objects.
When load () and get () are queried for the first time, an SQL statement is issued to query from the database table. When the second query is performed, the SQL statement is queried in the cache. If no update or modification is performed, the data will be read from the cache; otherwise, the database will be queried.
Save Method
@ Test public void testGet () {Session session = sf. openSession (); session. beginTransaction (); Category category1 = new Category (); category1.setName ("news"); session. save (category1); Category category2 = (Category) session. load (Category. class, category1.getId (); System. out. println (category2.getName (); session. getTransaction (). commit (); session. close ();}

Save also supports caching. When the save method is executed, a piece of data is first added to the session cache and updated to the database only when the transaction is committed or the cache is refreshed, from the execution process above, we can see that only one insert statement is issued and no query statement is issued, because the second query is made from the cache.

PS: After saving, run get or load to know the Object ID. After the save method is executed, although there is no data in the database, the Object ID has been generated and can be queried through this ID.

Batch insert data

When you insert data in batches, insert a part of data each time. For example, insert 20 data records at a time without one insert.

public void testInserBatch() {Session session = sf.openSession();session.beginTransaction();for(int i=0; i<1000; i++) {Category c = new Category();c.setName("test" + i);session.save(c);if (i%20==0) {session.flush();}}session.getTransaction().commit();session.close();}

Cache is cleared every time 20 data entries are cleared, and session is called every time cache is cleared. the flush () method will issue 20 insert statements, but there is no data in the database and so on, transactions are of the same level as sessions. Therefore, you must control transactions in a unified manner.


Hibernate N + 1

In Hibernate, set and other sets are often used to represent a one-to-many relationship. In our iron Community Project, when you obtain an object, you can retrieve the associated object or object set based on the link. You can also set cacade to update and delete the object Association. It must be said that the hibernate orm is doing well and is very close to oo's usage habits.

However, performance issues must still be considered for database access. After a one-to-many relationship is set, the legendary n + 1 issue may occur in queries.

One-to-multiple: If n objects are found on one side, n objects need to be retrieved from the set associated with n objects. Therefore, the original SQL query is changed to n + 1;

Multiple-to-one: if m objects are obtained from multiple queries, the one-party objects corresponding to m objects are also taken out and changed to m + 1;

Solution:

1. Using fetch capture, Hibernate capture policies are divided into single-ended proxy and collection proxy crawling policies.

Hibernate crawling Policy (single-ended proxy crawling policy ):

Keep the default value as follows:

<Subtitle-to-one name = "clazz" cascade = "save-update" fetch = "select"/>

Fetch = "select" means another select statement is sent to capture the object associated with the current object or set fetch = "join"

<Subtitle-to-one name = "clazz" cascade = "save-update" fetch = "join"/>

Hibernate uses the select statement to use external connections to attach the object to a live set. In this case, lazy becomes invalid.

Hibernate crawling Policy (Collection proxy crawling policy ):

Keep the default value (fetch = "select") as follows:

<Set name = "students" inverse = "true">

<Key column = "clazz"/>

<One-to-learn class = "com. June. hibernate. Student"/>

</Set>

1) fetch = "select" will issue another statement to query the set

2) set the lazy of the Outer join set for fetch = "join" to fail.

3) This fetch = "subselect" issue another select statement to capture the association set fetch of all the object objects previously queried. If fetch only affects HQL queries, it will not


OpenSessionInview

This problem occurs due to the lazy loading of load (). When querying data for the first time, the lazy loading is used to the ID of the queried data, when using data, you still need to query data in the database, but the session of the database has been closed. There are two ways to solve this problem: Do not use lazy loading; the second is to disable the session at the web layer and prolong the session lifecycle.


Level 2 Cache


The second-level cache is also called the process-level cache or sessionFactory cache, or the cache within the cluster. It needs to be implemented by a third party. The default second-level cache plug-in of hibernate is the ehcache cache, because the second-level cache is a process-level concurrency problem that may occur in multiple threads, you need to set a cache concurrency policy.

Hibernate second-level cache requires third-party plug-ins. hibernate supports ehcache by default. For details about the configuration, see Spring AOP + EHcache to add cache for the Service layer method.


Impact of enabling second-level cache on Methods

Get ()/load ()

There is no impact on the two methods. The first query is from the database, and the second query is to determine whether there is any data in the cache. If not, the query is performed in the database.


Query Cache


The query cache is the cache for the result set of common attributes. Entity objects are not cached. When the table associated with the query cache is modified, the query cache lifecycle ends, the data is cleared immediately.

Query cache configuration and usage:
The List method reads and writes the query cache. Iterator does not use the query cache (the query cache is only valid for query. list)

Query the cache configuration. The hibernate3 configuration is disabled by default:

  <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>  <property name="hibernate.cache.use_second_level_cache">false</property>         <property name="hibernate.cache.use_query_cache">true</property>  

Add a sentence to the code
query.setCacheable(true)


Relationship between Level 1, level 2, and query


The first-level cache is always enabled. We need to focus on the query cache and the second-level cache. The query cache can be enabled only one or two.
When the second-level cache is enabled, if the two sessions execute the load or get method successively, only one statement is executed for the second time and will be searched from the cache, first from the first level cache, if it is not found in the second-level cache.

Level 1 cache interaction with Level 2 Cache

Disable interaction between a level-1 cache and a level-2 cache.

Session. setCacheMode (CacheMode. IGNORE );
When a session is opened to execute the query, it first saves the query results to the first-level cache. After the session is closed, data in the first-level cache is cleared. Because the first-level cache and second-level cache data interaction are prohibited, therefore, after the first-level cache is disabled, the structure is not saved to the second-level cache. After the second session is opened, a query statement is sent. Therefore, there is no data in the second-level cache.


Query cache and second-level cache


Enable query and disable Level 2
If the query is executed twice. list (), the first time the query statement is sent, the result object id will be saved to the query cache, the second time the ID will be taken from the query cache, according to the id first level cache to find, second-level cache. If it is not found, it will be searched in the database. The first-level cache is irrelevant to the session and only to the table.

Enable query and second-level cache

Run query. list () twice. The first time you send the query statement


Summary:

Caching is very important for improving system performance in a project. Besides ehcache, memcache, redis, and other cache products are commonly used. redis has a wide range of data types and high-performance single-thread access efficiency, although memcache is multi-threaded, its efficiency is not as high as that of redis.

These cache products can achieve distributed cache, and ehcache + rmi can synchronize distributed cache; memcache + redis support distributed, redis also provides a high availability solution: master-slave replication several servers directly love you and you can switch between them.


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.