redis估计都不陌生了吧,如果不知道的可以去看我以前的文章进行查看,今天我们看看springboot使用redis最为缓存是如何使用的
ok直接看代码,具体细节代码中讲授一二
1.引入pom.xml。前提说下这里使用的mybatis的文件是这样的:
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.1</version> </dependency>
如果这里是高版本的当我们自定义配置cache的方式就不是本文章所看到的那样了
2.spring.application的配置文件
spring.datasource.url=jdbc:mysql://localhost:3306/spring-boot-cache?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.password=123 spring.datasource.username=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver #开启驼峰mybatis.configuration.map-underscore-to-camel-case=trues pring.redis.host=127.0.0.1
3.redis的配置类:
package com.kayleoi.springbootcache.config;
?
import com.kayleoi.springbootcache.bean.Department;
import com.kayleoi.springbootcache.bean.Employee;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ResourceLoader;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
?
import java.net.UnknownHostException;
import java.util.LinkedHashSet;
import java.util.List;
?
/*** @Author kay三石* @date:2019/8/3* 当有多个缓存管理器时,必须指定一个默认的缓存管理器* @Primary 指定默认的缓存管理器,这里我们话应该使用spring中自带的(不加会出现以下错误)* java.lang.IllegalStateException: No CacheResolver specified, and no unique bean of type CacheManager found.* Mark one as primary or declare a specific CacheManager to use.*需要使用低版本的对于2.0.0以上的版本使用方法不是这样的*/
@Configuration
public class MyRedisConfig {/*** 用自己的CacheManager 为 employee序列化缓存*@Primary 将某个缓存管理器设为默认的* @param* @return*/@Beanpublic RedisCacheManager employeeCacheManager(RedisTemplate<Object,Employee> empRedisTemplate) {RedisCacheManager cacheManager = new RedisCacheManager(empRedisTemplate);//key 使用前缀,将CacheName最为前缀cacheManager.setUsePrefix(true);return cacheManager;}/*** 用自己的CacheManager 为 depart序列化缓存管理器* @param* @return*/@Beanpublic RedisCacheManager departmentCacheManager(RedisTemplate<Object,Department> depRedisTemplate) {RedisCacheManager cacheManager = new RedisCacheManager(depRedisTemplate);//key 使用前缀,将CacheName最为前缀cacheManager.setUsePrefix(true);return cacheManager;}
?/*** 使用自己的将object对象转化为json* @param redisConnectionFactory* @return* @throws UnknownHostException*/@Beanpublic RedisTemplate<Object,Employee> empRedisTemplate(RedisConnectionFactory redisConnectionFactory)throws UnknownHostException {RedisTemplate<Object, Employee> template = new RedisTemplate <>();template.setConnectionFactory(redisConnectionFactory);template.setDefaultSerializer(new Jackson2JsonRedisSerializer <Employee>(Employee.class));return template;}
?@Beanpublic RedisTemplate<Object, Department> depRedisTemplate(RedisConnectionFactory redisConnectionFactory)throws UnknownHostException {RedisTemplate<Object, Department> template = new RedisTemplate <>();template.setConnectionFactory(redisConnectionFactory);template.setDefaultSerializer(new Jackson2JsonRedisSerializer <Department>(Department.class));return template;}
?/*** 选择redis作为默认缓存工具* @param redisTemplate* @return*/@Primary@Beanpublic RedisCacheManager cacheManager(RedisTemplate redisTemplate) {RedisCacheManager caheManager = new RedisCacheManager(redisTemplate);return caheManager;}
}
?
/*** 默认使用时ConcurrentMapCacheManager == ConcurrentMapCache 将数据保存到ConcurrentMap<Object,Object>* 实际开发中使用的是 中间件, redis,ehcache** redis 测试缓存,原理 CacheManager === Cache 将组件来实际给缓存存取数据* 引入redis的start后容器所用的是RedisCacheManager* RedisCacheManager 帮我们创建 RedisCache来作为缓存组件* 默认保存数据 k,v 都是object 利用序列化转化为json* 1.引入redis的start后CacheManager变为 RedisCacheManager* 2.默认创建的 RedisCacheManager 操作redis的时候使用的是 RedisTemplate<Object,Object>* 3.RedisTemplate<Object, Object>是默认使用jdk的序列化机制* 自定义CacheManager:**/
?
@SpringBootApplication
@MapperScan("com.kayleoi.springbootcache.mapper")
@EnableCaching
public class SpringBootCacheApplication {
?public static void main(String[] args) {SpringApplication.run(SpringBootCacheApplication.class, args);}
?
}
?
service层:
package com.kayleoi.springbootcache.service;
?
import com.kayleoi.springbootcache.bean.Employee;
import com.kayleoi.springbootcache.mapper.EmployeeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.*;
import org.springframework.stereotype.Service;
?
/*** @Author kay三石* @date:2019/7/22* @CacheConfig(cacheNames = "emp") 抽取缓存的公共配置* 原理:* 1.自动配置类:CacheAutoConfiguration* 2.缓存的配置类:** 3.默认的配置类:SimpleCaCheConfiguration* 当写了多个cacheManager 的需要指定哪个管理器使用的* 当使用了不同的管理器时,需要指定一个默认的缓存管理器,要不然不会找到自己写的缓存管理器**/
@CacheConfig(cacheNames = "emp", cacheManager = "employeeCacheManager")
@Service
public class EmployeeService {
?@AutowiredEmployeeMapper employeeMapper;
?/*** 属性:* cacheNames/value: 执行缓存组件的名字,将方法的返回结果放到哪个缓存中是数组方式,可指定多个缓存* key: 缓存数据使用的key,可以用来指定默认使用方法参数的值,1-方法的返回值* 编写spel: # id: 参数id的值, #a0 #p0 #root.args[0]* 执行使用的key :key = "#root.methodName+'['+#id+']'" ====getEmployee(id)* keyGenerator:key的生成器,可以自己指定key的生成器的组件的id* key/keyGenerator二则选一使用* <p>* cacheManager: 指定缓存管理器,或者cacheResolver指定获取解析器* condition: 指定符合条件的情况下才缓存 condion= "#id >0 and #id <10"* unless: 否定缓存,当unless指定条件为true时,方法的返回值就不会被缓存,可以获取到结果进行判断* unless = "#result == null"* unless = "#a0==2" 如果第一个参数为2时则不缓存* sync: 是否使用异步的方式** @param id* @return*/@Cacheable(value = {"emp"}, key = "#root.methodName+'['+#id+']'")public Employee getEmployee(Integer id) {//用默认的需要序列化System.out.println("查询数据库");Employee empById = employeeMapper.getEmpById(id);return empById;}
?/*** 指定缓存** @param id* @return*/@Cacheable(value = {"emp2"}, keyGenerator = "myKeyGenerator", condition = "#a0>0", unless = "#a0==2")public Employee getEmployee2(Integer id) {Employee empById = employeeMapper.getEmpById(id);return empById;}
?/*** @CachePut: 调用方法,又更新缓存 ,修改的同时更新(同步更新缓存)* 运行实机:* 1.先调用目标方法* 2.将目标方法的结果缓存起来* 方法运行后将结果放入** 调式步骤:* 1.查询1号员工,查到的结果放入缓存中:* key :1 value: lastName:* 2. 以后查询还是之前的结果* 3. 更新1号员工,* 将方法的返回值放入了缓存 key:传入的emplyee对象,返回的也是对象* 4. 查询1号员工* 应该是更新后的员工* key = "#employee.id" 使用传入参数的id* key = "#result.id" 使用返回值的id* @Caheable的key不能使用#result* 但为什么是没有更新前呢?【1号员工没有在缓冲中更新,就是缓存中没有这个key】*/@CachePut(value = {"emp"}, key = "#employee.id")public Employee update(Employee employee){System.out.println("employee = [" + employee + "]");employeeMapper.updateEmp(employee);return employee;
?}
?/*** 清除缓存* key:指定清除的数据* allEntries = true 指定清除这缓存中的所有的数据* beforeInvocation = false:* 默认是方法执行之后执行,如果出现异常缓存不会清除** beforeInvocation = true* 代表清除缓存操作是在方法运行之前执行,无论方法是否出现异常,缓存都清除*** @param id*/@CacheEvict(value = "emp",beforeInvocation = true, key = "#id")public void deleteEmp(Integer id){employeeMapper.deleteEmById(id);}@Caching(cacheable = {@Cacheable(value = "emp", key = "#lastName")},put = {@CachePut(value = "emp", key = "#result.id"),@CachePut(value = "emp", key = "#result.email")})public Employee getEmployeeByName(String lastName){return employeeMapper.getEmpByName(lastName);}
}
?
通过以上的配置的代码可以实现redis操作缓存数据。