Spring mind map makes Spring no longer difficult to understand (CACHE)

About caching

Caching is a very common method of improving performance in real work. In Java, the so-called cache is the object that the program or system often calls to be in memory. When called again, you can quickly get objects from memory without having to create new duplicate instances. This reduces system overhead and improves system efficiency.

In the search for additions and deletions, database queries occupy more than 80% of database operations, while very frequent disk I/O read operations will lead to extremely low database performance. And the importance of the database speaks for itself:

  • Databases are usually the central part of the enterprise application system
  • The amount of data that a database holds is usually very large
  • Database query operations are often frequent and sometimes complex

Caching can exist in order to speed up access between different levels of the system architecture

Spring mind map makes Spring no longer difficult to understand (CACHE)
cache different levels of action.Png

Features and shortcomings of spring cache

Now the mainstream cache frameworks on the market are ehcache, redis, and memcached. Spring cache can be used with a simple configuration. Among them, the annotation method is the simplest.

Spring mind map makes Spring no longer difficult to understand (CACHE)
features and regrets.Png

Cache annotation

Spring mind map makes Spring no longer difficult to understand (CACHE)
cache annotation.Png

As you can see from the annotations above, although it is convenient to use annotations, there is a lack of flexible caching policies,

Cache policy:

  • TTL (Time, To, Live)
    lifetime, that is, a time period from the creation point of the cache until its expiration (regardless of whether there is access during this time period will expire)
  • TTI (Time To Idle)
    idle period, that is, how long a data is not accessed and will be removed from the cache

There may be many cache TTL differences in the project, and this time you need to encode the use of caching.

Conditional caching

According to the running process, the following @Cacheable will determine the condition before the execution method (#result can’t get the return value), and if you return true, check the cache;

@Cacheable (value = user, key = #id, condition = #id, lt 10) public, User, conditionFindById (final, Long, ID)

As follows, @CachePut will determine the condition after the method is executed (#result can get the return value), and if true is returned, the cache is placed

@CachePut (value = user, key = #id, condition = #result.username, NE,'zhang') public, User, conditionSave (final, User, user)

As follows, @CachePut will determine the unless after the method has been executed (#result can get the return value), and if it returns false, it is placed in the cache (i.e., contrary to condition)

@CachePut (value = user, key = #user.id, unless = #result.username, EQ,'zhang') public, User, conditionSave2 (final, User, user)

The following @CacheEvict, beforeInvocation=false means that the call is made after the method is executed (#result gets the return value), and the condition is judged, and the cache is removed if true is returned;

@CacheEvict (value = user), key = #user.id, beforeInvocation = false, condition = #result.username, NE,'zhang') public, User, conditionDelete (final, User, user)
  • NiuDao, comprehensive use:
@CachePut (value = "user", key = "#user.id") public User save (User user) {users.add (user); return user;} @CachePut (value = user, key = "#user.id") public User update (User user) {users.remove (user); users.add (user; return) user;} @CacheEvict (value = user, key = "#user.id") public User delete (User user) {users.remove (user); return user;} @CacheEvict (value = user, allEntries = true) public void (deleteAll) {users.clear} (); @Cacheable (value = "user", key = "#id") public User findById (final Long ID) {System.out.println ("cache miss invoke find, by ID, id: + ID); for (User user users) { If (user.getId ().Equals (ID)) {return user}} return null}

Configuring ehcache and redis

  • Spring cache integration ehcache, spring-ehcache.xml main content:
< dependency> groupId> net.sf.ehcache< /groupId> < artifactId> < ehcache-core< /artifactId> <; version> ${ehcache.version}< /version> < /dependency>
< --> - Spring! Cache management based on the Ehcache implementation; <! -- if you have more than one ehcacheManager in bean with p:shared= "true" --> < bean; id= "ehcacheManager" class= "org.springframework.cache.ehcache.EhCacheManagerFactoryBean" > < property; name= "configLocation" value= "classpath:xml/ehcache.xml" /> < /bean> bean; < id= "cacheManager" class= "org.springframework.cache.ehcache.EhCacheCacheManager" > < property; name= "cacheManager" ref= "ehcacheManager" /> < property; name= "transactionAware" value= "true" /> < /bean> <! -- cache annotations, and spring-redis.xml in use only a --> < cache:annotation-driven; cache-manager= "cacheManager" proxy-target-class= "true" />
  • Spring cache integration redis, spring-redis.xml main content:
< dependency> < groupId> org.springframework.data< /groupId> < artifactId> spring-data-redis< /artifactId> < version> 1.8.1.RELEASE< /version> < /dependency> < dependency> < groupId> org.apache.commons< /groupId> < artifactId> commons-pool2< /artifactId> < version> 2.4.2< /version> < /dependency> < dependency> < groupId> redis.clients< /groupId> < artifactId> jedis< /artifactId> < version> 2.9.0< /version> < /dependency>
<! -- note Data Redis need to add Spring jar --> < description> redis /description> < < bean id= "jedisPoolConfig" class= "redis.clients.jedis.JedisPoolConfig" > < property; name= "maxIdle" value= "${redis.pool.maxIdle}" /> < property; name= "maxTotal" value= "${redis.pool.maxActive}" /> < property name= "maxWaitMillis" value= "${redis.pool.maxWait}" /> < property; name= "testOnBorrow" value= "redis.pool.testOnBorrow} a. /> < property" name= "testOnReturn" value= "${redis.pool.testOnReturn}" /> < /bean> < < JedisConnectionFactory! - --> bean id= "jedisConnectionFactory" class= "org.springframework.data.redis.connection.jedis.JedisConnectionFactory" > < property name= "HostName" value= "${redis.master.ip}" /> < property; name= "port" value= "${redis.master.port}" /> < property; name= "poolConfig" ref= "jedisPoolConfig" /> < /bean> < bean id= "redisTemplate" class= "org.springframework.data.redis.core.RedisTemplate" p:connectionFactory-ref= "jedisConnectionFactory" > < property; name= "keySerializer" > < bean class=; org.springframework.data.redis.serializer.JdkSerializationRedisSerializer & gt; < /bean> < /property> < property name= "valueSerializer" > < bean; class= "org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" /> < /property> < property name= "hashKeySerializer" > < bean class= o Rg.springframework.data.redis.serializer.JdkSerializationRedisSerializer /> < /property> < property name= "hashValueSerializer" > < bean; class= "org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" /& gt; < /property> < /bean> < --spring cache--> < bean! Id= "cacheManager" class= "org.springframework.data.redis.cache.RedisCacheManager" c:redisOperations-ref= "redisTemplate" > <! -- default cache 10 minutes --> < property name= "defaultExpiration" value= "600" /> < property; name= "usePrefix" value= "true" /> <! -- cacheName cache timeout configuration, half an hour, one hour, one day --> < property name= expires & gt; < map key-type= "J Ava.lang.String "value-type=" java.lang.Long "> < entry; key=" halfHour "value=" 1800 "/> < entry; key=" hour "value=" 3600 "/> < entry; key=" oneDay "value=" 86400 "/> < Shiro cache keys! - --> < entry key=" authorizationCache "value=" 1800 "/> < entry; key=" authenticationCache "value=" 1800 "/> < entry; key=" activeSessionCache "value=" 1800 "/> < /map> < /property> < /bean> cache & lt;! -- notes, and spring-ehcache.xml can only use a --> < cache:annotation-driven cache-manager=" cacheManager "proxy-target-class=" true "/>

In the project, the annotation cache can only configure one, so which configuration file can be introduced to determine which cache to use.

< import resource=; classpath:spring/spring-ehcache.xml; /> < - - < import; resource=; classpath:spring/spring-redis.xml; /> -->

Of course, you can use two cache mechanisms through other configurations. For example, ecache does the first level cache, and the redis does the two level cache.

Spring mind map makes Spring no longer difficult to understand (CACHE)
cache contrast.Png

For more detailed usage and configuration, you can refer to the configuration of spring spring-shiro-training in the cache in the project.

  • Https://git.oschina.net/wangzhixuan/spring-shiro-training.git

Written in the end

Visualization learning in mind mapping makes Java no longer difficult to understand.

Pay attention to Java mind map, simplified book or WeChat public number, and study with me.

Last article reading

  • Spring mind map makes Spring no longer difficult to understand (AOP)
  • Spring mind map makes Spring no longer difficult to understand (MVC)
  • Spring mind map makes Spring no longer difficult to understand (IOC)
  • Spring mind map makes spring no longer difficult to understand (1)