zoukankan      html  css  js  c++  java
  • SpringBoot整合Redis及Redis工具类撰写(转)

    转自https://www.cnblogs.com/zeng1994/p/03303c805731afc9aa9c60dbbd32a323.html

        SpringBoot整合Redis的博客很多,但是很多都不是我想要的结果。因为我只需要整合完成后,可以操作Redis就可以了,并不需要配合缓存相关的注解使用(如@Cacheable)。看了很多博客后,我成功的整合了,并写了个Redis操作工具类。特意在此记录一下,方便后续查阅。

    一、Maven依赖

    (1)本文所采用的SpringBoot的版本如下
     
    
    
     
     
     
     
     
     
     
    1
       <parent>
    2
            <groupId>org.springframework.boot</groupId>
    3
            <artifactId>spring-boot-starter-parent</artifactId>
    4
            <version>2.0.2.RELEASE</version>
    5
            <relativePath/> <!-- lookup parent from repository -->
    6
        </parent>
     
     
    (2)加入Redis相关依赖
     
    
    
     
     
     
     
     
    1
            <dependency>
    2
                <groupId>org.springframework.boot</groupId>
    3
                <artifactId>spring-boot-starter-data-redis</artifactId>
     
     
    4
            </dependency> 
     
     
     

    二、application.properties中加入redis相关配置

     
    
    
     
     
     
     
     
     
     
    1
    # Redis数据库索引(默认为0)  
    2
    spring.redis.database=0  
    3
    # Redis服务器地址  
    4
    spring.redis.host=192.168.0.24  
    5
    # Redis服务器连接端口  
    6
    spring.redis.port=6379  
    7
    # Redis服务器连接密码(默认为空)  
    8
    spring.redis.password=  
    9
    # 连接池最大连接数(使用负值表示没有限制)  
    10
    spring.redis.pool.max-active=200  
    11
    # 连接池最大阻塞等待时间(使用负值表示没有限制)  
    12
    spring.redis.pool.max-wait=-1  
    13
    # 连接池中的最大空闲连接  
    14
    spring.redis.pool.max-idle=10 
    15
    # 连接池中的最小空闲连接  
    16
    spring.redis.pool.min-idle=0  
    17
    # 连接超时时间(毫秒)  
    18
    spring.redis.timeout=1000 
     
     
     

    三、写一个redis配置类

    (1)聊聊RedisTemplate的自动配置
            其实现在就可以在代码中注入RedisTemplate,为啥可以直接注入呢?先看下源码吧。下图为 RedisAutoConfiguration类中的截图,为了防止图片失效,代码也贴上 。
            
            代码:
     
    
    
     
     
     
     
     
     
     
    1
    @Configuration
    2
    @ConditionalOnClass(RedisOperations.class)
    3
    @EnableConfigurationProperties(RedisProperties.class)
    4
    @Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
    5
    public class RedisAutoConfiguration {
    6
    
    
    7
        @Bean
    8
        @ConditionalOnMissingBean(name = "redisTemplate")
    9
        public RedisTemplate<Object, Object> redisTemplate(
    10
                RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
    11
            RedisTemplate<Object, Object> template = new RedisTemplate<>();
    12
            template.setConnectionFactory(redisConnectionFactory);
    13
            return template;
    14
        }
    15
    
    
    16
        @Bean
    17
        @ConditionalOnMissingBean
    18
        public StringRedisTemplate stringRedisTemplate(
    19
                RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
    20
            StringRedisTemplate template = new StringRedisTemplate();
    21
            template.setConnectionFactory(redisConnectionFactory);
    22
            return template;
    23
        }
    24
    
    
    25
    }
     
     
            通过源码可以看出,SpringBoot自动帮我们在容器中生成了一个RedisTemplate和一个StringRedisTemplate。但是,这个RedisTemplate的泛型是<Object,Object>,写代码不方便,需要写好多类型转换的代码;我们需要一个泛型为<String,Object>形式的RedisTemplate。并且,这个RedisTemplate没有设置数据存在Redis时,key及value的序列化方式。
            看到这个@ConditionalOnMissingBean注解后,就知道如果Spring容器中有了RedisTemplate对象了,这个自动配置的RedisTemplate不会实例化。因此我们可以直接自己写个配置类,配置RedisTemplate。
     

    (2)既然自动配置不好用,就重新配置一个RedisTemplate
            代码如下:
     
    
    
     
     
     
     
     
     
     
    1
    package com.zxy.demo.redis;
    2
    
    
    3
    import org.springframework.context.annotation.Bean;
    4
    import org.springframework.context.annotation.Configuration;
    5
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    6
    import org.springframework.data.redis.core.RedisTemplate;
    7
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    8
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    9
    
    
    10
    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    11
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    12
    import com.fasterxml.jackson.databind.ObjectMapper;
    13
    
    
    14
    /**
    15
     * redis配置类
    16
     * @author ZENG.XIAO.YAN
    17
     * @date   2018年6月6日
    18
     * 
    19
     */
    20
    @Configuration
    21
    public class RedisConfig {
    22
        
    23
        @Bean
    24
        @SuppressWarnings("all")
    25
        public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
    26
            RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
    27
            template.setConnectionFactory(factory);
    28
            Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    29
            ObjectMapper om = new ObjectMapper();
    30
            om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    31
            om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    32
            jackson2JsonRedisSerializer.setObjectMapper(om);
    33
            StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
    34
            // key采用String的序列化方式
    35
            template.setKeySerializer(stringRedisSerializer);
    36
            // hash的key也采用String的序列化方式
    37
            template.setHashKeySerializer(stringRedisSerializer);
    38
            // value序列化方式采用jackson
    39
            template.setValueSerializer(jackson2JsonRedisSerializer);
    40
            // hash的value序列化方式采用jackson
    41
            template.setHashValueSerializer(jackson2JsonRedisSerializer);
    42
            template.afterPropertiesSet();
    43
            return template;
    44
        }
    45
    
    
    46
    }
     
     


    四、写一个Redis工具类

            直接用RedisTemplate操作Redis,需要很多行代码,因此直接封装好一个RedisUtils,这样写代码更方便点。这个RedisUtils交给Spring容器实例化,使用时直接注解注入。
            工具类代码如下:
     
    
    
     
     
     
     
     
     
     
    1
    package com.zxy.demo.redis;
    2
    
    
    3
    import java.util.List;
    4
    import java.util.Map;
    5
    import java.util.Set;
    6
    import java.util.concurrent.TimeUnit;
    7
    
    
    8
    import org.springframework.beans.factory.annotation.Autowired;
    9
    import org.springframework.data.redis.core.RedisTemplate;
    10
    import org.springframework.stereotype.Component;
    11
    import org.springframework.util.CollectionUtils;
    12
    
    
    13
    /**
    14
     * Redis工具类
    15
     * @author ZENG.XIAO.YAN
    16
     * @date   2018年6月7日
    17
     */
    18
    @Component
    19
    public final class RedisUtil {
    20
    
    
    21
        @Autowired
    22
        private RedisTemplate<String, Object> redisTemplate;
    23
    
    
    24
        // =============================common============================
    25
        /**
    26
         * 指定缓存失效时间
    27
         * @param key 键
    28
         * @param time 时间(秒)
    29
         * @return
    30
         */
    31
        public boolean expire(String key, long time) {
    32
            try {
    33
                if (time > 0) {
    34
                    redisTemplate.expire(key, time, TimeUnit.SECONDS);
    35
                }
    36
                return true;
    37
            } catch (Exception e) {
    38
                e.printStackTrace();
    39
                return false;
    40
            }
    41
        }
    42
    
    
    43
        /**
    44
         * 根据key 获取过期时间
    45
         * @param key 键 不能为null
    46
         * @return 时间(秒) 返回0代表为永久有效
    47
         */
    48
        public long getExpire(String key) {
    49
            return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    50
        }
    51
    
    
    52
        /**
    53
         * 判断key是否存在
    54
         * @param key 键
    55
         * @return true 存在 false不存在
    56
         */
    57
        public boolean hasKey(String key) {
    58
            try {
    59
                return redisTemplate.hasKey(key);
    60
            } catch (Exception e) {
    61
                e.printStackTrace();
    62
                return false;
    63
            }
    64
        }
    65
    
    
    66
        /**
    67
         * 删除缓存
    68
         * @param key 可以传一个值 或多个
    69
         */
    70
        @SuppressWarnings("unchecked")
    71
        public void del(String... key) {
    72
            if (key != null && key.length > 0) {
    73
                if (key.length == 1) {
    74
                    redisTemplate.delete(key[0]);
    75
                } else {
    76
                    redisTemplate.delete(CollectionUtils.arrayToList(key));
    77
                }
    78
            }
    79
        }
    80
    
    
    81
        // ============================String=============================
    82
        /**
    83
         * 普通缓存获取
    84
         * @param key 键
    85
         * @return 值
    86
         */
    87
        public Object get(String key) {
    88
            return key == null ? null : redisTemplate.opsForValue().get(key);
    89
        }
    90
    
    
    91
        /**
    92
         * 普通缓存放入
    93
         * @param key 键
    94
         * @param value 值
    95
         * @return true成功 false失败
    96
         */
    97
        public boolean set(String key, Object value) {
    98
            try {
    99
                redisTemplate.opsForValue().set(key, value);
    100
                return true;
    101
            } catch (Exception e) {
    102
                e.printStackTrace();
    103
                return false;
    104
            }
    105
    
    
    106
        }
    107
    
    
    108
        /**
    109
         * 普通缓存放入并设置时间
    110
         * @param key 键
    111
         * @param value 值
    112
         * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
    113
         * @return true成功 false 失败
    114
         */
    115
        public boolean set(String key, Object value, long time) {
    116
            try {
    117
                if (time > 0) {
    118
                    redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
    119
                } else {
    120
                    set(key, value);
    121
                }
    122
                return true;
    123
            } catch (Exception e) {
    124
                e.printStackTrace();
    125
                return false;
    126
            }
    127
        }
    128
    
    
    129
        /**
    130
         * 递增
    131
         * @param key 键
    132
         * @param delta 要增加几(大于0)
    133
         * @return
    134
         */
    135
        public long incr(String key, long delta) {
    136
            if (delta < 0) {
    137
                throw new RuntimeException("递增因子必须大于0");
    138
            }
    139
            return redisTemplate.opsForValue().increment(key, delta);
    140
        }
    141
    
    
    142
        /**
    143
         * 递减
    144
         * @param key 键
    145
         * @param delta 要减少几(小于0)
    146
         * @return
    147
         */
    148
        public long decr(String key, long delta) {
    149
            if (delta < 0) {
    150
                throw new RuntimeException("递减因子必须大于0");
    151
            }
    152
            return redisTemplate.opsForValue().increment(key, -delta);
    153
        }
    154
    
    
    155
        // ================================Map=================================
    156
        /**
    157
         * HashGet
    158
         * @param key 键 不能为null
    159
         * @param item 项 不能为null
    160
         * @return 值
    161
         */
    162
        public Object hget(String key, String item) {
    163
            return redisTemplate.opsForHash().get(key, item);
    164
        }
    165
    
    
    166
        /**
    167
         * 获取hashKey对应的所有键值
    168
         * @param key 键
    169
         * @return 对应的多个键值
    170
         */
    171
        public Map<Object, Object> hmget(String key) {
    172
            return redisTemplate.opsForHash().entries(key);
    173
        }
    174
    
    
    175
        /**
    176
         * HashSet
    177
         * @param key 键
    178
         * @param map 对应多个键值
    179
         * @return true 成功 false 失败
    180
         */
    181
        public boolean hmset(String key, Map<String, Object> map) {
    182
            try {
    183
                redisTemplate.opsForHash().putAll(key, map);
    184
                return true;
    185
            } catch (Exception e) {
    186
                e.printStackTrace();
    187
                return false;
    188
            }
    189
        }
    190
    
    
    191
        /**
    192
         * HashSet 并设置时间
    193
         * @param key 键
    194
         * @param map 对应多个键值
    195
         * @param time 时间(秒)
    196
         * @return true成功 false失败
    197
         */
    198
        public boolean hmset(String key, Map<String, Object> map, long time) {
    199
            try {
    200
                redisTemplate.opsForHash().putAll(key, map);
    201
                if (time > 0) {
    202
                    expire(key, time);
    203
                }
    204
                return true;
    205
            } catch (Exception e) {
    206
                e.printStackTrace();
    207
                return false;
    208
            }
    209
        }
    210
    
    
    211
        /**
    212
         * 向一张hash表中放入数据,如果不存在将创建
    213
         * @param key 键
    214
         * @param item 项
    215
         * @param value 值
    216
         * @return true 成功 false失败
    217
         */
    218
        public boolean hset(String key, String item, Object value) {
    219
            try {
    220
                redisTemplate.opsForHash().put(key, item, value);
    221
                return true;
    222
            } catch (Exception e) {
    223
                e.printStackTrace();
    224
                return false;
    225
            }
    226
        }
    227
    
    
    228
        /**
    229
         * 向一张hash表中放入数据,如果不存在将创建
    230
         * @param key 键
    231
         * @param item 项
    232
         * @param value 值
    233
         * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
    234
         * @return true 成功 false失败
    235
         */
    236
        public boolean hset(String key, String item, Object value, long time) {
    237
            try {
    238
                redisTemplate.opsForHash().put(key, item, value);
    239
                if (time > 0) {
    240
                    expire(key, time);
    241
                }
    242
                return true;
    243
            } catch (Exception e) {
    244
                e.printStackTrace();
    245
                return false;
    246
            }
    247
        }
    248
    
    
    249
        /**
    250
         * 删除hash表中的值
    251
         * @param key 键 不能为null
    252
         * @param item 项 可以使多个 不能为null
    253
         */
    254
        public void hdel(String key, Object... item) {
    255
            redisTemplate.opsForHash().delete(key, item);
    256
        }
    257
    
    
    258
        /**
    259
         * 判断hash表中是否有该项的值
    260
         * @param key 键 不能为null
    261
         * @param item 项 不能为null
    262
         * @return true 存在 false不存在
    263
         */
    264
        public boolean hHasKey(String key, String item) {
    265
            return redisTemplate.opsForHash().hasKey(key, item);
    266
        }
    267
    
    
    268
        /**
    269
         * hash递增 如果不存在,就会创建一个 并把新增后的值返回
    270
         * @param key 键
    271
         * @param item 项
    272
         * @param by 要增加几(大于0)
    273
         * @return
    274
         */
    275
        public double hincr(String key, String item, double by) {
    276
            return redisTemplate.opsForHash().increment(key, item, by);
    277
        }
    278
    
    
    279
        /**
    280
         * hash递减
    281
         * @param key 键
    282
         * @param item 项
    283
         * @param by 要减少记(小于0)
    284
         * @return
    285
         */
    286
        public double hdecr(String key, String item, double by) {
    287
            return redisTemplate.opsForHash().increment(key, item, -by);
    288
        }
    289
    
    
    290
        // ============================set=============================
    291
        /**
    292
         * 根据key获取Set中的所有值
    293
         * @param key 键
    294
         * @return
    295
         */
    296
        public Set<Object> sGet(String key) {
    297
            try {
    298
                return redisTemplate.opsForSet().members(key);
    299
            } catch (Exception e) {
    300
                e.printStackTrace();
    301
                return null;
    302
            }
    303
        }
    304
    
    
    305
        /**
    306
         * 根据value从一个set中查询,是否存在
    307
         * @param key 键
    308
         * @param value 值
    309
         * @return true 存在 false不存在
    310
         */
    311
        public boolean sHasKey(String key, Object value) {
    312
            try {
    313
                return redisTemplate.opsForSet().isMember(key, value);
    314
            } catch (Exception e) {
    315
                e.printStackTrace();
    316
                return false;
    317
            }
    318
        }
    319
    
    
    320
        /**
    321
         * 将数据放入set缓存
    322
         * @param key 键
    323
         * @param values 值 可以是多个
    324
         * @return 成功个数
    325
         */
    326
        public long sSet(String key, Object... values) {
    327
            try {
    328
                return redisTemplate.opsForSet().add(key, values);
    329
            } catch (Exception e) {
    330
                e.printStackTrace();
    331
                return 0;
    332
            }
    333
        }
    334
    
    
    335
        /**
    336
         * 将set数据放入缓存
    337
         * @param key 键
    338
         * @param time 时间(秒)
    339
         * @param values 值 可以是多个
    340
         * @return 成功个数
    341
         */
    342
        public long sSetAndTime(String key, long time, Object... values) {
    343
            try {
    344
                Long count = redisTemplate.opsForSet().add(key, values);
    345
                if (time > 0)
    346
                    expire(key, time);
    347
                return count;
    348
            } catch (Exception e) {
    349
                e.printStackTrace();
    350
                return 0;
    351
            }
    352
        }
    353
    
    
    354
        /**
    355
         * 获取set缓存的长度
    356
         * @param key 键
    357
         * @return
    358
         */
    359
        public long sGetSetSize(String key) {
    360
            try {
    361
                return redisTemplate.opsForSet().size(key);
    362
            } catch (Exception e) {
    363
                e.printStackTrace();
    364
                return 0;
    365
            }
    366
        }
    367
    
    
    368
        /**
    369
         * 移除值为value的
    370
         * @param key 键
    371
         * @param values 值 可以是多个
    372
         * @return 移除的个数
    373
         */
    374
        public long setRemove(String key, Object... values) {
    375
            try {
    376
                Long count = redisTemplate.opsForSet().remove(key, values);
    377
                return count;
    378
            } catch (Exception e) {
    379
                e.printStackTrace();
    380
                return 0;
    381
            }
    382
        }
    383
        // ===============================list=================================
    384
    
    
    385
        /**
    386
         * 获取list缓存的内容
    387
         * @param key 键
    388
         * @param start 开始
    389
         * @param end 结束 0 到 -1代表所有值
    390
         * @return
    391
         */
    392
        public List<Object> lGet(String key, long start, long end) {
    393
            try {
    394
                return redisTemplate.opsForList().range(key, start, end);
    395
            } catch (Exception e) {
    396
                e.printStackTrace();
    397
                return null;
    398
            }
    399
        }
    400
    
    
    401
        /**
    402
         * 获取list缓存的长度
    403
         * @param key 键
    404
         * @return
    405
         */
    406
        public long lGetListSize(String key) {
    407
            try {
    408
                return redisTemplate.opsForList().size(key);
    409
            } catch (Exception e) {
    410
                e.printStackTrace();
    411
                return 0;
    412
            }
    413
        }
    414
    
    
    415
        /**
    416
         * 通过索引 获取list中的值
    417
         * @param key 键
    418
         * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
    419
         * @return
    420
         */
    421
        public Object lGetIndex(String key, long index) {
    422
            try {
    423
                return redisTemplate.opsForList().index(key, index);
    424
            } catch (Exception e) {
    425
                e.printStackTrace();
    426
                return null;
    427
            }
    428
        }
    429
    
    
    430
        /**
    431
         * 将list放入缓存
    432
         * @param key 键
    433
         * @param value 值
    434
         * @param time 时间(秒)
    435
         * @return
    436
         */
    437
        public boolean lSet(String key, Object value) {
    438
            try {
    439
                redisTemplate.opsForList().rightPush(key, value);
    440
                return true;
    441
            } catch (Exception e) {
    442
                e.printStackTrace();
    443
                return false;
    444
            }
    445
        }
    446
    
    
    447
        /**
    448
         * 将list放入缓存
    449
         * @param key 键
    450
         * @param value 值
    451
         * @param time 时间(秒)
    452
         * @return
    453
         */
    454
        public boolean lSet(String key, Object value, long time) {
    455
            try {
    456
                redisTemplate.opsForList().rightPush(key, value);
    457
                if (time > 0)
    458
                    expire(key, time);
    459
                return true;
    460
            } catch (Exception e) {
    461
                e.printStackTrace();
    462
                return false;
    463
            }
    464
        }
    465
    
    
    466
        /**
    467
         * 将list放入缓存
    468
         * @param key 键
    469
         * @param value 值
    470
         * @param time 时间(秒)
    471
         * @return
    472
         */
    473
        public boolean lSet(String key, List<Object> value) {
    474
            try {
    475
                redisTemplate.opsForList().rightPushAll(key, value);
    476
                return true;
    477
            } catch (Exception e) {
    478
                e.printStackTrace();
    479
                return false;
    480
            }
    481
        }
    482
    
    
    483
        /**
    484
         * 将list放入缓存
    485
         * 
    486
         * @param key 键
    487
         * @param value 值
    488
         * @param time 时间(秒)
    489
         * @return
    490
         */
    491
        public boolean lSet(String key, List<Object> value, long time) {
    492
            try {
    493
                redisTemplate.opsForList().rightPushAll(key, value);
    494
                if (time > 0)
    495
                    expire(key, time);
    496
                return true;
    497
            } catch (Exception e) {
    498
                e.printStackTrace();
    499
                return false;
    500
            }
    501
        }
    502
    
    
    503
        /**
    504
         * 根据索引修改list中的某条数据
    505
         * @param key 键
    506
         * @param index 索引
    507
         * @param value 值
    508
         * @return
    509
         */
    510
        public boolean lUpdateIndex(String key, long index, Object value) {
    511
            try {
    512
                redisTemplate.opsForList().set(key, index, value);
    513
                return true;
    514
            } catch (Exception e) {
    515
                e.printStackTrace();
    516
                return false;
    517
            }
    518
        }
    519
    
    
    520
        /**
    521
         * 移除N个值为value
    522
         * @param key 键
    523
         * @param count 移除多少个
    524
         * @param value 值
    525
         * @return 移除的个数
    526
         */
    527
        public long lRemove(String key, long count, Object value) {
    528
            try {
    529
                Long remove = redisTemplate.opsForList().remove(key, count, value);
    530
                return remove;
    531
            } catch (Exception e) {
    532
                e.printStackTrace();
    533
                return 0;
    534
            }
    535
        }
    536
    }
     
     

    五、小结

            整合其实不麻烦,网上好多博文都有。注意设置下key和value的序列化方式,不然存到Redis的中数据看起来像乱码一下。
  • 相关阅读:
    如何批量删除Redis数据库中的Key
    关于 no device found for connection ‘ System eth0′问题
    nginx配置vhost配置文件详解
    Linux教程之:Nginx [emerg]: bind() to 0.0.0.0:80 failed (98: Address already in use)
    Nginx配置文件详细说明
    swoole使用 常用案例
    超好用的一个JQUERY分页器-jpaginate
    如何解决chrome 等浏览器不支持本地ajax请求的问题
    PHP设计模式之单例模式
    IE和其他浏览器用JS新窗口打开的问题
  • 原文地址:https://www.cnblogs.com/ffaiss/p/11170791.html
Copyright © 2011-2022 走看看