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方法如下:
一、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。