需求:查询数据要先从本地缓存中查询,查询不到的话在从Redis中 查询,Redis查询不到在查询数据库
package com.jt.reids.controller;
import com.jt.reids.dao.Tag;
import com.jt.reids.service.TagService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@RestController
@RequestMapping("/tag")
public class TagController {
@Autowired
private TagService tagService;
private List tags = new CopyOnWriteArrayList<>();//线程安全的
@GetMapping()
public List doselectTags(){
if(tags.isEmpty()){//所有请求都能进来
synchronized (tags){
if(tags.isEmpty()){
tags.addAll(tagService.selectTags());
}
}
}
return tags;
}
}
Service中AOP方式缓存应用
目标:简化缓存代码的编写
解决方案:基于AOP(面向切面编程)方式实现缓存应用
实践步骤:
第一步:在启动上类添加@EnableCaching注解(开启AOP方式的缓存配置),例如:
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.net.UnknownHostException;
@EnableCaching
@SpringBootApplication
public class RedisApplication {
public static void main(String[] args) {
SpringApplication.run(RedisApplication.class, args);
}
第二步:重构TagServiceImpl中的selectTags()方法,方法上使用@Cacheable注解,例如:
@Cacheable(value = "tagCache") @Override public List自定义redis数据库中key和value:selectTags() { return tagMapper.selectList(null); }
RedisTemplate默认采用的是JDK的序列化方式,假如对系统对序列化做一些调整,可以自己定义RedisTemplate对象
package com.jt.reids.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.net.UnknownHostException;
public class RedisCacheConfig {
@Bean
//代码定制参考RedisAutoConfiguration类
public RedisTemplate
自定义redis数据库中key和value:(Aop方式)
package com.jt.blog.damain.config;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public CacheManager cacheManager(RedisConnectionFactory connectionFactory){
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.serializeKeysWith(RedisSerializationContext.SerializationPair.
fromSerializer(new StringRedisSerializer()))
.serializevaluesWith(RedisSerializationContext.SerializationPair.
fromSerializer(new Jackson2JsonRedisSerializer(Object.class)));
return RedisCacheManager.builder(connectionFactory).
cacheDefaults(config).
transactionAware().
build();
}
}
MapperObject的使用
@SpringBootTest
public class MapperObject {
@Test
void testJson02() throws JsonProcessingException {
//可以做面试题
Tag tag = new Tag();
tag.setId(01L);
tag.setName("mary");
List list = new ArrayList<>();
list.add(tag);
tag.setId(02L);
tag.setName("jack");
ObjectMapper objectMapper = new ObjectMapper();
//将所有的访问修饰符(private,public>>>)对应的get方法
//获取其名字和值作为json字符串内容
objectMapper.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.ANY);
//激活默认类型(json串中的存贮对象类型)作用是保证序列化和反序列化保持类型一致如果没有这句话List会变成linkedHashMap
objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypevalidator(),
ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
//将对象转换为json格式字符串时,会调用对象的get方法
String s = objectMapper.writevalueAsString(list);
List list1 = objectMapper.readValue(s, List.class);
System.out.println(s);
//System.out.println(list1.getClass());
//反序列化时查看类型
for (Object o : list1) {
System.out.println(o.getClass());
}
}



