Ehcache Cache actual Battle __ Cache

Source: Internet
Author: User
Tags aop delete cache stringbuffer

The previous introduction of the MyBatis level two cache briefly introduces the Ehcache, and ehcache How to configure the level two cache for MyBatis. This article describes the application of Ehcache in the higher layers.
Using Ehcache's two-level cache as quickly as possible optimizes mybatis query efficiency, but there are several limitations to this.

1. Caching can only be used on tables with only single table operations

It's not just to make sure that this table has a single table operation on the entire system, and that all of the operations associated with the table must be under one namespace.

2. Use caching when you can guarantee that the query is much larger than the insert,update,delete operation

This point does not need to be said more, all should be clear. Remember, this needs to be guaranteed at 1.

In fact, you should avoid the use of level two cache, MyBatis under the level two cache has the following features:

The >*  cache is namespace, and the operations under different namespace do not affect each other.  The >* insert,update,delete operation clears all caches under the namespace.

>*  usually use MyBatis Generator generated code, each table is independent, each table has its own namespace.

Why avoid using level two caching

It does not have any effect when it meets the first-mentioned limit of level two caching.

Other things can be a lot of harm.

Some of the operations against a table are not performed under his independent namespace.

For example, in Usermapper.xml, there are most operations against the user table. However, in one xxxmapper.xml, there are actions for the user single table.

This causes user data to be inconsistent under two namespaces. If you do a flush cache in Usermapper.xml, the cache is still valid in Xxxmapper.xml, and if you have a single table query for user, the result of using the cache may be incorrect.

A more dangerous situation is when xxxmapper.xml do a insert,update,delete operation (and all caches are emptied at this time), which can cause various operations in usermapper.xml to be full of unknowns and risks.

Operations on such a single table may not be common. But you may think of a common situation.

multiple table operations must not use caching

Why not.

First of all, no matter how many table operations are written to that namespace, there is a situation where a table is not under this namespace.

For example, two tables: role and User_role, if I want to query out the roles of a user, it will certainly involve the operation of multiple tables.

<select id= "Selectuserroles" resulttype= "Userrolevo" >
    select * from User_role a,role b where A.roleid = B.rolei D and A.userid = #{userid}
</select>

Like the query above, you'll write it in that XML.

Whether it's written to Rolemapper.xml or userrolemapper.xml, or a separate xxxmapper.xml. If a level two cache is used, the above query result may be incorrect.

If you modify the role of this user exactly, the result of this query using caching is wrong.

This should be easy to understand.

In my opinion, it is no solution to look at the current MyBatis caching method. Multiple table operations cannot be cached at all.

If you let them all use the same namespace (via <cache-ref>) to avoid dirty data, then you lose the meaning of caching.

Save level Two cache.

trying to use level two caching more efficiently is not going to work.

However, the solution of multiple table operation to avoid dirty data is still solved. The solution is to use the interceptor to determine which of the executed SQL involves those tables (which can be parsed by Jsqlparser), and then automatically empty the cache of related tables. But this is a very inefficient way to use the cache.

Design such a plug-in is quite complex, since I do not want to achieve, it is not nonsense.

Finally, it is recommended that you discard the secondary cache and replace it better with a controlled cache at the business level.

Business Layer Use Ehcache combat:

You need to add the following jar package to the Lib directory

Ehcache-core-2.5.2.jar

Ehcache-web-2.0.4.jar//primarily for page caching

3, the current project SRC directory to add the configuration file

Ehcache.xml

ehcache.xsd

These configuration files can be found in the Ehcache-core jar package

Basic usage of Ehcache

CacheManager CacheManager = Cachemanager.create ();
or CacheManager = Cachemanager.getinstance ();
or CacheManager = Cachemanager.create ("/config/ehcache.xml");
or CacheManager = Cachemanager.create ("Http://localhost:8080/test/ehcache.xml");
CacheManager = Cachemanager.newinstance ("/config/ehcache.xml");
..//Get a cache Cache sample = Cachemanager.getcache ("sample") in the Ehcache configuration file;
Gets the page cache Blockingcache cache = new Blockingcache (Cachemanager.getehcache ("Simplepagecachingfilter"));
Add data to the cache element element = new Element ("Key", "Val");
Sample.put (Element);
Gets the object in the cache, noting that the object added to the cache is serialized to implement serializable interface Element result = Sample.get ("key");
Delete Cache Sample.remove ("key");

Sample.removeall (); Gets the cache configuration name in Cache Manager for (String CacheName:cacheManager.getCacheNames ()) {System.out.println (cachename);}//Get all cache

Object for (Object Key:cache.getKeys ()) {System.out.println (key);}
Get the number of objects in the cache Cache.getsize ();
Get the cache object to occupy the memory size cache.getmemorystoresize (); Hit count CA with cache readChe.getstatistics (). Getcachehits (); The number of missed cache reads Cache.getstatistics (). getcachemisses ();

Third, page caching

The page cache filters the requested URL primarily with the filter filter, if the URL appears in the cache. The page data is then fetched from the cached object and returned with gzip compression. The speed is 3-5 times the speed without compressing the cache, and the efficiency is quite high. The filter for the page cache has cachingfilter, typically extending the filter or customizing the filter to inherit the Cachingfilter.
The Cachingfilter feature can cache the contents of an HTTP response. This way the granularity of the cached data is relatively coarse, such as caching the entire page. Its advantage is simple, high efficiency, the disadvantage is not flexible enough, the degree of reuse is not high.

Ehcache uses the Simplepagecachingfilter class to implement the filter cache. This class inherits from Cachingfilter and has the default Calculatekey () method of generating cache key, which uses the URI of the HTTP request and the query condition to form the key. You can also implement a filter by itself, inheriting the Cachingfilter class, and then Calculatekey () method to generate a custom key.

Cachingfilter output data will be based on the browser sent accept-encoding header information for gzip compression.

When using gzip compression, you need to be aware of two issues: filter in the gzip compression, using the system default encoding, for the use of GBK-encoded Chinese web pages, the operating system needs to set the language to: ZH_CN. GBK, otherwise will appear garbled problem. By default, Cachingfilter determines whether gzip compression is performed according to the accept-encoding parameter values that are included in the request headers sent by the browser. Although the Ie6/7 browser supports gzip compression, it does not take this parameter when sending a request. In order to IE6/7 can also be a gzip compression, you can inherit cachingfilter, to implement their own filter, and then in the implementation of the Acceptsgzipencoding override method.

Specific implementation reference:

Protected Boolean acceptsgzipencoding (HttpServletRequest request) {

Boolean IE6 = headercontains (Request, " User-agent "," MSIE 6.0 ");

Boolean IE7 = Headercontains (Request, "User-agent", "MSIE 7.0");

return acceptsencoding (Request, "gzip") | | IE6 | | IE7;

}

The configuration in Ehcache.xml is as follows:

<?xml version= "1.0" encoding= "GBK"?> <ehcache xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance" xsi: nonamespaceschemalocation= "Ehcache.xsd" > <diskstore path= "java.io.tmpdir"/> <defaultcache maxElements 
        Inmemory= "10000" eternal= "false" timetoidleseconds= "timetoliveseconds=" overflowtodisk= "false"/> <!--
        Configure the Custom cache maxelementsinmemory: The maximum number of objects allowed to be created in the cache eternal: whether the object in the cache is permanent, and if so, the timeout setting is ignored and the object never expires. Timetoidleseconds: The passivation time of cached data, which is the maximum time interval value of two access times before an element dies, which can only be valid if the element is not permanently resident, if the value is 0
        means that the element can pause for an infinite length of time.
        Timetoliveseconds: The lifetime of the cached data, which is the maximum time interval value for an element from construction to extinction, which can only be valid if the element is not permanently resident, if the value is 0 means that the element can pause for an infinite length of time.
        Overflowtodisk: Disk caching is enabled when there is not enough memory.

     Memorystoreevictionpolicy: Cache full after the elimination algorithm.
    Note: A ehcache.xml can not only write a cache tag, depending on the cached object to write a number of caches, the other name for its identity bit. --> <cache name= "Simplepagecachingfilter" maxelementsinmemory= "10000" FALSE "overflowtodisk=" false "timetoidleseconds=" 900 "timetoliveseconds=" 1800 "Memorystore evictionpolicy= "LFU"/> </ehcache>

Add the following configuration to the Web.xml

<!--ehcache-->
    <filter>
        <filter-name>SimplePageCachingFilter</filter-name>
        <filter-class>net.sf.ehcache.constructs.web.filter.simplepagecachingfilter
        </filter-class >
      </filter>

  <!--This is a filter chain. They are executed in the order below.
  Don't change the order. -->
     <filter-mapping>
        <filter-name>SimplePageCachingFilter</filter-name>
        < Url-pattern>*.do</url-pattern>
     </filter-mapping>

Note: The cached name configured in the Ehcache.xml file must match the Web.xml configured cache filter name or it will throw an exception that cannot find the configuration.

When these pages are requested for the first time, they are added to the cache and later requested to be retrieved from the cache. You can test whether the page is cached by using a little script on the cache.jsp page. <%=new Date ()%> If the time is variable, it means that the page is not cached or the cache has expired, otherwise it is in the cached state.

Object caching

Object caching is to add the queried data to the cache and retrieve it directly from the cache the next time it is queried, rather than querying the database.

Object caching is typically for methods, classes, and the combination of spring's AOP objects and method caches is simple. You need to use cut-surface programming to use Spring Methodinterceptor or @aspect.

public class Methodcacheinterceptor implements Methodinterceptor, Initializingbean {private static final Logger log

    = Logger.getlogger (Methodcacheinterceptor.class);

    Private cache cache;
    public void Setcache (cache cache) {This.cache = cache; The public void Afterpropertiesset () throws Exception {Log.info cache + ' A cache is required.

    Use Setcache (Cache) to provide one; ");} Public Object Invoke (Methodinvocation invocation) throws Throwable {String targetName = Invocation.getthis (). getc
        Lass (). GetName ();
        String methodname = Invocation.getmethod (). GetName ();
        object[] arguments = invocation.getarguments ();

        Object result;
        String CacheKey = Getcachekey (TargetName, MethodName, arguments);
        element element = null;
            Synchronized (this) {element = Cache.get (CacheKey);
          if (element = = null) {Log.info (CacheKey + "add to cache:" + cache.getname ());      Invoke the actual method result = Invocation.proceed ();
                element = new Element (CacheKey, (Serializable) result);
            Cache.put (Element);
            else {log.info (CacheKey + "Use cache:" + cache.getname ());
    } return Element.getvalue ();
     /** * <b>function:</b> Return specific method full path name parameter * @param targetName full path * @param methodname method name * @param arguments parameter * @return Full method Name */private string Getcachekey (String targetName, String Methodna
        Me, object[] arguments {stringbuffer sb = new StringBuffer (); Sb.append (TargetName). Append (".").
        Append (methodname);
                if ((arguments!= null) && (arguments.length!= 0)) {for (int i = 0; i < arguments.length; i++) { Sb.append (".").
            Append (Arguments[i]);
    } return sb.tostring (); }
}

The method interceptor here is primarily to intercept the class you want to intercept the method, and then determine the method of the class path + method name + parameter value combination of cache key in the cached buffer exists. If it exists, the object is removed from the cache and converted to the return type we want. If not, add the object returned by the method to the cache. It is worth the idea that the parameters of the current method and the object type of the return value need to be serialized.

We need to add Applicationcontext.xml to the SRC directory to complete the configuration of the Methodcacheinterceptor interceptor, which is mainly injected into our cache object, which cache to manage the object cache, and then which classes, method to participate in the scanning of the interceptor.

<!--Configure EH cache manager--> <bean id= "CacheManager" class= " Org.springframework.cache.ehcache.EhCacheManagerFactoryBean "/> <!--Configure a simple cache factory Bean object--> <bean id=" Simplecache "class=" Org.springframework.cache.ehcache.EhCacheFactoryBean "> <property name=" CacheManager "ref = "CacheManager"/> <!--using the cache configuration in the cache association Ehcache.xml--> <property name= "CacheName" value= "Mobilecache"/&
Gt </bean> <!--Configure a cache interceptor object to handle specific caching services--> <bean id= "Methodcacheinterceptor" class= " Com.common.interceptor.MethodCacheInterceptor "> <property name=" Cache "ref=" Simplecache "/> </bean> & lt;! --Participate in the cached Pointcut object (Pointcut object, determine when and where the Interceptor is invoked)--> <bean id= "Methodcachepointcut" class= " Org.springframework.aop.support.RegexpMethodPointcutAdvisor "> <!--configuration cache AOP Slice--> <property name=" Advic                  
        E "ref=" Methodcacheinterceptor/> <!--Configure which methods participate in the caching policy--> <!--. Represent any single character          ### + indicates that the previous character is met one or more times        
        ### * represents a symbol that conforms to the previous character 0 or more times ### \escape any regular expression uses --> <!--. * represents the preceding prefix (including the package name) representing the Print method--> <property name= "Patterns" > <li St> <value>com.hoo.rest.*RestService*\.*get.*</value> <value>com.hoo.rest.*re stservice*\.*search.*</value> </list> </property> </bean>

Add the following cache configuration to the Ehcache.xml

<cache name= "Mobilecache"
        maxelementsinmemory= "10000" eternal= "
        false"
        overflowtodisk= "true"
        timetoidleseconds= "1800"
        timetoliveseconds= "3600" memorystoreevictionpolicy= "LFU"
        />

Reference: http://blog.csdn.net/isea533/article/details/44566257
Reference: http://www.cnblogs.com/hoojo/archive/2012/07/12/2587556.html

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.