Spring Boot 8.5 Data Cache

Keywords: Spring Ehcache Database Redis

We know that the bottleneck of a program is the database. We also know that the speed of memory is much faster than that of hard disk. When we need to retrieve the same data repeatedly, we request database or remote service again and again, which leads to a large amount of time consuming in data query or remote method invocation, resulting in deterioration of program performance, which is the problem to be solved by data caching.

8.5.1 Spring cache support

Spring defines an interface between org. spring framework. cache. CacheManager and org. spring framework. cache. Cache to unify different caches. Cache Manager is the abstract interface of various caching technologies provided by Spring. Cache interface includes all kinds of operations of caching (adding, deleting and obtaining caches, we usually do not deal with this interface directly).

1.Spring-supported Cache Manager

For different caching technologies, different Cache Managers need to be implemented. Spring defines the implementation of Cache Manager as shown in the table.

CacheManager describe
SimpleCacheManager Use a simple Collection to store caches, mainly for testing purposes
ConcurrentMapCacheManager Use Concurrent Map to cache
NoOpCacheManager Testing purposes only, not actually storing caches
EhCacheCacheManager Using EhCache as Caching Technology
GuavaCacheManager Using Google Guava's Guava Cache as Caching Technology
HazelcastCacheManager Using Hazelcast as Caching Technology
JCacheCacheManager Supporting the implementation of JCache (jsr-107) standard as a caching technology, such as Apache Commons JCS
RedisCacheManager Using Redis as Caching Technology

When we use Cache Manager of any implementation, we need to register the Bean of the implemented Cache Manager, for example:

@Bean
public EhCacheCacheManager cacheManager(CacheManager ehCacheCacheManager) {
  return new EhCacheCacheManager(ehCacheCacheManager);
}

Of course, there are many additional configurations for each caching technology, but configuring the cache manager is essential.

2. Nominal Cache Annotations

Spring provides four annotations to declare caching rules (another vivid example of using annotated AOP). These four annotations are shown in the table.

annotation explain
@Cacheable Before the method is executed, Spring first checks whether there is data in the cache, and if there is data, returns the cached data directly; if there is no data, it calls the method and puts the method return value into the cache.
@CachePut In any case, the return value of the method is placed in the cache. @ CachePut's attributes are consistent with @Cacheable
@CacheEvict Delete one or more data from the cache
@Caching Multiple annotation strategies can be combined on one method through @Caching annotations
3. Open Famous Cache Support

It's easy to turn on fame caching support by simply using the @EnableCaching annotation on the configuration class, such as:

@Configuration
@EnableCaching
public class AppConfig{

}

8.5.2 Spring Boot support

The key to using caching technology in Spring is to configure Cache Manager, and Spring Boot automatically configures several Cache Manager implementations for us.
The automatic configuration of Spring Boot's Cache Manager is placed in the org.sprinframework.boot.autoconfigure.cache package, as shown in the figure

As you can see from the figure above, Spring Boot automatic configures EhCache Configuration (using EhCache), GenericCache Configuration (using Collection), Guava Cache Configuration (using Guava), Hazelcast Cache Configuration (using Hazelcast), Infinispan Cache Configuration (using Infinispan), JC Cache Configuration (using JCAC Cache Co.) He), NoOpCache Configuration (no storage), RedisCache Configuration (using Redis), SimpleCache Configuration (using Concurrent Map). Without any additional configuration, the default is SimpleCache Configuration, even with Concurrent Map Cache Manager. Spring Boot supports the configuration of caches with properties“ Spring. cache ".

spring.cache.type= # Optional generic,ehcache,hazelcast,infinispan,jcache,redis,guava,simple,none
spring.cache.cache-names=#Create a cache name at program startup
spring.cache.ehcache.config=#ehcache profile address
spring.cache.hazelcast.config=#hazelcast configuration file address
spring.cache.infinispan.config = # infinispan configuration file address
spring.cache.jcache.config = # jcache configuration file steep
spring.cache.jcache.provider = #When multiple jcache implementations are in the classpath, specify the jcache implementation
spring.cache.guava.spec = # guava specs

In Spring Book environment, using caching technology only needs to import dependency packages of related caching technology into the project and use @EnableCaching to open caching support in the configuration class.

8.5.3 Actual Warfare

This example uses Spring Boot's default Concurrent Map Cache Manager as the cache technology, demonstrates @Cacheable,@CachePut,@CacheEvit, and finally replaces the cache technology with EhCache and Guava.

1. New Spring Book Project

New Spring Book projects rely on Cache (spring-boot-starter-cache), JPA (spring-boot-starter-data-jpa) and Web (spring-boot-starter-web).

Project information:

groupId:com.wisely
arctifactId:ch8_5
package:com.wisely.ch8_5

Add Oracle JDBC driver and configure related properties in application.properties, which is consistent with the previous example.

2. entity class
package com.wisely.ch8_5.domain;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Person {
	@Id
	@GeneratedValue
	private Long id;
	
	private String name;
	
	private Integer age;
	
	private String address;

	public Person() {
		super();
	}

	public Person(Long id, String name, Integer age, String address) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.address = address;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}
	
	

}

3. Entity class Repository
package com.wisely.ch8_5.dao;

import org.springframework.data.jpa.repository.JpaRepository;

import com.wisely.ch8_5.domain.Person;

public interface PersonRepository extends JpaRepository<Person, Long> {

}

4. Business Services
(1) Interface:
package com.wisely.ch8_5.service;

import com.wisely.ch8_5.domain.Person;

public interface DemoService {
	public Person save(Person person);
	
	public void remove(Long id);
	
	public Person findOne(Person person);

}


(2) Implementation class:
package com.wisely.ch8_5.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.wisely.ch8_5.dao.PersonRepository;
import com.wisely.ch8_5.domain.Person;
import com.wisely.ch8_5.service.DemoService;

@Service
public class DemoServiceImpl implements DemoService {
	
	@Autowired
	PersonRepository personRepository;

	@Override
	@CachePut(value="people" , key="#Person.id"/@CachePut caches newly added or updated data to the cache, where the cache name is people and the key of the data is the ID of person.
	public Person save(Person person) {
		Person p = personRepository.save(person);
		System.out.println("by id,key For:"+p.getId()+"Data is cached");
		return p;
	}

	@Override
	@CacheEvict(value="people",key="#person.id"// Delete the data whose key is ID from the cache people.
	public void remove(Long id) {
		System.out.println("Deleted id,key by"+id+"Data caching");
		personRepository.deleteById(id);
	}

	@Override
	@CacheEvict(value="people",key="#id "// Delete the data whose key is id from the cache people.
	public void remove(Long id) {

		System.out.println("Deleted id,key by"+id+"Data caching");

	}

}

5. controller
package com.wisely.ch8_5.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.wisely.ch8_5.domain.Person;
import com.wisely.ch8_5.service.DemoService;

@RestController
public class CacheController {
	
	@Autowired
	DemoService demoService;
	
	@RequestMapping("/put")
	public Person put(Person person) {
		return demoService.save(person);
	}
	
	@RequestMapping("/able")
	public Person cacheable(Person person) {
		return demoService.findOne(person);
	}
	
	@RequestMapping("/evit")
	public String evit(Long id) {
		demoService.remove(id);
		
		return "ok";
	}

}

6. Turn on cache support
package com.wisely.ch8_5;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching      //Turn on cache support
public class Ch885Application {

	public static void main(String[] args) {
		SpringApplication.run(Ch885Application.class, args);
	}

}

7. operation

When we cache the data, the data will be obtained from the cache, not from the database. The data situation of the current database is shown in the figure.

We restarted the application every time we ran the test.

(1) Test @Cacheable

The first visit to http://localhost:8080/able?id=1, the first call method queries the database, and puts the data into the cache people.
At this time, the console output is as follows:

The page output is as follows


Re-visit http://localhost:8080/able?id=1. At this time, the console does not output Hibernate's query statement again, and the words "cached for id and key: 1 data" indicate that this method is not invoked, and the page obtains data directly from the data cache.
The output of the page is as follows

(2) Test @CachePut

Visit http://localhost:8080/put?Name=cc&age=22&adress=Chengdu, and the console output is as follows:

The page output is shown in Figure 1.

We visited http://localhost:8080/able?id=4 again. The console had no output. We got the data directly from the cache. The page display was the same as the figure above.

(3) Test @CacheEvit

Visit http://localhost:8080/able?id=1 to cache the data with id 1, and then visit http://localost:8080/able?id=1 again to confirm that the data has been obtained from the cache.

Access http://localhost:8080/evit?id=1 and delete the cached data with key 1 from the cache

Visit http://localhost:8080/able?id=1 again and watch the console re-caching:

Posted by tempa on Sat, 04 May 2019 01:10:38 -0700