# 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共享,从而
可以用来实现单点登录。