When reading the official hibernate documentation, you can see the Introduction to cache.
Hibernate does a good job in Cache Management. This Chapter does not explain how to use it. This article mainly studies the usage of EhCache. Here, the list of cache providers used by hibernate is as follows:
Cache |
Provider class |
Type |
Cluster Safe |
Query Cache Supported |
Hashtable (not intended for production use) |
org.hibernate.cache.HashtableCacheProvider |
Memory |
|
Yes |
EHCache |
org.hibernate.cache.EhCacheProvider |
Memory, disk, transactional, clustered |
Yes |
Yes |
OSCache |
org.hibernate.cache.OSCacheProvider |
Memory, disk |
|
Yes |
SwarmCache |
org.hibernate.cache.SwarmCacheProvider |
Clustered (ip multicast) |
Yes (clustered invalidation) |
|
JBoss Cache 1.x |
org.hibernate.cache.TreeCacheProvider |
Clustered (ip multicast), transactional |
Yes (replication) |
Yes (clock sync req .) |
JBoss Cache 2 |
org.hibernate.cache.jbc.JBossCacheRegionFactory |
Clustered (ip multicast), transactional |
Yes (replication or invalidation) |
Yes (clock sync req .) |
Among them, I am more interested in EHCache. The supported types include memory, hard disk, traditional, and cluster.
We can study the use of Ehcache cache separately, so that we can customize Cache Management for other places that are used in the cache (not just for hibernate data query ).
Ehcache: http://sourceforge.net/projects/ehcache/files/ehcache/
First, write an example to see how its api is used:
EhcacheTest
Package org. base. cache. test; import java.net. malformedURLException; import java.net. URL; import net. sf. ehcache. cache; import net. sf. ehcache. cacheManager; import net. sf. ehcache. element; import net. sf. ehcache. config. cacheConfiguration; import net. sf. ehcache. config. configuration; /*** api test example for Ehcache Cache Management * @ author lushuaiyin **/public class EhcacheTest {/*** @ param args */public static void main (String [] Args) throws MalformedURLException {net. sf. ehcache. config. configuration config = new Configuration (); // if you do not use ehcache. in the xml configuration file, you must use the code to configure a defaultCacheConfigurationCacheConfiguration defaultCacheConfiguration = new CacheConfiguration (); defaultCacheConfiguration. setMaxEntriesLocalHeap (0); defaultCacheConfiguration. setEternal (false); defaultCacheConfiguration. setTimeToIdleSeconds (30); defaultCacheConfiguration. SetTimeToLiveSeconds (30); config. addDefaultCache (defaultCacheConfiguration); // you can specify the default value of cachenet. sf. ehcache. cacheManager cacheManager = CacheManager. create (config); // create Cache Information/* multiple construction methods. For details, see public Cache (String name, int maxElementsInMemory, boolean overflowToDisk, boolean eternal, long timeToLiveSeconds, long timeToIdleSeconds) * /// customize the cache. net. sf. ehcache. cache cache1 = new Cache ("mycache-one", 1000, false, fals E, 30, 30); cacheManager. addCache (cache1); // This method can be used only when defaultCacheConfiguration is configured. Because the cache named by string must have actual configuration. CacheManager. addCache ("mycache-two"); // Add an empty cache // Add the value String objkey1 = "key1", objvalue1 = "value1 "; cache1.put (new Element (objkey1, objvalue1); // put it directly // retrieve all values in a cache through traversal if (cacheManager. getCache ("mycache-one ")! = Null) {Cache cache11 = cacheManager. getCache ("mycache-one"); if (cache11.getKeys (). size () = 0) {System. out. println ("mycache-one exits, but no value. ");} else {for (int I = 0; I <cache11.getKeys (). size (); I ++) {Object thekey = cache11.getKeys (). get (I); Object thevalue = cache11.get (thekey); System. out. println ("mycache-one-" + I + ", key:" + thekey. toString () + ", value:" + thevalue. toString () ;}} else {System. out. println ("mycache-one -Is null ");}/* print the mycache-one-0, key: key1, value: [key = key1, value = value1, version = 1, hitCount = 1, CreationTime = 1366263629054, lastAccessTime = 1366263629054] */if (cacheManager. getCache ("mycache-two ")! = Null) {Cache cache2 = cacheManager. getCache ("mycache-two"); if (cache2.getKeys (). size () = 0) {System. out. println ("mycache-two exits, but no value. ");} else {for (int I = 0; I <cache2.getKeys (). size (); I ++) {Object thekey = cache2.getKeys (). get (I); Object thevalue = cache2.get (thekey); System. out. println ("mycache-two-" + I + ", key:" + thekey. toString () + ", value:" + thevalue. toString () ;}} else {System. out. println ("mycache-two-is null");}/* print mycache-two exits, but no value. */}}
In most cases, Ehcache is configured with ehcache. xml. Integration in spring is very convenient.
Next we will use ehcache. xml, but not in the web environment, to customize the cache.
Org/base/cache/test/myehcache. xml
<? Xml version = "1.0" encoding = "UTF-8"?> <Ehcache xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi: noNamespaceSchemaLocation = "ehcache. xsd "updateCheck =" true "monitoring =" autodetect "dynamicConfig =" true "> <diskStore path =" java. io. tmpdir "/> <! -- JTA transaction configuration. If the class attribute is null, The TransactionManager object is searched in a sequence by default. You can also customize it. You need to implement the net. sf. ehcache. transaction. manager. TransactionManagerLookup interface --> <! -- <TransactionManagerLookup class = "net. sf. ehcache. transaction. manager. DefaultTransactionManagerLookup" properties = "jndiName = java:/TransactionManager" propertySeparator = ";"/> --> <! -- CacheManagerEventListener: cache listener. You can customize the listener class as needed. <cacheManagerEventListenerFactory class = "" properties = ""/> --> <! -- Terracotta server cluster configuration. For details, see the document --> <! -- <TerracottaConfig url = "localhost: 9510"/> --> <defaultCache maxEntriesLocalHeap = "0" eternal = "false" timeToIdleSeconds = "30" timeToLiveSeconds = "30"> <! -- <Terracotta/> --> </defaultCache> <! -- The cache name is myCache1. The cache contains a maximum of 10000 elements in the memory, and the elements that are idle for more than 5 minutes and exist for more than 10 minutes are released. If there are more than 10000 elements, the disk cache will overflow and the maximum number of Hard Disk caches will be 1000. The hard disk path is defined as java. io. tmp. --> <Cache name = "myCache1" maxEntriesLocalHeap = "500" maxEntriesLocalDisk = "1000" eternal = "false" leading = "20" timeToIdleSeconds = "300" timeToLiveSeconds = "600" leading = "LFU" transactionalMode = "off"> <persistence strategy = "localTempSwap"/> </cache> <! -- The cache name is sampleCache2. The maximum number of elements cached in the memory is 1000. No overflow is set to the disk, so 1000 is the Maximum Cache value. Note that when a cache eternal is set to true, TimeToLive and timeToIdle do not work. <Cache name = "sampleCache2" maxEntriesLocalHeap = "1000" eternal = "true" memoryStoreEvictionPolicy = "FIFO"/> --> <! -- The cache name is sampleCache3. This cache overflows to the disk. The disk cache is valid permanently before the VM restarts. The time interval of the disk termination thread is set to 3 minutes, covering the default 2 minutes. <Cache name = "sampleCache3" maxEntriesLocalHeap = "500" eternal = "false" overflowToDisk = "true" diskPersistent = "true" timeToIdleSeconds = "300" timeToLiveSeconds = "600" seconds =" 180 "memoryStoreEvictionPolicy =" LFU "> </cache> --> <! -- Terracotta cluster cache sampleTerracottaCache. <Cache name = "sampleTerracottaCache" maxBytesLocalHeap = "10 m" eternal = "false" timeToIdleSeconds = "3600" timeToLiveSeconds = "1800"> <terracotta/> </cache> --> /ehcache>
For more information about the meaning of configuration properties, see the documentation on the official website. Some common properties are provided here.
The following attributes of the Cache are required. Name: the unique identifier of the cache. MaxEntriesLocalHeap: Maximum number of objects created in the memory. 0 = unrestricted. Unlimited actually refers to Integer. MAX_SIZE (2147483647 ). MaxEntriesLocalDisk: sets the maximum number of objects stored on the hard disk. The default value is 0, which is unlimited. Eternal: sets whether the element is persistent. If yes, the element will not expire. The following attributes of the Cache are optional. OverflowToOffHeap: this feature is only available in the Ehcache Enterprise Edition. When set to true, you can use unlimited off-heap memory cache storage to improve performance. The off-heap memory is not restricted by Java GC. The default value is false. MaxBytesLocalHeap: defines how many bytes of cache may use the Virtual Machine heap. If maxBytesLocalHeap of a CacheManager has been defined, the specified amount of the cache will be subtracted from the value of CacheManager. Other caches will share the rest. The value of this attribute is <number> K | meter | M | G kilobytes (K | K) and MB (M | M) or 1 Gbit/s (G | G ). For example, the "2 GB" of maxBytesLocalHeap delivers 2 GB heap memory. If you specify a maxBytesLocalHeap, you cannot use the maxEntriesLocalHeap attribute. MaxBytesLocalOffHeap: this function is only available in the Ehcache Enterprise Edition. The amount of off-heap memory. You can use this cache setting to retain it. This setting sets overflowToOffHeap to true. Set explicitly to false to disable overflow. Note that at least 100 elements are recommended for setting maxEntriesLocalHeap when off-heap is used. Otherwise, the performance will seriously degrade and a warning is given. The minimum allocable amount is 128 MB. No maximum value. MaxBytesLocalDisk: As for maxBytesLocalHeap, but specifies the limit of disk storage this cache will ever use. timeToIdleSeconds: sets the idle duration of the element. Unit: seconds. (Valid when eternal is set to false) Optional attribute. If the value is 0, the elements can be idle infinitely. The default value is 0. TimeToLiveSeconds: sets the expiration time of an element. Unit: seconds. (Valid when eternal is set to false) Optional attribute. If the value is 0, the elements can be infinite. The default value is 0. DiskExpiryThreadIntervalSeconds: the number of seconds between disk expiration threads. Default Value: 120 seconds. DiskSpoolBufferSizeMB: the size of the buffer allocated to the hard disk storage. Information is written to this region and then asynchronously written to the disk. The default size is 30 MB. Each buffer is only used for its cache. If you encounter a memory overflow error, try to reduce this value. This value should be added to improve hard disk storage performance. ClearOnFlush: When the flush () method is called, the hard disk storage cache is cleared. The default value is true. MemoryStoreEvictionPolicy: memory management policy. By default, it is the Least Recently Used Policy (Least Recently Used, LRU ). Other options include First-In-First-Out and First-Out (FIFO). The minimum frequency policy (Less Frequently Used and LFU) is Used ). CopyOnRead: whether to read an element from the cache when it is copied. The default value is false. CopyOnWrite: whether an element is copied when it is added to the cache. The default value is false.
EhcacheManagerTest
Package org. base. cache. test; import java.net. URL; import net. sf. ehcache. cache; import net. sf. ehcache. cacheManager; import net. sf. ehcache. element; import net. sf. ehcache. status;/*** initial learning instance for Ehcache Cache Management * @ author lushuaiyin **/public class EhcacheManagerTest {public static net. sf. ehcache. cacheManager cacheManager = null; private static String configPath = "org/base/cache/test/myehcache. xml "; // the path of the configuration file, which is usually placed in the source file Private static String CACHE_MYCACHE1 = "myCache1"; // defines the cache configured in the file // instantiate cacheManager. Singleton mode: public static CacheManager getCacheManagerInstance () {if (cacheManager = null) {URL configUrl = null; configUrl = EhcacheManagerTest. class. getClassLoader (). getResource (configPath); cacheManager = CacheManager. create (configUrl);} return cacheManager;} public static net. sf. ehcache. cacheManager getCacheManager () {return getC AcheManagerInstance (); // single-instance Cache Management} // This set may not be open to public static void setCacheManager (net. sf. ehcache. cacheManager cacheManager) {EhcacheManagerTest. cacheManager = cacheManager;} // Add public static void addCacheByName (String cacheName) {if (cacheName = null | cacheName. trim (). equals ("") {System. out. println ("cacheName is null");} else {if (getCacheManager (). getCache (cacheName. trim ())! = Null) {getCacheManager (). removeCache (cacheName. trim ();} getCacheManager (). addCache (cacheName. trim (); System. out. println (cacheName + "add again") ;}// obtain the public static cache object getCacheByName (String cacheName) {Cache cache = null; if (cacheName = null | cacheName. trim (). equals ("") {System. out. println ("cacheName is null");} else {if (getCacheManager (). getCache (cacheName. trim ())! = Null) {cache = getCacheManager (). getCache (cacheName. trim () ;}} return cache;} // Add the public static void putElementToCache (String cacheName, String elementKey, Object elementValue) to the Cache {cache Cache = null; if (cacheName = null | cacheName. trim (). equals ("") {System. out. println ("failed to add cache element, cacheName is null");} else if (elementKey = null | elementValue = null) {System. out. println ("failed to add cache element, elementKey or elementValue is nul L ");} else {if (getCacheByName (cacheName. trim ())! = Null) {// cache existence cache = getCacheByName (cacheName. trim ();} else {// The cache does not contain addCacheByName (cacheName. trim (); cache = getCacheByName (cacheName. trim ();} // Add ElementElement = null to the cache object; if (cache. get (elementKey. trim ())! = Null) {cache. remove (elementKey. trim ();} element = new Element (elementKey. trim (), elementValue); cache. put (element); System. out. println ("add cache element:" + elementKey + "successful! ") ;}}// Obtain the value of the specified key from the Cache. public static Object getElementValueFromCache (String cacheName, String elementKey) {Object result = null; cache Cache cache = null; if (cacheName = null | cacheName. trim (). equals ("") {System. out. println ("failed to get cache element, cacheName is null");} else if (elementKey = null) {System. out. println ("failed to get the cache element, elementKey is null");} else {if (getCacheByName (cacheName. trim ())! = Null) {// cache = getCacheByName (cacheName. trim (); Element element = null; if (cache. get (elementKey. trim ())! = Null) {element = cache. get (elementKey. trim (); if (element. getObjectValue () = null) {System. out. println (the value of "+ elementKey +" in the cache is null. ");} else {result = element. getObjectValue () ;}} else {System. out. println (the Element value of "+ elementKey +" in the cache is null. ") ;}} else {// The cache does not exist System. out. println ("failed to get cache element, cache" + cacheName + "is empty. ") ;}} return result;}/*** deletes all the content in the cache, but the cache object is retained. * Clears the contents of all caches in the CacheManager, * B Ut without removing any caches. */public static void clearAllFromCacheManager () {if (getCacheManager ()! = Null) {getCacheManager (). clearAll (); System. out. println ("CacheManager was clearAll... ") ;}}/*** Delete All cache objects. Use it with caution! * Removes all caches using removeCache (String) for each cache. */public static void removalAllFromCacheManager () {if (getCacheManager ()! = Null) {getCacheManager (). removalAll (); System. out. println ("CacheManager was removalAll... ") ;}} // when no cache is required, disable it. Otherwise, it will occupy cpu and memory resources. Public static void shutdownCacheManager () {if (getCacheManager ()! = Null) {getCacheManager (). shutdown (); System. out. println ("CacheManager was shutdown... ") ;}} // print method 1, to test the use of public static void printCache (Cache cache) {System. out. println ("cache status:" + cache. getStatus (). toString (); if (cache = null) {System. out. println ("cache is null, no print info. ");} else if (cache. getStatus (). toString (). equals (Status. STATUS_UNINITIALISED) {System. out. println ("cache Status: Not initialized" + cache. getStatus (). toStri Ng ();} else if (cache. getStatus (). toString (). equals (Status. STATUS_SHUTDOWN) {System. out. println ("cache status: Disabled" + cache. getStatus (). toString ();} else if (cache. getStatus (). toString (). equals (Status. STATUS_ALIVE) {if (cache. getKeys (). size () = 0) {System. out. println (cache. getName () + "exits, but no value. ");} else {for (int I = 0; I <cache. getKeys (). size (); I ++) {Object thekey = cache. getKeys (). get (I); Object thevalue = cache. Get (thekey); System. out. println (cache. getName () + "--" + I + ", key:" + thekey. toString () + ", value:" + thevalue. toString () ;}}}// print method 2. To test the function of using public static void printCacheByName (String cacheName) {if (cacheName = null | cacheName. trim (). equals ("") {System. out. println ("cacheName is null, no print info. ");} else {if (getCacheManager (). getCache (cacheName. trim ())! = Null) {Cache cache = getCacheManager (). getCache (cacheName. trim (); printCache (cache);} else {System. out. println (cacheName + "-- null") ;}} public static void main (String [] sdfsf) {Cache cache1 = EhcacheManagerTest. getCacheByName (EhcacheManagerTest. CACHE_MYCACHE1); printCache (cache1); EhcacheManagerTest. putElementToCache (EhcacheManagerTest. CACHE_MYCACHE1, "111", "111 haah"); EhcacheManagerTest. putElementToCache (Eh CacheManagerTest. CACHE_MYCACHE1, "222", "222 haah"); EhcacheManagerTest. putElementToCache (EhcacheManagerTest. CACHE_MYCACHE1, "333", "333 haah"); printCache (cache1); EhcacheManagerTest. putElementToCache (EhcacheManagerTest. new Value of CACHE_MYCACHE1, "111", "111. "); System. out. println (EhcacheManagerTest. getElementValueFromCache (EhcacheManagerTest. CACHE_MYCACHE1, "111"); printCache (cache1); clearAllFromCacheManager (); printCache (cache1); cached (); printCache (cache1); shutdownCacheManager ();} /* print the cache status: STATUS_ALIVE adds the cache element: 111 successful! Cache element added: 222 successful! Cache element added: 333 successful! Cache status: STATUS_ALIVE: 111 successful! The new value of 111. Cache status: STATUS_ALIVECacheManager was clearAll... Cache status: STATUS_ALIVECacheManager was removalAll... Cache status: STATUS_SHUTDOWNCacheManager was shutdown ...*/}
Through the above usage, we have a preliminary understanding of Ehcache APIs. In the web environment, we can inject EhcacheManager objects,
Put the required data into the cache. When data is retrieved elsewhere, it is obtained from EhcacheManager instead of directly
Query from the database. This improves the efficiency.
It is worth noting that the cache is generally used in some areas where data is relatively fixed. If a query needs to ensure real-time data, use the cache
It is an incorrect practice.