Jedis与RedisTemplate的区别:
Jedis是Redis官方推荐的面向Java的操作Redis的客户端,可以用JedisPool来获得连接进行get、set、del等操作相对简单,而RedisTemplate是SpringDataRedis中对JedisApi的高度封装。
SpringDataRedis相对于Jedis来说可以方便地更换Redis的Java客户端,比Jedis多了自动管理连接池的特性,方便与其他Spring框架进行搭配使用如:SpringCache
参考:https://blog.csdn.net/varyall/article/details/83476970
redisTemplate与stringRedisTemplate的区别
第一点,StringRedisTemplate继承了RedisTemplate。
第二点,RedisTemplate是一个泛型类,而StringRedisTemplate则不是。
第三点,StringRedisTemplate只能对key=String,value=String的键值对进行操作,RedisTemplate可以对任何类型的key-value键值对操作。
第四点,是他们各自序列化的方式不同,但最终都是得到了一个字节数组,殊途同归,StringRedisTemplate使用的是StringRedisSerializer类;RedisTemplate使用的是JdkSerializationRedisSerializer类。反序列化,则是一个得到String,一个得到Object
这两个类是springboot-data-redis对Redis进行操作的实现类。
打开StringRedisTemplate和RedisTemplate的源码,发现StringRedisTemplate继承了RedisTemplate,一般来说子类应该比父类有用更强大的功能,而此处却不是,因为RedisTemplate是泛型类,而在StringRedisTemplate继承RedisTemplate类时,则是指定了泛型的类型,两个String。
这就直接导致了,StringRedisTemplate只能处理String-String的键值对数据,而RedisTemplate则可以处理任何类型的键值对。
RedisTemplate源码:
public class RedisTemplate extends RedisAccessor implements RedisOperations, BeanClassLoaderAware {}
StringRedisTemplate源码:
public class StringRedisTemplate extends RedisTemplate {}
参考:https://jingyan.baidu.com/article/f7ff0bfcc5c4152e26bb13bc.html
/**
* Constructs a new StringRedisTemplate
instance. {@link #setConnectionFactory(RedisConnectionFactory)}
* and {@link #afterPropertiesSet()} still need to be called.
*/
public StringRedisTemplate() {
setKeySerializer(RedisSerializer.string());
setValueSerializer(RedisSerializer.string());
setHashKeySerializer(RedisSerializer.string());
setHashValueSerializer(RedisSerializer.string());
}
在redisTemplate中采用的序列化机制默认都是JdkSerializationRedisSerializer,源码:
@Override
public void afterPropertiesSet() {
super.afterPropertiesSet();
boolean defaultUsed = false;
if (defaultSerializer == null) {
defaultSerializer = new JdkSerializationRedisSerializer(
classLoader != null ? classLoader : this.getClass().getClassLoader());
}
if (enableDefaultSerializer) {
if (keySerializer == null) {
keySerializer = defaultSerializer;
defaultUsed = true;
}
if (valueSerializer == null) {
valueSerializer = defaultSerializer;
defaultUsed = true;
}
if (hashKeySerializer == null) {
hashKeySerializer = defaultSerializer;
defaultUsed = true;
}
if (hashValueSerializer == null) {
hashValueSerializer = defaultSerializer;
defaultUsed = true;
}
}
if (enableDefaultSerializer && defaultUsed) {
Assert.notNull(defaultSerializer, "default serializer null and not all serializers initialized");
}
if (scriptExecutor == null) {
this.scriptExecutor = new DefaultScriptExecutor<>(this);
}
initialized = true;
}
而在StringRedisTemplate中默认采用的序列化机制是:StringRedisSerializer,源码:
/**
* Constructs a new StringRedisTemplate
instance. {@link #setConnectionFactory(RedisConnectionFactory)}
* and {@link #afterPropertiesSet()} still need to be called.
*/
public StringRedisTemplate() {
setKeySerializer(RedisSerializer.string());
setValueSerializer(RedisSerializer.string());
setHashKeySerializer(RedisSerializer.string());
setHashValueSerializer(RedisSerializer.string());
}
/**
* Obtain a simple {@link java.lang.String} to {@literal byte[]} (and back) serializer using
* {@link java.nio.charset.StandardCharsets#UTF_8 UTF-8} as the default {@link java.nio.charset.Charset}.
*
* @return never {@literal null}.
* @since 2.1
*/
static RedisSerializer string() {
return StringRedisSerializer.UTF_8;
}
public static final StringRedisSerializer UTF_8 = new StringRedisSerializer(StandardCharsets.UTF_8);
无论是JdkSerializationRedisSerializer还是StringRedisSerializer都实现泛型接口RedisSerializer, 源码:
/**
* Basic interface serialization and deserialization of Objects to byte arrays (binary data). It is recommended that
* implementations are designed to handle null objects/empty arrays on serialization and deserialization side. Note that
* Redis does not accept null keys or values but can return null replies (for non existing keys).
*
* @author Mark Pollack
* @author Costin Leau
* @author Christoph Strobl
*/
public interface RedisSerializer {}
/**
* Java Serialization Redis serializer. Delegates to the default (Java based) {@link DefaultSerializer serializer} and
* {@link DefaultDeserializer}. This {@link RedisSerializer serializer} can be constructed with either custom
* {@link ClassLoader} or own {@link Converter converters}.
*
* @author Mark Pollack
* @author Costin Leau
* @author Mark Paluch
* @author Christoph Strobl
*/
public class JdkSerializationRedisSerializer implements RedisSerializer
除此外,spring-data-redis中还有几个也实现了RedisSerializer接口的序列化类,它们之间的区别如下:
GenericToStringSerializer: 可以将任何对象泛化为字符串并序列化
Jackson2JsonRedisSerializer: 跟JacksonJsonRedisSerializer实际上是一样的
JacksonJsonRedisSerializer: 序列化object对象为json字符串,jackson-json工具提供了javabean与json之间的转换能力,可以将pojo实例序列化成json格式存储在redis中,也可以将json格式的数据转换成pojo实例。因为jackson工具在序列化和反序列化时,需要明确指定Class类型,因此此策略封装起来稍微复杂。【需要jackson-mapper-asl工具支持】
JdkSerializationRedisSerializer: 序列化java对象(被序列化的对象必须实现Serializable接口),使用JDK本身序列化机制,将pojo类通ObjectInputStream/ObjectOutputStream进行序列化操作,最终redis-server中将存储字节序列。是目前最常用的序列化策略
StringRedisSerializer: 简单的字符串序列化,根据指定的charset对数据的字节序列编码成string,是“new String(bytes, charset)”和“string.getBytes(charset)”的直接封装。是最轻量级和高效的策略。
GenericToStringSerializer:类似StringRedisSerializer的字符串序列化
GenericJackson2JsonRedisSerializer:类似Jackson2JsonRedisSerializer,但使用时构造函数不用特定的类
OxmSerializer:提供了将javabean与xml之间的转换能力,目前可用的三方支持包括jaxb,apache-xmlbeans;redis存储的数据将是xml工具。不过使用此策略,编程将会有些难度,而且效率最低;不建议使用。【需要spring-oxm模块的支持】
ObjectMapper objectMapper = new ObjectMapper();
/**序列化的时候序列对象的所有属性
* Include.ALWAYS 是序列化对像所有属性
* Include.NON_NULL 只有不为null的字段才被序列化
* Include.NON_EMPTY 如果为null或者 空字符串和空集合都不会被序列化
* /
objectMapper.setSerializationInclusion(Include.ALWAYS);
//反序列化的时候如果多了其他属性,不抛出异常
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//如果是空对象的时候,不抛异常
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
//取消时间的转化格式,默认是时间戳,可以取消,同时需要设置要表现的时间格式
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
// 属性访问器可以访问任何属性,jackson的自动检测机制可以任何级别的字段都可以识别
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY)
// 非final类型
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL)
jackson 1.x和2.x版本的注解是放置在不同的包下的
1.x是在jackson core jar包org.codehaus.jackson.annotate下
2.x是在jackson-databind包com.fasterxml.jackson.annotation下
https://blog.csdn.net/xiaoyu411502/article/details/45001317
spring.redis.host=
spring.redis.port=
# 连接池中最少空闲的连接数
spring.redis.jedis.pool.min-idle=
# 当连接池资源耗尽时,调用者最大的阻塞时间,超出时将抛出异常。单位:ms,默认-1,表示永不超时
spring.redis.jedis.pool.max-wait=
# 连接池的最大数据库连接数。设为0表示无限制,如果是jedis 2.4以后用redis.maxTotal
spring.redis.jedis.pool.max-active=
# 连接池中最大空闲的连接数数
spring.redis.jedis.pool.max-idle=
spring.redis.database=
spring.redis.timeout=