SessionFactory level 2 cache is global cache, it can be used under different caching libraries, such as ehcache, oscache and so on, need to set up hibernate.cache.provider_class, we here ehcache, is at 2.1
hibernate.cache.provider_class = net.sf.hibernate.cache.EhCacheProvider
If you use the query cache, coupled with
hibernate.cache.use_query_cache = true
Cache can be simple as a Map, through the key cache inside look at value.
Class Cache
For a record is a PO, it is in accordance with ID come in, is key cache ID, value is a POJO. Whatever list, load, or iterate, as long as the read out an object, it will fill the cache. But the list does not use cache, and iterate the database will first select id check out, then id a id of a load, if there are in the cache from a cache access, not go to the database load. The assumption that the read and write cache settings required:
<cache usage="read-write"/>
If you use a secondary cache ehcache implementation is then required to configure ehcache.xml
<cache name="com.xxx.pojo.Foo" maxElementsInMemory="500" eternal="false" timeToLiveSeconds="7200" timeToIdleSeconds="3600" overflowToDisk="true" />
Express one of the cache are not eternal and will never timeout, timeToLiveSeconds is cached for each element (here is a POJO) overtime hours, if the eternal = "false", over a specified period of time, this element was removed a. trance are timeToIdleSeconds time, is optional. When put to the cache inside the more than 500 elements, if overflowToDisk = "true", will put part of the data cache stored in temporary files on your hard disk inside.
Required for each cache configuration class should do. If you do not have to configure, hibernate will warn you when to start, then use defaultCache configuration, this class will share a number of configurations.
When an ID through hibernate changes, hibernate will know, so remove the cache.
So everyone may think, the same query, first the first list, the second re-iterate, you can use to cache the. This is in fact very difficult, because you can not judge what is the first time, but the conditions of each inquiry is not always the same, if the database has 100 records, id from 1 to 100, when the first list of the previous 50 id, when the second iterate has inquiries No. 30-70 to id, then 30-50 are taken from a cache inside, and 51-70 are taken from the database, a total of 1 +20 article Send sql. So I have always thought that iterate Nothing, and always will be the 1 + N problem.
(Off-topic: Say that there is large-scale inquiry will list the entire result set into memory, very slow, and iterate only select id better, but large-scale inquiry always check the pagination, no one would really put the whole The results assembled in, if a 20, then, iterate the need to implement a total of 21 statements, list a number of fields although the selection than the first iterate statement select id slower, but there is only one statement, not the entire result set into hibernate also Does the database dialect based on optimization, such as the use of mysql the limit, the whole list should be faster still.)
If you want to iterate on the list or the results of inquiries in the cache, it is necessary to use a query cache
Query cache
First of all required configuration hibernate.cache.use_query_cache = true
If you use ehcache, configuration ehcache.xml, attention hibernate3.0 not net.sf after the package names of the
<cache name = "net.sf.hibernate.cache.StandardQueryCache"
maxElementsInMemory = "50" eternal = "false" timeToIdleSeconds = "3600"
timeToLiveSeconds = "7200" overflowToDisk = "true" />
<cache name = "net.sf.hibernate.cache.UpdateTimestampsCache"
maxElementsInMemory = "5000" eternal = "true" overflowToDisk = "true" />
And
query.setCacheable (true); / / activate the query cache
query.setCacheRegion ( "myCacheRegion ");// designated to be used cacheRegion, optional
The second line specifies to use cacheRegion are myCacheRegion, that is, you can give each query to do a separate cache configuration, use the designated setCacheRegion do need to configure it inside ehcache.xml:
<cache name="myCacheRegion" maxElementsInMemory="10" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="7200" overflowToDisk="true" />
If you omit the second line, do not set cacheRegion, then use the above-mentioned standard query cache configuration, which is net.sf.hibernate.cache.StandardQueryCache
For query cache, the cache key is generated in accordance with HQL sql, coupled with the parameters, such as pagination information (through the log output to see, but its output is not very readable, it is best to check it out code).
For instance hql:
from Cat c where c.name like?
Generated along the following sql:
select * from cat c where c.name like?
Parameter is the "tiger%", then the query cache key * around * is this kind of string (I am writing from memory are not precise, but also the read to understand):
select * from cat c where c.name like?, parameter: tiger%
In this way, guarantees the same query, the same parameters under the condition with the same key.
Now talk about the cached value, if yes, then list the way, value is not here at the entire result set, but this string of inquiries by the ID. In other words, whether it is list or Ways iterate method, when the first query, which query the way is the way they usually are the same, list the implementation of a sql, iterate the implementation of 1 + N article, by the many acts that they are filled the cache. However, the same conditions when the second query, and iterate on all the same behavior, according to the key cache to cache found inside the value, value is a string of id, then the cache at the class go inside one by one the load out. This is done to save memory.
Can be seen, query cache related need to open the class cache. list and the first iterate method of execution when both are filled query cache also filled class cache.
Here have a very easily be overlooked important question, namely, to open after the query cache, even if the list methods are also likely to be encountered the problem of 1 + N! The same conditions when the first list, because query cache can not be found, regardless of the existence of class caching data, always send a sql statement to the database to obtain all the data query cache and then populate the cache class. However, when the second performance, the problem comes, if your class cache timeout relatively short, and now cache all overtime class, but also query cache, then the list method in the future to obtain id string will go the database one by one load! Therefore, class cache timeout must not be shorter than the query cache timeout settings! If you have set up a daze time, to ensure that class time trance cached query cache is greater than the survival time. Here have other circumstances, such as class cache evict a compulsory procedure, which took note of on your own.
In addition, if HQL select query contains everything, then the query cache is inside the value of the entire result set.
When hibernate update the database, it knows how to update query cache does what?
hibernate in a place the maintenance of each table was last updated, in fact, that is, on the above specified net.sf.hibernate.cache.UpdateTimestampsCache cache configuration inside.
When the time passed hibernate update, hibernate will know what the impact of the updated table. And it is to update these tables were last updated. Each cache has a generation time and the cache of the query table, when the hibernate query whether the existence of a cache, if cache exist, it would also like to remove the cache and the cache generated by the query table, then go search the tables of the last update time, and if there is a table generated at time updated, then the cache are invalid.
As can be seen, as long as the updated a table, then anything related to this table query cache on failure, so the query cache hit rate may be relatively low.
Collection Cache
HBM required at the collection inside the set
<cache usage="read-write"/>
If the class is the Cat, collection called children, then there ehcache configuration
<cache name = "com.xxx.pojo.Cat.children"
maxElementsInMemory = "20" eternal = "false" timeToIdleSeconds = "3600" timeToLiveSeconds = "7200"
overflowToDisk = "true" />
Collection of the cache and query cache in front of the list, as is only to maintain a string of id, but it will not be updated because of the table on the failure, a collection cache only at the elements inside the collection has added to and deleted when expired.
So there is a problem, if your collection is based on a field sort, when one of an element to update the field, resulting in the order of changes, collection cache inside the order did not make updates.
Cache strategy
Read-only cache (read-only): Nothing to say the
Read / write cache (read-write): the procedure may have to update data
Not a strict read / write cache (nonstrict-read-write): the need to update the data, but two affairs update records with the possibility of a small, good performance than to read and write cache
Services cache (transactional): cache support services, when an exception occurs, the cache also be able to rollback only jta Supporting the environment, this I have not studied how
Read and write cache and read-write cache is not strictly on the difference in implementation lies in the fact that read and write cache will update the cache when the data into the cache inside a lock, if other matters to fetch the corresponding cache data and found that was locked, and then on the direct access to database query.
Hibernate2.1 at the ehcache implementation, if the locked part of the affairs of the cache unusual happened, then the cache will always be locked until after 60 seconds of overtime.
Not strictly locked to read and write cache does not cache data.
The use of the secondary cache of pre-conditions
Hibernate your procedures on the database has exclusive write access to other process updates the database, hibernate is impossible to know. Necessary to operate your database directly through hibernate, if you call the stored procedure, or for their own use jdbc update the database, hibernate is not aware of this. hibernate3.0 bulk update and delete the secondary cache are not updated, but 3.1 is said to have resolved the problem.
This limit quite difficult to do sometimes hibernate batch update, delete very slow, but you can not write it to optimize jdbc very郁闷吧.
SessionFactory also provided a way to remove the cache, you must have to write some JDBC, you can call these methods to remove the cache, these methods are:
void evict (Class persistentClass)
Evict all entries from the second-level cache.
void evict (Class persistentClass, Serializable id)
Evict an entry from the second-level cache.
void evictCollection (String roleName)
Evict all entries from the second-level cache.
void evictCollection (String roleName, Serializable id)
Evict an entry from the second-level cache.
void evictQueries ()
Evict any query result sets cached in the default query cache region.
void evictQueries (String cacheRegion)
Evict any query result sets cached in the named query cache region.
However, I do not propose to do, because it hard to maintain. For instance you are using JDBC batch update a certain table has three query cache will use this table, using evictQueries (String cacheRegion) Remove the three query cache, and then evict (Class persistentClass) remove the class cache , looks like complete. But day you add a related query cache, you may forget to update to remove the code here. If your jdbc code everywhere, you add a query at a time when the cache, but also know what other places should also be corresponding changes to it?
Summary:
Not to take it for granted that the cache will certainly be able to improve performance, only you can control it and the conditions appropriate circumstances is the case. secondary cache hibernate or more restrictions, inconvenient to use jdbc may greatly reduce the update performance. Do not understand the principle in the case of misuse, there may be a 1 + N problem. Improper use can also lead to read the dirty data.
If you can not stand the hibernate many restrictions, then in the application or its own level of cache to do on it.
At the higher level cache to do, the effect will be better. Even though there is just like a disk cache, the database is to achieve its own cache, even though there is a database cache, let's do the application or the cache. Since the bottom of the cache it does not know what high-level use of these data can only make the more generic, and may have targeted high-level cache implementation, so at a higher level cache up to do, the effect should be better now .







