Spring Data Redis
Spring Data Redis,是Spring Data 家族的一部分。 对Jedis客户端进行了封装,与spring进行了整合。可以非常方便的来实现redis的配置和操作。
一、RedisTemplate基本操作
Spring Data Redis 提供了一个工具类:RedisTemplate。里面封装了对于Redis的五种数据结构的各种操作,包括:
- redisTemplate.opsForValue():操作字符串
- redisTemplate.opsForHash(): 操作hash
- redisTemplate.opsForList(): 操作list
- redisTemplate.opsForSet(): 操作set
- redisTemplate.opsForZSet(): 操作Zset
其它一些通用命令,如expire,可以通过redisTemplate.xx()来直接调用
5种结构:
- String:等同于Java中的
Map<String,String>
- list:等同于Java中的
Map<String,List<String>>
- set:等同于Java中的
Map<String,Set<String>>
- hash:等同于Java中的
Map<String,Map<String,String>>
- sort_set:可排序的set
二、StringRedisTemplate
RedisTemplate在创建时,可以指定其泛型类型:
- K:代表key 的数据类型
- V:代表value的数据类型
注意:这里的类型不是Redis中存储的数据类型,而是Java中的数据类型,RedisTemplate会自动将Java类型转为Redis支持的数据类型:字符串、字节、二进制等等。
不过RedisTemplate默认会采用JDK自带的序列化(Serialize)来对对象进行转换。生成的数据十分庞大,因此一般我们都会指定key和value为String类型,这样就由我们自己把对象序列化为json字符串来存储即可。
因为大部分情况下,我们都会使用key和value都为String的RedisTemplate,因此Spring就默认提供了这样一个实现:
三、配置
1. 引入依赖
jedis 和 spring-data-redis
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.1.9.RELEASE</version>
</dependency>
2. 在spring的配置文件配置redisTemplate
<!-- 连接池配置 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大空闲数 -->
<property name="maxIdle" value="50"></property>
<!-- 最大连接数 -->
<property name="maxTotal" value="100"></property>
<!-- 最大等待时间 -->
<property name="maxWaitMillis" value="20000"></property>
</bean>
<!-- 配置连接工厂 -->
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="192.168.80.131"></property>
<property name="port" value="6379"></property>
<!-- <property name="password" value=""></property> -->
<property name="poolConfig" ref="poolConfig"></property>
</bean>
<!-- 配置 key 和 value 的序列化器 -->
<bean id="jdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
<!-- 配置Redis模板对象 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="connectionFactory"></property>
<property name="keySerializer" ref="stringRedisSerializer"></property>
<property name="valueSerializer" ref="jdkSerializationRedisSerializer"></property>
</bean>
3. 使用redisTemplate
@Autowired
RedisTemplate redisTemplate = null;
public void Test01() {
Role role = new Role();
role.setId(1L);
role.setNote("note_1");
role.setRoleName("role_name_1");
//存储到到内存中的不是map而是string,进行了序列化
redisTemplate.opsForValue().set("role_1", role);
Role role1 = (Role) redisTemplate.opsForValue().get("role_1");
//上面两步不能保证每次使用RedisTemplate是操作同一个对Redis的连接
System.out.println(role1.toString());
}
public void Test02(){
final Role role = new Role();
role.setId(1L);
role.setNote("note_1");
role.setRoleName("role_name_1");
SessionCallback callback = new SessionCallback<Role>(){
public Role execute(RedisOperations ops) throws DataAccessException {
ops.boundValueOps("role_1").set(role);
return (Role) ops.boundValueOps("role_1").get();
}
};
Role savedRole = (Role) redisTemplate.execute(callback);
System.out.println(savedRole.getRoleName());
}
五、Spring Boot
1. 引入依赖
spring-boot-starter-data-redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2. 配置文件中指定Redis地址:
application.yml
spring:
redis:
host: 192.168.56.101
3. 编写测试类
package com.leyou.test;
import com.leyou.LeyouUserApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = LeyouUserApplication.class)
public class RedisTest {
@Autowired
private StringRedisTemplate redisTemplate;
@Test
public void testRedis() {
// 存储数据
this.redisTemplate.opsForValue().set("key1", "value1");
// 获取数据
String val = this.redisTemplate.opsForValue().get("key1");
System.out.println("val = " + val);
}
@Test
public void testRedis2() {
// 存储数据,并指定剩余生命时间,5小时
this.redisTemplate.opsForValue().set("key2", "value2",
5, TimeUnit.HOURS);
}
@Test
public void testHash() {
BoundHashOperations<String, Object, Object> hashOps =
this.redisTemplate.boundHashOps("user");
// 操作hash数据
hashOps.put("name", "jack");
hashOps.put("age", "21");
// 获取单个数据
Object name = hashOps.get("name");
System.out.println("name = " + name);
// 获取所有数据
Map<Object, Object> map = hashOps.entries();
for (Map.Entry<Object, Object> me : map.entrySet()) {
System.out.println(me.getKey() + " : " + me.getValue());
}
}
}
4. 在service层使用
@Autowired
private StringRedisTemplate redisTemplate;
/**
* 发送验证码
* @Param phone 手机号
*/
public Boolean sendVerifyCode(String phone) {
// 生成验证码
String code = NumberUtils.generateCode(6);
private static final String KEY_PREFIX = "user:code:phone:"; // 验证码key前缀
try {
// 发送短信
Map<String, String> msg = new HashMap<>();
msg.put("phone", phone);
msg.put("code", code);
this.amqpTemplate.convertAndSend("leyou.sms.exchange", "sms.verify.code", msg);
// 将code存入redis,5分钟内有效
this.redisTemplate.opsForValue().set(KEY_PREFIX + phone, code, 5, TimeUnit.MINUTES);
return true;
} catch (Exception e) {
// logger.error("发送短信失败。phone:{}, code:{}", phone, code);
return false;
}
}