一.Redis環境搭建linux
系統默認是使用ConcurrentMapCacheManager,而後獲取和建立ConcurrentMapCache類型的緩存組件,再將數據保存在ConcurrentMap中redis
開發中使用緩存中間件:redis,memcached,ehcachespring
1.搭建redis環境docker
在linux上安裝redis(推薦使用docker)。docker安裝redis的技巧:使用國內鏡像能夠加速下載。數據庫
docker pull registry.docker-cn.com/library/redis
2.使用docker啓動redisjson
docker run -p 6379:6379 --name myredis -d registry.docker-cn.com/library/redis緩存
3.引入redis的starterapp
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
4.配置redismemcached
spring.redis.host=172.**.**.**
二.RedisTemplate的使用spring-boot
SpringBoot底層整合了spring-data-redis,裏面的StringRedisTemplate以及RedisTemplate都已經注入到容器中,使用的時候直接從容器中取出來便可。其中StringRedisTemplate封裝了redis對字符串的一些經常使用操做,RedisTemplate封裝了一些對象的經常使用操做。
1.StringRedisTemplate的使用
public void testStringRedis() { //redis保存數據 stringRedisTemplate.opsForValue().append("msg","hello"); //讀取數據 String msg = stringRedisTemplate.opsForValue().get("msg"); System.out.println(msg); //list存儲數據 stringRedisTemplate.opsForList().leftPush("mylist","1"); stringRedisTemplate.opsForList().leftPush("mylist","2"); stringRedisTemplate.opsForList().leftPush("mylist","3"); String mylist = stringRedisTemplate.opsForList().leftPop("mylist"); //刪除並查詢最頂層的list數據 System.out.println(mylist); }
2.RedisTemplate的使用
public void testRedis() { employeeRedisTemplate.opsForValue().set("emp-02",employeeMapper.getEmployeeById(2)); }
使用set方法保存查詢到的員工對象,執行完畢後發現有錯誤,這是由於Emp對象沒有被序列化,沒有序列化的對象是沒法存入redis數據庫。因此須要Emp實體類實現Serializable接口,將對象序列化再次執行發現有數據存儲到數據庫中,可是是以序列化的方式存儲的。
這樣存儲數據是有了,可是存在數據庫裏很不直觀,查詢數據的人沒法知道本身存了什麼數據進去,那麼如何解決序列化對象的問題呢?
redis存取序列化對象的解決方式
方式一:將數據以json形式保存,將對象轉爲json,轉成json對象後,就會以json的形式存儲到數據庫中。
方式二:改變默認的序列化規則,因爲默認使用jdk的序列化器,切換使用json的序列化器便可解決序列化問題
@Configuration public class MyRedisConfig { @Bean public RedisTemplate<Object, Employee> empRedisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { RedisTemplate<Object, Employee> template = new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory); Jackson2JsonRedisSerializer<Employee> serializer = new Jackson2JsonRedisSerializer(Employee.class); template.setDefaultSerializer(serializer); return template; } }
使用的時候注入該類,使用這個類來調用set方法便可將Emp對象存到數據庫裏
@Autowired
RedisTemplate<Object, Employee> employeeRedisTemplate;
public void testRedis() {
employeeRedisTemplate.opsForValue().set("emp-02",employeeMapper.getEmployeeById(2));
}
三.測試Redis緩存
1.默認使用ConcurrentMapCacheManager緩存組件來實際給緩存中存取數據。引入redis的starter以後,容器中保存的是RedisCacheManager,開啓debug日誌報告,能夠搜索已經開啓了的 org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration,原來的SimpleCacheConfiguration將再也不匹配。
2.RedisCacheManager幫咱們建立RedisCache來做爲緩存組件,RedisCache經過操做redis來操做緩存數據,原來的緩存替換爲redis緩存,註解配置都同樣,區別是緩存的內容都存到配置好的redis數據庫了。
3.默認保存數據k-v都是object,利用序列化保存,因此須要反序列化,將其保存爲json
1)、引入了redis的starter,cacheManager變爲RedisCacheManager
2)、默認建立的RedisCacheManager操做redis的時候使用的是RedisTemplate<Object,Object>
3)、RedisTemplate<Object,Object>默認使用jdk的序列化機制,因此會亂碼
4)、自定義CacheManager(springboox1.x的版本和這個有區別,這邊給出的是2.x的例子)
//容器會自動檢測到這個CacheManager,並替換原來自帶的CacheManager @Primary //若配置多個緩存管理器須要有一個默認的緩存管理器 @Bean public RedisCacheManager myCacheManager(RedisConnectionFactory redisConnectionFactory){ RedisSerializer<String> redisSerializer = new StringRedisSerializer(); //.entryTtl(Duration.ofHours(1)); // 設置緩存有效期一小時 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); // 配置序列化(解決亂碼的問題) RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)) .disableCachingNullValues(); RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory) .cacheDefaults(config) .build(); return cacheManager; }
注意多個緩存管理器時,若須要引入緩存管理器能夠在類註解上@CacheConfig(cacheNames = "emp",cacheManager = "myCacheManager") 配置。
使用編碼的方式進行緩存
上面講的都是採用註解的方式進行緩存的,實際生產過程當中也能夠採用編碼的方式進行緩存。
1) 注入緩存管理器
@Qualifier("myCacheManager")
@Autowired
RedisCacheManager myCacheManager;
2) 編碼緩存
public Department getDept(Integer id){ Department department = departmentMapper.getDepartmentById(id); Cache dept = myCacheManager.getCache("dept"); //獲取某個緩存 dept.put("dept:1",department); return departmentMapper.getDepartmentById(id); }