# redisdemo **Repository Path**: fysola/redisdemo ## Basic Information - **Project Name**: redisdemo - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2018-03-26 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 本项目用来演示redis在java中的基本用法,其中 jedis-api模块 ============== 演示官方提供的redis api的,即redis原生api的使用 基本使用方法 spring-redis模块 ================== 则演示在spring项目中如何配置使用redis, spring中的配置比较关键,包括以下配置项 * spring管理redis缓存管理器 * spring配置jedis 连接池配置 * redis的连接工厂 * spring data 提供 redis模板 ### spring data RedisTemplate 和 RedisSerializer > 当redis作为一种数据库使用的时候,和其他数据库一样,spring提供了`RedisTemplate`来进行通用的ACID操作, > 通常在spring配置下面三项,就可以使用spring的API操作redis了 ```xml ``` > 同时,spring 还提供了`StringRedisTemplate`进行ACID操作,与`RedisTemplate`的区别在于序列化类,`RedisTemplate`默认使用的是JdkSerializationRedisSerializer, > 而`StringRedisTemplate`默认使用的是StringRedisSerializer。 那么什么场景下要用RedisTemplate什么场景下又要用StringRedisSerializer呢? 或者说,什么场景要用JdkSerializationRedisSerializer进行序列化存储,什么场景又要用StringRedisSerializer进行序列化存储呢? 官方API如下解释: * StringRedisSerializer > Simple String to byte[] (and back) serializer. Converts Strings into bytes and vice-versa using the specified charset (by default UTF-8). > Useful when the interaction with the Redis happens mainly through Strings. > Does not perform any null conversion since empty strings are valid keys/values. 就是说当交互数据主要是string的时候,用StringRedisSerializer是很管用的 * JdkSerializationRedisSerializer > Java Serialization Redis serializer. Delegates to the default (Java based) serializer and DefaultDeserializer. This serializer can be constructed with either custom ClassLoader or own converters. 只说了采用的是基于java序列化类,并没有比较跟StringRedisSerializer的区别,结合StringRedisSerializer的描述,看来他们的区别 主要是性能问题了,如果大部分数据都是string类型,则用StringRedisSerializer[StringRedisSerializer], 而对于一般数据则用JdkSerializationRedisSerializer[RedisTemplate] > 注:redis提供了多种序列化的方式,关于序列化可以参考 https://blog.csdn.net/csdn_xuexiaoqiang/article/details/73650046 ### spring data redis 的 operator spring data 提供了RedisTemplate做ACID操作,但是并不是直接使用RedisTemplate对象来操作, 而是使用Operator来操作redis,通过RedisTemplate的opsForValueXXX()方法,可以为redis的五种数据类型返回对应的operator. * redisTemplate.opsForValue() - 返回用于操作string类型的operator * redisTemplate.opsForList() - 返回用于操作list类型的operator ### 在redis中存储对象 redis只能存储string和byte类型的数据,当要存储一个对象时,redis会将对象序列化之后存储。 使用spring data redis存储对象时,首先要保证对象是实现Serializable接口的,否则无法序列化, 同时,在利用redisTemplate创建redis的operators时,需要将使用Serializable类型来初始化redisTemplate,例如 ```java //key和value同时支持序列化的redisTemplate @Autowired private RedisTemplate redisTemplate; ``` spring-redis-cache模块 ================== ### 启用缓存及缓存注解 xml中可配置 ```xml ``` ### 配置缓存管理器及配置Redis缓存管理器 在上面配置缓存开启时,要配置一个缓存管理器,默认使用spring的SimpleCacheManager, 在spring data redis中则可以使用RedisCacheManager,RedisCacheManager则依赖redisTemplate配置, ```xml ``` ### 为方法添加注解以支持缓存 可以在xml文件中,使用配置的方式为每一个bean的方法配置缓存,则在缓存的有效期内调用bean的方法时,是读取缓存而不是调用方法的, 当然比较方便的做法是直接在方法上加注解,常用注解有, * @Cacheable - 声明Spring在调用方法之前,首先应该在缓存中查找方法的返回值。如果这个值能够找到,就会返回存储的值,否则的话,这个方法就会被调用,返回值会放在缓存之中 * @CachePut - 表明Spring应该将方法的返回值放到缓存中,在方法的调用前并不会检查缓存,方法始终都会被调用 * @CacheEvict -表明Spring应该在缓存中清除一个或多个条目 > allEntries属性, 表示是否需要清除缓存中的所有元素。默认为false,表示不需要. > beforeInvocation属性,可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素 * @Caching注解可以指定一个注解组合。其拥有三个属性:cacheable、put和evict,分别用于指定@Cacheable、@CachePut和@CacheEvict。 例如 ```java @Caching(cacheable = @Cacheable("users"), evict = { @CacheEvict("cache2"),@CacheEvict(value = "cache3", allEntries = true) }) public User find(Integer id) ``` 需要注意以下几点 * @Cacheable可以标记在一个方法上,也可以标记在一个类上,@Cacheable可以指定三个属性,value、key和condition * @Cacheable的value属性是必须指定的,其表示当前方法的返回值是会被缓存在哪个Cache上的,对应Cache的名称。其可以是一个Cache也可以是多个Cach,例如@Cacheable({"cache1", "cache2"}),则Cache是发生在cache1和cache2上的 * @Cacheable的key属性指定Spring缓存方法的返回结果时对应的key,spring有默认生成key的策略,我们自己也可以自定义策略,例如@Cacheable(value="users", key="#id") > 一些列子 ```java @Cacheable(value="users", key="#id") public User find(Integer id); @Cacheable(value="users", key="#p0") public User find(Integer id); @Cacheable(value="users", key="#user.id") public User find(User user); @Cacheable(value="users", key="#p0.id") public User find(User user); ``` 而spring的默认策略,则是使用root对象,例如 ```java @Cacheable(value={"users", "xxx"}, key="#root.caches[1].name") public User find(User user) { ``` * condition属性指定发生的条件 > 有的时候我们可能并不希望缓存一个方法所有的返回结果。通过condition属性可以实现这一功能 如下示例表示只有当user的id为偶数时才会进行缓存 ```java @Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0") public User find(User user) ``` ### 对象序列化 Redis存储时,key和value都会使用Redis的序列化器进行序列化。RedisTemplate会使用JdkSerializationRedisSerializer。StringRedisTemplate默认会使用StringRedisSerializer 当使用RedisTemplate,我们希望将Value序列化为JSON(性能最好?),而key是String类型时,通过keySerializer和valueSerializer改变序列化方式 Spring Data Redis提供多个序列化器 * GenericToStringSerializer:使用spring转换服务进行序列化。 * JacksonJsonRedisSerializer:使用Jackson1,将对象序列化为JSON。 * Jackson2JsonRedisSerializer:使用Jackson2,将对象序列化为JSON。 * JdkSerializationRedisSerializer:使用Java序列化 * OxmSerializer:使用Spring O/X映射的编排器和解排器实现序列化,用于XML序列化。 * StringRedisSerializer:序列化String类型的key和value ### 配置缓存过期 ### 基于spring data redis cache的局限性 关于spring cache相关可以参考 https://www.ibm.com/developerworks/cn/opensource/os-cn-spring-cache/index.html redis-sso模块 =============== 此项目则是一个综合应用,使用spring + redis 实现的session共享,从而 可以用来实现单点登录。