RedisTemplate常用集合使用说明
在这里我使用的是spring-boot框架组合的redisTemplate的jar包spring-boot-starter-data-redis,采用POM的方式引入,引入代码如下:
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>1.5.6.RELEASE</version>
- </parent>
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-configuration-processor</artifactId>
- <optional>true</optional>
- </dependency>
- </dependencies>
RedisTemplate主要支持String,List,Hash,Set,ZSet这几种方式的参数,其对应的方法分别是opsForValue()、opsForList()、opsForHash()、opsForSet()、opsForZSet()。下面分别介绍这几个方法的使用。
在介绍之前,首先说下RedisTemplate的序列化方法,在RedisTemplate类下有一个继承了该类的StringRedisTemplate类,该类主要用于opsForValue()方法的String类型的实现,而且这2个类的内部实现不一样,如果是使用RedisTemplate类作为连接Redis的工具类,如果不使用opsForValue方法的话,我们可以这样初始化序列化方法:
- ObjectMapper om = new ObjectMapper();
- om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
- om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
- jackson2JsonRedisSerializer.setObjectMapper(om);
- template.setKeySerializer(template.getStringSerializer());
- template.setValueSerializer(jackson2JsonRedisSerializer);
- template.setHashValueSerializer(jackson2JsonRedisSerializer);
如果需要使用opsForValue()方法的话,我们就必须使用如下的序列化方法:
- ObjectMapper om = new ObjectMapper();
- om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
- om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
- jackson2JsonRedisSerializer.setObjectMapper(om);
- //在使用String的数据结构的时候使用这个来更改序列化方式
- RedisSerializer<String> stringSerializer = new StringRedisSerializer();
- template.setKeySerializer(stringSerializer );
- template.setValueSerializer(stringSerializer );
- template.setHashKeySerializer(stringSerializer );
- template.setHashValueSerializer(stringSerializer );
当然如果想使用RedisTemplate方法作为bean来使用,必须按照如下的方式实现代码(这里介绍的都是通过使用spring-boot方式进行使用):
1. 我们可以在application.properties文件定义如下的redis连接:
- #配置缓存redis
- spring.redis.database=8
- # Redis服务器地址
- spring.redis.host=127.0.0.1
- # Redis服务器连接端口
- spring.redis.port=6379
- # Redis服务器连接密码(默认为空)
- spring.redis.password=
- # 连接池最大连接数(使用负值表示没有限制)
- spring.redis.pool.max-active=8
- # 连接池最大阻塞等待时间(使用负值表示没有限制)
- spring.redis.pool.max-wait=-1
- # 连接池中的最大空闲连接
- spring.redis.pool.max-idle=8
- # 连接池中的最小空闲连接
- spring.redis.pool.min-idle=0
- # 连接超时时间(毫秒)
- spring.redis.keytimeout=1000
- spring.redis.timeout=0
2. 使用RedisTemplate类来设置bean文件:
- import com.fasterxml.jackson.annotation.JsonAutoDetect;
- import com.fasterxml.jackson.annotation.PropertyAccessor;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.data.redis.connection.RedisConnectionFactory;
- import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.data.redis.core.StringRedisTemplate;
- import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
- import org.springframework.data.redis.serializer.RedisSerializer;
- import org.springframework.data.redis.serializer.StringRedisSerializer;
- import redis.clients.jedis.JedisPoolConfig;
- /**
- * @author liaoyubo
- * @version 1.0 2017/8/1
- * @description
- */
- @Configuration
- public class RedisConfig {
- @Value("${spring.redis.host}")
- private String hostName;
- @Value("${spring.redis.port}")
- private int port;
- @Value("${spring.redis.password}")
- private String passWord;
- @Value("${spring.redis.pool.max-idle}")
- private int maxIdl;
- @Value("${spring.redis.pool.min-idle}")
- private int minIdl;
- @Value("${spring.redis.database}")
- private int database;
- @Value("${spring.redis.keytimeout}")
- private long keytimeout;
- @Value("${spring.redis.timeout}")
- private int timeout;
- /*@Bean
- public JedisConnectionFactory redisConnectionFactory() {
- JedisConnectionFactory factory = new JedisConnectionFactory();
- factory.setHostName(hostName);
- factory.setPort(port);
- factory.setTimeout(timeout); //设置连接超时时间
- return factory;
- }
- @Bean
- public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
- StringRedisTemplate template = new StringRedisTemplate(factory);
- setSerializer(template); //设置序列化工具,这样ReportBean不需要实现Serializable接口
- template.afterPropertiesSet();
- return template;
- }
- private void setSerializer(StringRedisTemplate template) {
- Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
- ObjectMapper om = new ObjectMapper();
- om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
- om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
- jackson2JsonRedisSerializer.setObjectMapper(om);
- template.setValueSerializer(jackson2JsonRedisSerializer);
- }*/
- @Bean
- public RedisConnectionFactory redisConnectionFactory(){
- JedisPoolConfig poolConfig=new JedisPoolConfig();
- poolConfig.setMaxIdle(maxIdl);
- poolConfig.setMinIdle(minIdl);
- poolConfig.setTestOnBorrow(true);
- poolConfig.setTestOnReturn(true);
- poolConfig.setTestWhileIdle(true);
- poolConfig.setNumTestsPerEvictionRun(10);
- poolConfig.setTimeBetweenEvictionRunsMillis(60000);
- JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(poolConfig);
- jedisConnectionFactory.setHostName(hostName);
- if(!passWord.isEmpty()){
- jedisConnectionFactory.setPassword(passWord);
- }
- jedisConnectionFactory.setPort(port);
- jedisConnectionFactory.setDatabase(database);
- return jedisConnectionFactory;
- }
- @Bean
- public RedisTemplate<String, Object> redisTemplateObject() throws Exception {
- RedisTemplate<String, Object> redisTemplateObject = new RedisTemplate<String, Object>();
- redisTemplateObject.setConnectionFactory(redisConnectionFactory());
- setSerializer(redisTemplateObject);
- redisTemplateObject.afterPropertiesSet();
- return redisTemplateObject;
- }
- private void setSerializer(RedisTemplate<String, Object> template) {
- Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
- Object.class);
- ObjectMapper om = new ObjectMapper();
- om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
- om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
- jackson2JsonRedisSerializer.setObjectMapper(om);
- /*template.setKeySerializer(template.getStringSerializer());
- template.setValueSerializer(jackson2JsonRedisSerializer);
- template.setHashValueSerializer(jackson2JsonRedisSerializer);*/
- //在使用String的数据结构的时候使用这个来更改序列化方式
- RedisSerializer<String> stringSerializer = new StringRedisSerializer();
- template.setKeySerializer(stringSerializer );
- template.setValueSerializer(stringSerializer );
- template.setHashKeySerializer(stringSerializer );
- template.setHashValueSerializer(stringSerializer );
- }
- }
3. 创建启动类App类
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- /**
- * @author liaoyubo
- * @version 1.0 2017/7/31
- * @description
- */
- @SpringBootApplication
- public class App {
- public static void main(String [] args){
- SpringApplication.run(App.class);
- }
- }
通过以上步骤我们就可以以bean的注入方式正常使用RedisTemplate模板类了,如果没有安装Redis,请到https://redis.io/download官网下载需要的Redis。下面依次主要介绍RedisTemplate集合以及pipeline、multi的使用,官网地址是http://docs.spring.io/spring-data/redis/docs/current/api/org/springframework/data/redis/core/RedisTemplate.html。注入RedisTemplate方法如下:
- @Autowired
- private RedisTemplate<String,Object> redisTemplate;
一、pipeline介绍
Pipeline是redis提供的一种通道功能,通常使用pipeline的地方是不需要等待结果立即返回的时候,使用pipeline的好处是处理数据的速度更快因为它专门开辟了一个管道来处理数据(具体的对比可以参考网上的文章),它是单向的,从客户端向服务端发送数据,当管道关闭链接时将会从服务端返回数据,再次期间是无法获取到服务端的数据的。
因为这个例子的需要,我们把RedisConfig.java类的序列化的方式修改为:
- template.setKeySerializer(template.getStringSerializer());
- template.setValueSerializer(jackson2JsonRedisSerializer);
- template.setHashValueSerializer(jackson2JsonRedisSerializer);
下面是一个基本的使用示例:
- import com.springRedis.App;
- 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.dao.DataAccessException;
- import org.springframework.data.redis.connection.RedisConnection;
- import org.springframework.data.redis.core.RedisCallback;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.test.context.junit4.SpringRunner;
- /**
- * @author liaoyubo
- * @version 1.0 2017/7/31
- * @description
- */
- @RunWith(SpringRunner.class)
- @SpringBootTest(classes = App.class)
- public class PipelineTest {
- @Autowired
- private RedisTemplate<String,Object> redisTemplate;
- @Test
- public void testPipeLine(){
- redisTemplate.opsForValue().set("a",1);
- redisTemplate.opsForValue().set("b",2);
- redisTemplate.executePipelined(new RedisCallback<Object>() {
- @Override
- public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
- redisConnection.openPipeline();
- for (int i = 0;i < 10;i++){
- redisConnection.incr("a".getBytes());
- }
- System.out.println("a:"+redisTemplate.opsForValue().get("a"));
- redisTemplate.opsForValue().set("c",3);
- for(int j = 0;j < 20;j++){
- redisConnection.incr("b".getBytes());
- }
- System.out.println("b:"+redisTemplate.opsForValue().get("b"));
- System.out.println("c:"+redisTemplate.opsForValue().get("c"));
- redisConnection.closePipeline();
- return null;
- }
- });
- System.out.println("b:"+redisTemplate.opsForValue().get("b"));
- System.out.println("a:"+redisTemplate.opsForValue().get("a"));
- }
- }
二、multi与exec
这2个方法是RedisTemplate.java类提供的事务方法。在使用这个方法之前必须开启事务才能正常使用。例子如下:
- import com.springRedis.App;
- 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.RedisTemplate;
- import org.springframework.data.redis.core.ValueOperations;
- import org.springframework.test.context.junit4.SpringRunner;
- import java.util.List;
- /**
- * @author liaoyubo
- * @version 1.0 2017/8/4
- * @description
- */
- @RunWith(SpringRunner.class)
- @SpringBootTest(classes = App.class)
- public class MultiTest {
- @Autowired
- private RedisTemplate<String,Object> redisTemplate;
- @Test
- public void testMulti(){
- ValueOperations<String,Object> valueOperations = redisTemplate.opsForValue();
- redisTemplate.setEnableTransactionSupport(true);
- //在未提交之前是获取不到值得,同时再次循环报错
- while (true){
- redisTemplate.watch("multiTest");
- redisTemplate.multi();
- valueOperations.set("multiTest",1);
- valueOperations.increment("multiTest",2);
- Object o = valueOperations.get("multiTest");
- List list = redisTemplate.exec();
- System.out.println(list);
- System.out.println(o);
- }
- }
- }
在使用exec()方法的时候,没有带入参数,使用的是默认的序列化方法,同时提供了一个exec(RedisSerializer<?> valueSerializer)
方法,这个方法可以自己
定义序列化方法,如
Jackson2JsonRedisSerializer。