这一篇主要讲一下关于redis的一些东西,个人习惯先上代码 然后再讲一些redis的东西
maven依赖: 因为在写redis的时候有两个版本,一个是用原生的方式去写的,第二个就是用springboot帮我们集成的
先说说第一个吧
<!--整合redis--> <!-- <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency>--> <!--springBoot整合redis--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>这个springboot整合redis的的配置 ip 以及端口号
#redis redis.host=127.0.0.1 redis.port=6379
然后建立参数类:将我们的刚刚的配置导入
package com.yjp.login.user.cache; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * 配置缓存池 需要的参数 * * @Author : WenBao * Date : 16:23 2017/12/6 */ @Component public class Parameters { @Value("${redis.host}") private String redisHost; @Value("${redis.port}") private int redisPort; @Value("${redis.max-idle}") private int redisMaxIdle; @Value("${redis.max-total}") private int redisMaxTotal; @Value("${redis.max-wait-millis}") private int redisMaxWaitMillis; @Override public String toString() { return "Parameters{" + "redisHost='" + redisHost + '\'' + ", redisPort=" + redisPort + ", redisMaxIdle=" + redisMaxIdle + ", redisMaxTotal=" + redisMaxTotal + ", redisMaxWaitMillis=" + redisMaxWaitMillis + '}'; } public String getRedisHost() { return redisHost; } public void setRedisHost(String redisHost) { this.redisHost = redisHost; } public int getRedisPort() { return redisPort; } public void setRedisPort(int redisPort) { this.redisPort = redisPort; } public int getRedisMaxIdle() { return redisMaxIdle; } public void setRedisMaxIdle(int redisMaxIdle) { this.redisMaxIdle = redisMaxIdle; } public int getRedisMaxTotal() { return redisMaxTotal; } public void setRedisMaxTotal(int redisMaxTotal) { this.redisMaxTotal = redisMaxTotal; } public int getRedisMaxWaitMillis() { return redisMaxWaitMillis; } public void setRedisMaxWaitMillis(int redisMaxWaitMillis) { this.redisMaxWaitMillis = redisMaxWaitMillis; } }将我们刚刚配置的好的参数类注入,创建连接池
package com.yjp.login.user.cache; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import javax.annotation.PostConstruct; /** * redis JedisPool * * @Author : WenBao * Date : 16:22 2017/12/6 */ @Component public class PoolWrapper { private static final Logger LOGGER = LoggerFactory.getLogger(PoolWrapper.class); private JedisPool jedisPool = null; @Autowired private Parameters parameters; /** * PostConstruct 相当于静态代码块 类初始化的时候直接加载 */ @PostConstruct public void init() { try { JedisPoolConfig config = new JedisPoolConfig(); config.setMaxIdle(parameters.getRedisMaxIdle()); config.setMaxWaitMillis(parameters.getRedisMaxWaitMillis()); config.setMaxTotal(parameters.getRedisMaxTotal()); jedisPool = new JedisPool(config, parameters.getRedisHost(), parameters.getRedisPort()); } catch (Exception e) { LOGGER.error("Fail to initialize redis pool", e); throw new RuntimeException("初始化失败"); } } public JedisPool getJedisPool() { return jedisPool; } }通过连接池来获取连接,然后写工具方法
package com.yjp.login.user.cache; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.Assert; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; @Component public class CacheUtil { private static final Logger LOGGER = LoggerFactory.getLogger(CacheUtil.class); @Autowired private static PoolWrapper poolWrapper; /** * 存入永久的key * * @param key * @param value */ public static void cache(String key, String value) { Jedis jedis = getJedis(); Assert.notNull(jedis, "jed's连接为空"); //选择redis第0片区 分开存放list,set类型的key //select选择在哪里个区 jedis.select(0); jedis.set(key, value); jedis.close(); } /** * 获取value * * @param key * @return */ public static String getCacheValue(String key) { String value; Jedis jedis = getJedis(); Assert.notNull(jedis, "jed's连接为空"); value = jedis.get(key); jedis.close(); return value; } /** * 设置有缓存时间的key * * @param key 不会被覆盖的key 可以作为分布式的锁 外置锁 * @param value * @param expiry 缓存时间 以秒为单位 * @return */ public static long cacheNxExpire(String key, String value, int expiry) { long result = 0L; Jedis jedis = getJedis(); Assert.notNull(jedis, "jed's连接为空"); //选择redis第0片区 分开存放list,set类型的key //select选择在哪里个区 jedis.select(0); //setnx 不会覆盖原有的key 操作失败 //可以设置为分布式锁 try { result = jedis.setnx(key, value); //expire 设置过期时间 jedis.expire(key, expiry); } catch (Exception e) { jedis.del(key); LOGGER.error("设置错误"); } finally { try { jedis.close(); } catch (Exception e) { LOGGER.error("关闭连接异常"); } } return result; } /** * 删除key * * @param key */ public static void delKey(String key) { Jedis jedis = getJedis(); Assert.notNull(jedis, "jed's连接为空"); //选择redis第0片区 分开存放list,set类型的key //select选择在哪里个区 jedis.select(0); jedis.del(key); jedis.close(); } /** * 获取redis连接 * * @return */ public static Jedis getJedis() { Jedis jedis = null; try { JedisPool jedisPool = poolWrapper.getJedisPool(); if (null != jedisPool) { jedis = jedisPool.getResource(); } } catch (Exception e) { LOGGER.error("jedisPool获取失败"); throw new RuntimeException("jedisPool获取失败", e); } return jedis; } }
springboot整合redis:
springboot本身就帮我们将redis整合了,所以我们只需要将我们需要使用的一些模板初始化就可以了
package com.yjp.login.user.cache.redis; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.*; import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class RedisConfig { /** * 注入 RedisConnectionFactory */ @Autowired RedisConnectionFactory redisConnectionFactory; /** * 实例化 RedisTemplate 对象 * * @return */ @Bean public RedisTemplate<String, Object> functionDomainRedisTemplate() { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); initDomainRedisTemplate(redisTemplate, redisConnectionFactory); return redisTemplate; } /** * 设置数据存入 redis 的序列化方式 * * @param redisTemplate * @param factory */ private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) { redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer()); redisTemplate.setConnectionFactory(factory); } /** * 实例化 HashOperations 对象,可以使用 Hash 类型操作 * * @param redisTemplate * @return */ @Bean public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForHash(); } /** * 实例化 ValueOperations 对象,可以使用 String 操作 * * @param redisTemplate * @return */ @Bean public ValueOperations<String, Object> valueOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForValue(); } /** * 实例化 ListOperations 对象,可以使用 List 操作 * * @param redisTemplate * @return */ @Bean public ListOperations<String, Object> listOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForList(); } /** * 实例化 SetOperations 对象,可以使用 Set 操作 * * @param redisTemplate * @return */ @Bean public SetOperations<String, Object> setOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForSet(); } /** * 实例化 ZSetOperations 对象,可以使用 ZSet 操作 * * @param redisTemplate * @return */ @Bean public ZSetOperations<String, Object> zSetOperations(RedisTemplate<String, Object> redisTemplate) { return redisTemplate.opsForZSet(); } }
同样是写一些工具方法
package com.yjp.login.user.cache.redis; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.*; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.concurrent.TimeUnit; @Component public class RedisCacheUtil { @Autowired private RedisTemplate<String, Object> redisTemplate; /** * 简单的k-v操作 */ @Resource private ValueOperations valueOperations; /** * Set类型数据的操作 */ private SetOperations setOperations; /** * list类型数据的操作 */ private ListOperations listOperations; /** * map类型数据的操作 */ private HashOperations hashOperations; /** * zset类型数据的操作 */ private ZSetOperations zSetOperations; /** * 存入永久的key * * @param key * @param value */ public void cache(String key, String value) { valueOperations.set(key, value); } /** * 获取value * * @param key * @return */ public String getCacheValue(String key) { return (String) valueOperations.get(key); } /** * 设置有缓存时间的key * * @param key * @param value * @param expiry 缓存时间 以秒为单位 * @return */ public void cacheExpire(String key, String value, int expiry) { valueOperations.set(key, value, expiry, TimeUnit.MILLISECONDS); } /** * 设置不会被覆盖的key 可以作为分布式的锁 外置锁 * * @param key * @param value */ public void cacheNx(String key, String value) { valueOperations.setIfAbsent(key, value); } /** * 删除key * * @param key */ public void delKey(String key) { redisTemplate.delete(key); } }
还有一个springboot整合redis的发布订阅
消费者:
package com.yjp.springbootredis.cache; import org.springframework.stereotype.Component; /** * 消息接受者 * * @Author : WenBao * Date : 9:34 2018/1/15 */ @Component public class Receiver { public void receiveMessage(String message) { System.err.println(message); } }配置类:
package com.yjp.springbootredis.cache; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.listener.PatternTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; /** * 设置redis的监听设置类 * * @Author : WenBao * Date : 9:24 2018/1/15 */ @Configuration public class RedisSubListenerConfig { @Bean RedisMessageListenerContainer container(RedisConnectionFactory factory, MessageListenerAdapter listenerAdapter) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(factory); //将消费者和队列绑定 container.addMessageListener(listenerAdapter, new PatternTopic("123")); return container; } /** * 指定消费者是哪一个类,收到消息后调用什么方法 * * @param receiver * @return */ @Bean MessageListenerAdapter listenerAdapter(Receiver receiver) { return new MessageListenerAdapter(receiver, "receiveMessage"); } }发送消息
public void sendChannelMess(String channel, String message) { redisTemplate.convertAndSend(channel, message); }测试:
@Test public void contextLoads() throws Exception { redisService.sendChannelMess("123", "你好"); System.err.println("发送成功"); }整合就到这里结束了。
努力吧,皮卡丘