/*springboot-version 2.4.4 */
@SpringBootTest
public class MybatiscacheApplicationTests {
//注意stringRedisTemplate是api存储的值,不能使用redisTemplate的api取值
//除非指定了 redisTemplate.setKeySerializer(new StringRedisSerializer());
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Autowired
private RedisTemplate redisTemplate;
@Test
public void testStringRedisTemplate() {
User userPO = new User(1111L,"小明_testRedis1","12121");
List<Object> list = new ArrayList<>();
for(int i=0;i<200;i++){
list.add(userPO);
}
}
//测试JdkSerializationRedisSerializer,GenericJackson2JsonRedisSerializer,Jackson2JsonRedisSerializer,FastJson2JsonRedisSerializer
@Test
public void testSerializableTiem(){
User userPO = new User(1111L,"小明_testRedis1","12121");
List<Object> list = new ArrayList<>();
for(int i=0;i<200;i++){
list.add(userPO);
}
/*
JdkSerializationRedisSerializer j = new JdkSerializationRedisSerializer();
Long j_s_start = System.currentTimeMillis();
byte[] bytesJ = j.serialize(list);
System.out.println("JdkSerializationRedisSerializer序列化时间:"+(System.currentTimeMillis()-j_s_start) + "ms,序列化后的长度:" + bytesJ.length);
Long j_d_start = System.currentTimeMillis();
Object JDKDeserialize = j.deserialize(bytesJ);
List<User> jDKList =(List<User>) JDKDeserialize;
System.out.println("JdkSerializationRedisSerializer反序列化时间:"+(System.currentTimeMillis()-j_d_start));
jDKList.forEach(System.out::println);*/
/*
GenericJackson2JsonRedisSerializer g = new GenericJackson2JsonRedisSerializer();
Long g_s_start = System.currentTimeMillis();
byte[] bytesG = g.serialize(list);
System.out.println("GenericJackson2JsonRedisSerializer序列化时间:"+(System.currentTimeMillis()-g_s_start) + "ms,序列化后的长度:" + bytesG.length);
Long g_d_start = System.currentTimeMillis();
Object gDserialize = g.deserialize(bytesG);
System.out.println("GenericJackson2JsonRedisSerializer反序列化时间:"+(System.currentTimeMillis()-g_d_start));
List<User> gList =(List<User>)gDserialize;
gList.forEach(System.out::println);*/
/*
Jackson2JsonRedisSerializer j2 = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);方法過期,下面是替换方案
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance , ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
j2.setObjectMapper(objectMapper);
Long j2_s_start = System.currentTimeMillis();
byte[] bytesJ2 = j2.serialize(list);
System.out.println("Jackson2JsonRedisSerializer序列化时间:"+(System.currentTimeMillis()-j2_s_start) + "ms,序列化后的长度:" + bytesJ2.length);
Long j2_d_start = System.currentTimeMillis();
Object jacksonDeserialize = j2.deserialize(bytesJ2);
System.out.println("Jackson2JsonRedisSerializer反序列化时间:"+(System.currentTimeMillis()-j2_d_start));
List<User> jacksonList = (List<User>) jacksonDeserialize;
jacksonList.forEach(System.out::println);
*/
//这个是自定的fastjson解析类
FastJson2JsonRedisSerializer f =new FastJson2JsonRedisSerializer(Object.class);
Long f_s_start = System.currentTimeMillis();
String s = JSON.toJSONString(list, SerializerFeature.DisableCircularReferenceDetect);
byte[] bytesF= f.serialize(s);
System.out.println("FastJsonRedisSerializer序列化时间:"+(System.currentTimeMillis()-f_s_start) + "ms,序列化后的长度:" + bytesF.length);
Long f_d_start = System.currentTimeMillis();
Object deserialize = f.deserialize(bytesF);
System.out.println();
System.out.println(deserialize);
List lists = JSONObject.parseArray((String) deserialize, List.class);
String s1 = JSON.toJSONString(deserialize);
System.out.println("FastJsonRedisSerializer反序列化时间:"+(System.currentTimeMillis()-f_s_start));
}
@Test
public void testSerlSerial1() {
User userPO = new User(1111L, "小明_testRedis1", "12121");
List<Object> list = new ArrayList<>();
for (int i = 0; i < 200; i++) {
list.add(userPO);
}
//key一般默认是默认的字符串序列化 new StringRedisSerializer()
redisTemplate.setKeySerializer(new StringRedisSerializer());
//1.默认jdk序列化,key和value都是
//JdkSerializationRedisSerializer j = new JdkSerializationRedisSerializer();
/*redisTemplate.opsForValue().set("jdkusers", list);
List<User> jdkusers =(List<User>) redisTemplate.opsForValue().get("jdkusers");
jdkusers.forEach(System.out::println);*/
//2. GenericJackson2JsonRedisSerializer序列化
// GenericJackson2JsonRedisSerializer g = new GenericJackson2JsonRedisSerializer();
/*redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.opsForValue().set("gusers",list);
List<User> gusers =(List<User>) redisTemplate.opsForValue().get("gusers");
gusers.forEach(System.out::println);*/
//3.Jackson2JsonRedisSerializer序列化
/* Jackson2JsonRedisSerializer j2 = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);方法過期
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
j2.setObjectMapper(objectMapper);
redisTemplate.setValueSerializer(j2);
redisTemplate.opsForValue().set("jusers",list);
List<User> jusers =(List<User>) redisTemplate.opsForValue().get("jusers");
jusers.forEach(System.out::println);*/
//4.FastJsonRedisSerializer序列化
FastJson2JsonRedisSerializer f = new FastJson2JsonRedisSerializer(Object.class); ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);方法過期
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
f.setObjectMapper(objectMapper);
redisTemplate.setValueSerializer(f);
redisTemplate.afterPropertiesSet();
redisTemplate.opsForValue().set("fusers",list);
List<User> fusers =(List<User>) redisTemplate.opsForValue().get("fusers");
fusers.forEach(System.out::println);
/* Long f_s_start = System.currentTimeMillis();
String s = JSON.toJSONString(list, SerializerFeature.DisableCircularReferenceDetect);
byte[] bytesF= f.serialize(s);
System.out.println("FastJsonRedisSerializer序列化时间:"+(System.currentTimeMillis()-f_s_start) + "ms,序列化后的长度:" + bytesF.length);
Long f_d_start = System.currentTimeMillis();
Object deserialize = f.deserialize(bytesF);
System.out.println();
System.out.println(deserialize);
List lists = JSONObject.parseArray((String) deserialize, List.class);
String s1 = JSON.toJSONString(deserialize);
System.out.println("FastJsonRedisSerializer反序列化时间:"+(System.currentTimeMillis()-f_s_start));
}*/
}
}
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T> {
private ObjectMapper objectMapper = new ObjectMapper();
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class<T> clazz;
static {
ParserConfig.getGlobalInstance().setAutoTypeSupport(true);
//如果遇到反序列化autoType is not support错误,请添加并修改一下包名到bean文件路径
// ParserConfig.getGlobalInstance().addAccept("com.xxxxx.xxx");
}
public FastJson2JsonRedisSerializer(Class<T> clazz) {
super();
this.clazz = clazz;
}
public byte[] serialize(T t) throws SerializationException {
if (t == null) {
return new byte[0];
}
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
public T deserialize(byte[] bytes) throws SerializationException {
if (bytes == null || bytes.length <= 0) {
return null;
}
String str = new String(bytes, DEFAULT_CHARSET);
return JSON.parseObject(str, clazz);
}
public void setObjectMapper(ObjectMapper objectMapper) {
Assert.notNull(objectMapper, "'objectMapper' must not be null");
this.objectMapper = objectMapper;
}
protected JavaType getJavaType(Class<?> clazz) {
return TypeFactory.defaultInstance().constructType(clazz);
}
}
测试JdkSerializationRedisSerializer,GenericJackson2JsonRedisSerializer,Jackson2JsonRedisSerializer,FastJson2JsonRedisSerializer的性能比较,选择看自己的业务需求,
注释:上诉fastjson注入的同一个对象,在redis的储存的json对象会是这样的;
"password":"12121","username":"小明_testRedis1"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"},{"$ref":"$[0]"}......
其原因是:
**
用同一个对象,进行赋值插入list集合中,然后,集合中虽然是不同对象,但是对象的hashcode是同样,所以用toString打印是显示不同,但是用json解析就不一样了!
**
这位大佬已经说明了:
[fastjson异常显示{"
r
e
f
"
:
"
ref":"
ref":"[0]"},{"
r
e
f
"
:
"
ref":"
ref":"[0]"}]](https://blog.csdn.net/hlw521hxq/article/details/88048481)