SpringBoot默认缓存配置案例及原理

一、搭建基本环境

1)、创建表

2)、创建javaBean封装数据

package com.zhq.springboot.bean;

public class Employee {
	
	private Integer id;
	private String lastName;
	private String email;
	private Integer gender; //性别 1男  0女
	private Integer dId;
	
	
	public Employee() {
		super();
	}

	
	public Employee(Integer id, String lastName, String email, Integer gender, Integer dId) {
		super();
		this.id = id;
		this.lastName = lastName;
		this.email = email;
		this.gender = gender;
		this.dId = dId;
	}
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public Integer getGender() {
		return gender;
	}
	public void setGender(Integer gender) {
		this.gender = gender;
	}
	public Integer getdId() {
		return dId;
	}
	public void setdId(Integer dId) {
		this.dId = dId;
	}
	@Override
	public String toString() {
		return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + ", dId="
				+ dId + "]";
	}
	
	

}

3)、整合MyBatis操作数据库

   配置数据源:

 @MapperScan指定需要扫描的mapper接口所在的包 :

 二、快速体验缓存案例

1)、编写Mapper接口

public interface EmployeeMapper {
    @Select("select * from employee where id=#{id}")
    public Employee getEmpById(Integer id);

}

2)、编写Service

@Service
public class EmployeeService {
    @Autowired
    EmployeeMapper employeeMapper;

    /**
     * 将方法的运行结果进行缓存:以后再要相同的数据,直接从缓存中获取,不用调用方法
     * CacheManager管理多个Cache组件的,对缓存的真正CRUD操作在Cache组件中,每一个缓存组件有自己唯一一个名字;
     * 几个属性:
     *      cacheNames/value:指定缓存组件的名字;
     *      key缓存数据时使用的key,可以用它来指定,默认是使用方法参数的值 eg:1-方法的返回值
     *        可编写SpEL表达式,eg:
     *        #id表示参数id的值 相当于#a0 #p0 #root.args[0]
     *      keyGenerator:key的生成器;可以自己指定key的生成器的组件id
     *      keyGenerator/key:二选一,用其中一个就行
     *      cacheManager:指定缓存管理器,或者指定缓存解析器cacheResolver
     *      condition:指定符合条件的情况下才缓存
     *      unless:否定缓存,当unless指定的条件为true,方法的返回值就不会被缓存;可以获取到结果集进行判断
     *          eg:unless="#result==null"
     *      sync:是否使用异步模式
     *
     * @param id
     * @return
     */
    @Cacheable(cacheNames = "emp",key = "#id",condition = "#id>0")
    public Employee getEmp(Integer id){
        System.out.println("查询"+id+"号员工");
        Employee emp = employeeMapper.getEmpById(id);
        return emp;
    }
}

3)、编写controller

@RestController
public class EmployeeController {
    @Autowired
    EmployeeService employeeService;
    @GetMapping("/emp/{id}")
    public Employee getEmp(@PathVariable("id") Integer id){
        Employee emp = employeeService.getEmp(id);
        return emp;
    }

}

4)、测试效果

多次查询id=2会发现数据库只查询了一次,其他的都是从缓存获取的结果

三、缓存实现原理

将方法的运行结果进行缓存;以后再要相同的数据,直接从缓存中获取,不用调用方法,CacheManager管理多个Cache组件的,对缓存的真正CRUD操作在Cache组件中,每一个缓存组件有自己唯一一个名字。

详细原理:

1)、查看自动配置类:CacheAutoConfiguration

2)、断点跟踪可知默认配置了:
     *   org.springframework.boot.autoconfigure.cache.GenericCacheConfiguration
     *   org.springframework.boot.autoconfigure.cache.JCacheCacheConfiguration
     *   org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration
     *   org.springframework.boot.autoconfigure.cache.HazelcastCacheConfiguration
     *   org.springframework.boot.autoconfigure.cache.InfinispanCacheConfiguration
     *   org.springframework.boot.autoconfigure.cache.CouchbaseCacheConfiguration
     *   org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration
     *   org.springframework.boot.autoconfigure.cache.CaffeineCacheConfiguration
     *   org.springframework.boot.autoconfigure.cache.GuavaCacheConfiguration
     *   org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration【默认】
     *   org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration

  默认SimpleCacheConfiguration生效

3)、给容器中注册了一个CacheManager:ConcurrentMapCacheManager;

4)、获取和创建ConcurrentMapCache类型的缓存组件,他的作用将数据保存在ConcurrentMap中;

5)、 运行流程:

  方法运行之前,先去查询Cache(缓存组件),按照cacheNames指定的名字获取,(CacheManager先获取相应的缓存),第一次获取缓存如果没有Cache组件会自动创建;

  去Cache中查找缓存的内容,使用一个key,默认就是方法的参数,key是按照某种策略生成的,默认是使用keyGenerator生成的,默认使用SimpleKeyGenerator生成key,SimpleKeyGenerator生成key的默认策略:如果没有参数:key=new SimpleKey();如果有一个参数:key=参数的值;如果有多个参数:key=new SimpleKey(params);
  没有查到缓存就调用目标方法,将目标方法返回的结果,放进缓存中,@Cacheable标注的方法执行之前先来检查缓存中有没有这个数据,默认按照参数的值作为key去查询缓存,如果没有就运行方法并将结果放入缓存,以后再来调用就可以直接使用缓存中的数据。


    

猜你喜欢

转载自blog.csdn.net/xm393392625/article/details/88625681