EhCache is one of Hibernate's second-level cache technologies. It can store the queried data in memory or disk, saving the need to query the database again with the same query statement next time, greatly reducing the database pressure;
EhCache usage notes
When you use Hibernate to modify table data (save, update, delete, and so on), EhCache will automatically delete all the caches related to this table (this can achieve synchronization ). However, for tables that frequently modify data, the significance of caching may be lost (the database pressure cannot be reduced );
When table data is updated less, EhCache generally uses tables with less write operations (including update, insert, and delete) [This is also the case for Hibernate's second-level cache]; when the concurrency requirements are not very strict, the cache in the two machines cannot be synchronized in real time;
Add the following configuration in the hibernate. cfg. xml configuration file:
[Html]
Add the following content to the mapping tag in Hibernate. cfg. xml:
<! -- Hibernate 3.3 and higher -->
<! --
<Property name = "hibernate. cache. region. factory_class"> net. sf. ehcache. hibernate. EhCacheRegionFactory </property>
<Property name = "hibernate. cache. region. factory_class"> net. sf. ehcache. hibernate. SingletonEhCacheRegionFactory </property>
-->
<! -- Hibernate3.0-3.2 cache config -->
<! --
<Property name = "hibernate. cache. region. factory_class"> net. sf. ehcache. hibernate. EhCacheProvider </property>
-->
<Property name = "hibernate. cache. provider_class"> net. sf. ehcache. hibernate. SingletonEhCacheProvider </property>
<! -- Enable Second-Level Cache and Query Cache Settings -->
<Property name = "hibernate. cache. use_second_level_cache"> true </property>
<Property name = "hibernate. cache. use_query_cache"> true </property>
If you are integrated into the spring configuration file, you need to configure the SessionFactory configuration in your applicationContext. xml.
[Html]
<Prop key = "hibernate. cache. use_query_cache"> true </prop>
<Prop key = "hibernate. cache. use_second_level_cache"> true </prop>
<Prop key = "hibernate. cache. provider_class"> org. hibernate. cache. EhCacheProvider </prop>
Then add the cached attributes to the hibernate. cfg. xml configuration file.
[Html]
<! -- Class-cache config -->
<Class-cache class = "com. hoo. hibernate. entity. User" usage = "read-write"/>
Of course, you can add the following format information under the configuration class node of the User. hbm. xml ing file that requires Cache:
[Html]
<Class name = "com. hoo. hibernate. entity. User" table = "USER" lazy = "false">
<Cache usage = "transactional | read-write | nonstrict-read-write | read-only"/>
Note: The cache node element should keep up with the class element.
About how to select a cache policy:
Ehcache does not support transactional. The other three types are supported.
Read-only: you do not need to modify it. You can perform read-only caching on it. Note: If you modify the database directly under this policy, even if you can see the front-end display effect, however, when an object is modified to the cache, an error is reported, and the cache does not work. In addition, an error is returned when you delete a record because the read-only mode object cannot be deleted from the cache.
Read-write: to update data, it is more appropriate to use the read/write cache. premise: the database cannot think of serializable transaction isolationlevel (serialization transaction isolation level)
Nonstrict-read-write: Only data needs to be updated occasionally (that is, it is uncommon for two transactions to update the same record at the same time), and strict transaction isolation is not required, therefore, it is more suitable to use non-strict read/write cache policies.
If the annotation method you use does not have User. hbm. xml, you can configure the cache using the annotation method.
[Java]
@ Cache (usage = CacheConcurrencyStrategy. READ_WRITE)
Public class User implements Serializable {
}
Use cache on the Dao layer. The Code is as follows:
[Java]
Session s = HibernateSessionFactory. getSession ();
Criteria c = s. createCriteria (User. class );
C. setCacheable (true); // This sentence must have
System. out. println ("first read ");
List <User> users = c. list ();
System. out. println (users. size ());
HibernateSessionFactory. closeSession ();
S = HibernateSessionFactory. getSession ();
C = s. createCriteria (User. class );
C. setCacheable (true); // This sentence must have
System. out. println ("second read ");
Users = c. list ();
System. out. println (users. size ());
HibernateSessionFactory. closeSession ();
You will find that the second query does not print the SQL statement, but directly uses the objects in the cache.
If your Hibernate and Spring are integrated, you can use HibernateTemplate to set the cache.
[Java]
GetHibernateTemplate (). setCacheQueries (true );
Return getHibernateTemplate (). find ("from User ");
When you integrate Spring, if your HibernateTemplate template is configured in the Ioc container of Spring, you can enable query cache in this way.
[Html]
<Bean id = "hibernateTemplate" class = "org. springframework. orm. hibernate3.HibernateTemplate">
<Property name = "sessionFactory">
<Ref bean = "sessionFactory"/>
</Property>
<Property name = "cacheQueries">
<Value> true </value>
</Property>
</Bean>
After that, you can inject hibernateTemplate into sessionFactory In the dao module.
All of the above are Spring and Hibernate configurations. The following describes how to configure ehcache. xml in combination with the ehcache used above. If you do not configure ehcache, The defaultCache configuration is used by default.
[Html]
<Cache name = "com. hoo. hibernate. entity. user "maxElementsInMemory =" 10000 "eternal =" false "timeToIdleSeconds =" 300 "timeToLiveSeconds =" 600 "overflowToDisk =" true "/>
<! --
Cache method name search policy for hbm files: if you do not specify region = "ehcache. the property value of name in xml ", the name is com. hoo. hibernate. entity. user's cache. If the cache name that matches the class name does not exist, use defaultCache.
If a User contains a set, you need to specify its cache
For example, if a User contains the citySet set
Add the following configuration to ehcache. xml:
-->
<Cache name = "com. hoo. hibernate. entity. citySet"
MaxElementsInMemory = "10000" eternal = "false" timeToIdleSeconds = "300"
TimeToLiveSeconds = "600" overflowToDisk = "true"/>
If you use the Hibernate query cache, add the following configuration in ehcache. xml.
[Html]
<Cache name = "org. hibernate. cache. UpdateTimestampsCache"
MaxElementsInMemory = "5000"
Eternal = "true"
OverflowToDisk = "true"/>
<Cache name = "org. hibernate. cache. StandardQueryCache"
MaxElementsInMemory = "10000"
Eternal = "false"
TimeToLiveSeconds = "120"
OverflowToDisk = "true"/>
When debugging, use log4j.logger.org. hibernate. cache = debug of log4j to conveniently see the operation process of ehcache, which is mainly used in the debugging process. comment out the operation process when the actual application is released to avoid performance impact.
When ehcache is used, it is normal to print the SQL statement, because when the query cache is set to true, two cache regions will be created: one for saving the query result set (org. hibernate. cache. standardQueryCache); the other is used to save the timestamp (org. hibernate. cache. updateTimestampsCache ). Note: In the query cache, it does not cache the exact status of the objects contained in the result set. It only caches the values of the Identifier attributes of these entities and the results of each value type. Compare the printed SQL statement with the latest cache content and modify the difference to the cache. Therefore, the query cache is usually used together with the second-level cache.
Author: IBM_hoojo