最近我在把項(xiàng)目的php后端改成Java后端,之前的php項(xiàng)目我用的是Redis做的緩存記錄,然后還要用訂閱進(jìn)行短信推送,所以Redis必須要用到。但是我用spring boot去整合Redis的時(shí)候,遇到的問題還是有的,先說整合的步驟吧!
首先你得在pom文件里面加入依賴:
<dependency>
? ? ? ? ? ? <groupId>org.springframework.boot</groupId>
? ? ? ? ? ? <artifactId>spring-boot-starter-data-redis</artifactId>
? ? ? ? </dependency>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.springframework.boot</groupId>
? ? ? ? ? ? <artifactId>spring-boot-starter-redis</artifactId>
? ? ? ? ? ? <version>1.3.8.RELEASE</version>
? ? ? ? </dependency>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.apache.commons</groupId>
? ? ? ? ? ? <artifactId>commons-pool2</artifactId>
? ? ? ? </dependency>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>commons-io</groupId>
? ? ? ? ? ? <artifactId>commons-io</artifactId>
? ? ? ? ? ? <version>2.6</version>
? ? ? ? </dependency>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>com.alibaba</groupId>
? ? ? ? ? ? <artifactId>fastjson</artifactId>
? ? ? ? ? ? <version>1.2.38</version>
? ? ? ? </dependency>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>redis.clients</groupId>
? ? ? ? ? ? <artifactId>jedis</artifactId>
? ? ? ? ? ? <version>2.9.1</version>
? ? ? ? </dependency>
這些都是得在spring boot里面進(jìn)行整合的,然后還要進(jìn)行序列化等操作,這些百度都有
然后開始在yml里面配置Redis的信息:
redis:
? ? password: 123456
? ? port: 6379
? ? host: 127.0.0.1
? ? lettuce:
? ? ? pool:
? ? ? ? min-idle: 5
? ? ? ? max-idle: 10
? ? ? ? max-active: 8
? ? ? ? max-wait: 1ms
? ? ? shutdown-timeout: 100ms
? ? database: 0
然后就是工具類的封裝:
@Slf4j
@Configuration
public class RedisConfig {
? ? @Resource
? ? private RedisTemplate redisTemplate;
? ? public RedisTemplate setDataBase(int num) {
? ? ? ? LettuceConnectionFactory connectionFactory = (LettuceConnectionFactory) redisTemplate.getConnectionFactory();
? ? ? ? if (connectionFactory != null && num != connectionFactory.getDatabase()) {
? ? ? ? ? ? connectionFactory.setDatabase(num);
? ? ? ? ? ? this.redisTemplate.setConnectionFactory(connectionFactory);
? ? ? ? ? ? connectionFactory.afterPropertiesSet();//一定要加上這句
? ? ? ? ? ? connectionFactory.resetConnection();
? ? ? ? }
? ? ? ? return redisTemplate;
? ? }
? ? /**
? ? * 序列化注入spring容器的RedisTemplate
? ? *
? ? * @return
? ? */
? ? @Bean
? ? public RedisTemplate<Serializable, Object> getRedisTemplate() {
? ? ? ? Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);
? ? ? ? ObjectMapper mapper = new ObjectMapper();
? ? ? ? mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
? ? ? ? serializer.setObjectMapper(mapper);
? ? ? ? redisTemplate.setKeySerializer(new StringRedisSerializer());
? ? ? ? redisTemplate.setValueSerializer(new StringRedisSerializer());
? ? ? ? redisTemplate.setValueSerializer(serializer);
? ? ? ? redisTemplate.setHashKeySerializer(new StringRedisSerializer());
? ? ? ? redisTemplate.setHashValueSerializer(new StringRedisSerializer());
? ? ? ? redisTemplate.afterPropertiesSet();
? ? ? ? return redisTemplate;
? ? }
}
這里有一個(gè)注意點(diǎn):
因?yàn)楹笃谀悴豢赡芤恢痹谀硞€(gè)數(shù)據(jù)庫里面加一個(gè)數(shù)據(jù)集合,還得用到其他的庫,所以就得用到切換數(shù)據(jù)庫的功能。
setDatabase后,如果你不用afterPropertiesSet,是無法達(dá)到刷新連接信息的目的。
在看用redis實(shí)現(xiàn)異步消息隊(duì)列時(shí),遇到了注冊(cè)Event,其中看到了afterPropertiesSet。然后查博客,記錄下。
1、init-method方法,初始化bean的時(shí)候執(zhí)行,可以針對(duì)某個(gè)具體的bean進(jìn)行配置。init-method需要在applicationContext.xml配置文檔中bean的定義里頭寫明。例如:<bean id="TestBean" class="nju.software.xkxt.util.TestBean" init-method="init"></bean>這樣,當(dāng)TestBean在初始化的時(shí)候會(huì)執(zhí)行TestBean中定義的init方法。
2、afterPropertiesSet方法,初始化bean的時(shí)候執(zhí)行,可以針對(duì)某個(gè)具體的bean進(jìn)行配置。afterPropertiesSet 必須實(shí)現(xiàn) InitializingBean接口。實(shí)現(xiàn) InitializingBean接口必須實(shí)現(xiàn)afterPropertiesSet方法。
3、BeanPostProcessor,針對(duì)所有Spring上下文中所有的bean,可以在配置文檔applicationContext.xml中配置一個(gè)BeanPostProcessor,然后對(duì)所有的bean進(jìn)行一個(gè)初始化之前和之后的代理。BeanPostProcessor接口中有兩個(gè)方法: postProcessBeforeInitialization和postProcessAfterInitialization。 postProcessBeforeInitialization方法在bean初始化之前執(zhí)行, postProcessAfterInitialization方法在bean初始化之后執(zhí)行。
總之,afterPropertiesSet 和init-method之間的執(zhí)行順序是afterPropertiesSet 先執(zhí)行,init-method 后執(zhí)行。從BeanPostProcessor的作用,可以看出最先執(zhí)行的是postProcessBeforeInitialization,然后是afterPropertiesSet,然后是init-method,然后是postProcessAfterInitialization。
@Slf4j
@Component
public class RedisUtils {
? ? @Resource
? ? private RedisConfig redisConfig;
? ? /**
? ? * 根據(jù)db獲取對(duì)應(yīng)的redisTemplate實(shí)例
? ? *
? ? * @param db
? ? * @return redisTemplate實(shí)例
? ? */
? ? public RedisTemplate<Serializable, Object> getRedisTemplateByDb(final int db) {
? ? ? ? return redisConfig.setDataBase(db);
? ? }
? ? /**
? ? * 設(shè)置緩存
? ? *
? ? * @param key? 緩存key
? ? * @param value 緩存value
? ? */
? ? public void setString(String key, String value, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? redisTemplate.opsForValue().set(key, value);
? ? ? ? Loger.debug("RedisUtil:set cache key={},value={}", key, value);
? ? }
? ? /**
? ? * 設(shè)置緩存,并且自己指定過期時(shí)間
? ? *
? ? * @param key
? ? * @param value
? ? * @param expireTime 過期時(shí)間
? ? */
? ? public void setString(String key, String value, int expireTime, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? redisTemplate.opsForValue().set(key, value, expireTime, TimeUnit.SECONDS);
? ? ? ? Loger.debug("RedisUtil:set cache key={},value={}", key, value, expireTime, TimeUnit.SECONDS);
? ? }
? ? /**
? ? * 設(shè)置緩存對(duì)象,可指定DB
? ? *
? ? * @param key 緩存key
? ? * @param obj 緩存value
? ? */
? ? public <T> void setObject(String key, T obj, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? redisTemplate.opsForValue().set(key, obj);
? ? }
? ? /**
? ? * 新增hashMap值
? ? *
? ? * @param key
? ? * @param hashKey
? ? * @param hashValue
? ? * @param db
? ? * @return void
? ? * @author Xuyijieing
? ? * @date 2019年10月26日 9:22
? ? */
? ? public <T> void hashPutString(Serializable key, Serializable hashKey, String hashValue, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
? ? ? ? operations.put(key, hashKey, hashValue);
? ? }
? ? /**
? ? * 以map集合的形式添加鍵值對(duì)
? ? *
? ? * @param key
? ? * @param maps
? ? * @param db
? ? * @return void
? ? * @author Sunhj
? ? * @date 2019年10月26日 9:56
? ? */
? ? public void hashPutAll(String key, Map<Serializable, Serializable> maps, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
? ? ? ? operations.putAll(key, maps);
? ? }
? ? /**
? ? * 獲取變量中的鍵值對(duì)
? ? * {key3=value3, key1=value1, key5=value5, key4=value4, key2=value2}
? ? *
? ? * @param db
? ? * @param key
? ? * @return java.util.Map<String, String>
? ? * @author Xuyijie
? ? * @date 2019年10月26日 8:47
? ? */
? ? public <T> Map<Object, Object> hashGetAll(int db, Serializable key) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? return redisTemplate.opsForHash().entries(key);
? ? }
? ? /**
? ? * 判斷key是否存在
? ? *
? ? * @param key
? ? * @param db
? ? * @return java.util.Map<String, String>
? ? * @author Xuyijie
? ? * @date 2019年10月26日 8:47
? ? */
? ? public <T> Boolean hashHasKey(Serializable key, Serializable hahsKey, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? return redisTemplate.opsForHash().hasKey(key, hahsKey);
? ? }
? ? /**
? ? * 獲取hash表中存在的所有的鍵
? ? *
? ? * @param key
? ? * @param db
? ? * @return java.util.List<java.lang.String>
? ? * @author Sunhj
? ? * @date 2019年10月26日 10:58
? ? */
? ? public Set<Object> hashGetAllHashKeys(Serializable key, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? return redisTemplate.opsForHash().keys(key);
? ? }
? ? /**
? ? * 獲取hash表中存在的所有的值
? ? *
? ? * @param key
? ? * @param db
? ? * @return java.util.List<java.lang.String>
? ? * @author Sunhj
? ? * @date 2019年10月26日 10:58
? ? */
? ? public List<Object> hashGetAllHashValues(Serializable key, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? return redisTemplate.opsForHash().values(key);
? ? }
? ? /**
? ? * 根據(jù)key,hashKey
? ? * 獲取hash表中存在的單個(gè)值
? ? *
? ? * @param key
? ? * @param db
? ? * @return java.util.List<java.lang.String>
? ? * @author Sunhj
? ? * @date 2019年10月26日 10:58
? ? */
? ? public Object hashGetObject(Serializable key, Serializable hashKey, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? return redisTemplate.opsForHash().get(key, hashKey);
? ? }
? ? /**
? ? * 刪除一個(gè)或者多個(gè)hash表字段
? ? *
? ? * @param key
? ? * @param db
? ? * @param fields
? ? * @return java.lang.Long
? ? * @author Sunhj
? ? * @date 2019年10月26日 10:15
? ? */
? ? public Long hashDelete(Serializable key, int db, Serializable... fields) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
? ? ? ? return operations.delete(key, (Object) fields);
? ? }
? ? /**
? ? * 刪除一個(gè)hash表字段
? ? *
? ? * @param key
? ? * @param db
? ? * @param fields
? ? * @return java.lang.Long
? ? * @author Sunhj
? ? * @date 2019年10月26日 10:15
? ? */
? ? public boolean hashDeleteOne(Serializable key, String fields, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
? ? ? ? return operations.delete(key, fields) == 1;
? ? }
? ? /**
? ? * 設(shè)置緩存對(duì)象
? ? *
? ? * @param key 緩存key
? ? * @param obj 緩存value
? ? */
? ? public <T> void setObject(String key, T obj, int expireTime, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? redisTemplate.opsForValue().set(key, obj, expireTime, TimeUnit.SECONDS);
? ? }
? ? /**
? ? * 獲取指定key的緩存
? ? *
? ? * @param key---JSON.parseObject(value, User.class);
? ? */
? ? public Object getObject(String key, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? return redisTemplate.opsForValue().get(key);
? ? }
? ? /**
? ? * 獲取指定key的緩存
? ? *
? ? * @param key---JSON.parseObject(value, User.class);
? ? */
? ? public Object getKeys(String key, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? return redisTemplate.opsForValue().getOperations().keys(key);
? ? }
? ? /**
? ? * 判斷當(dāng)前key值 是否存在
? ? *
? ? * @param key
? ? */
? ? public boolean hasKey(String key, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? return redisTemplate.hasKey(key);
? ? }
? ? /**
? ? * 獲取指定key的緩存
? ? *
? ? * @param key
? ? */
? ? public String getString(String key, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? String value = (String) redisTemplate.opsForValue().get(key);
? ? ? ? Loger.debug("RedisUtil:get cache key={},value={}", key, value);
? ? ? ? return value;
? ? }
? ? /**
? ? * 刪除指定key的緩存
? ? *
? ? * @param key
? ? */
? ? public boolean delete(String key, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? return redisTemplate.delete(key);
? ? }
? ? /**
? ? * @param key
? ? * @throws
? ? * @Title: expire
? ? * @Description: 更新key的失效時(shí)間
? ? */
? ? public Boolean expire(String key, int seconds, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? Loger.debug("RedisUtil:expire cache key={}", key);
? ? ? ? return redisTemplate.expire(key, seconds, TimeUnit.SECONDS);
? ? }
? ? /**
? ? * 移除并獲取列表中第一個(gè)元素
? ? *
? ? * @param key
? ? * @param db
? ? * @return void
? ? * @author sunhj
? ? * @date 2019年10月26日 14:35
? ? */
? ? public String listLeftPop(Serializable key, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? Object leftPop = redisTemplate.opsForList().leftPop(key);
? ? ? ? if (leftPop == null) {
? ? ? ? ? ? return null;
? ? ? ? }
? ? ? ? return JSON.toJSONString(leftPop);
? ? }
? ? /**
? ? * 移除并獲取列表最后一個(gè)元素
? ? *
? ? * @param key
? ? * @param db
? ? * @return java.lang.Object
? ? * @author sunhj
? ? * @date 2019年10月26日 14:40
? ? */
? ? public String listRightPop(Serializable key, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? ListOperations<Serializable, Object> operations = redisTemplate.opsForList();
? ? ? ? Object x = operations.rightPop(key);
? ? ? ? if (x == null) {
? ? ? ? ? ? return null;
? ? ? ? }
? ? ? ? return JSON.toJSONString(x);
? ? }
? ? /**
? ? * 獲取變量中的指定map鍵是否有值,如果存在該map鍵則獲取值,沒有則返回null。
? ? *
? ? * @param key
? ? * @param field
? ? * @param db
? ? * @return T
? ? * @author Sunhj
? ? * @date 2019年10月26日 8:41
? ? */
? ? public <T> T hashGet(Serializable key, Serializable field, Class<T> t, int db) {
? ? ? ? try {
? ? ? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? ? ? HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
? ? ? ? ? ? //String x = Objects.requireNonNull(operations.get(key, field)).toString();
? ? ? ? ? ? //T y = JSON.parseObject(Objects.requireNonNull(operations.get(key, field)).toString(), t);
? ? ? ? ? ? //T y = JSON.parseObject(x , t);
? ? ? ? ? ? return JSON.parseObject(Objects.requireNonNull(operations.get(key, field)).toString(), t);
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? return null;
? ? ? ? }
? ? }
? ? /**
? ? * 獲取變量中的指定map鍵是否有值,如果存在該map鍵則獲取值(String格式),沒有則返回null。
? ? *
? ? * @param key
? ? * @param field
? ? * @param db
? ? * @return T
? ? * @author Sunhj
? ? * @date 2019年10月26日 8:41
? ? */
? ? public String hashGetString(Serializable key, Serializable field, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
? ? ? ? try {
? ? ? ? ? ? Serializable serializable = operations.get(key, field);
? ? ? ? ? ? if (serializable != null) {
? ? ? ? ? ? ? ? return serializable.toString();
? ? ? ? ? ? }
? ? ? ? ? ? return null;
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? Loger.error("hashGetString方法異常", e);
? ? ? ? ? ? return null;
? ? ? ? }
? ? }
? ? /**
? ? * 獲取變量中的鍵值對(duì) ??
? ? *
? ? * @param key
? ? * @param db
? ? * @return java.util.Map<String, String>
? ? * @author Sunhj
? ? * @date 2019年10月26日 8:47
? ? */
? ? public <T> Map<String, T> hashGetAll(Serializable key, Class<T> t, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
? ? ? ? Map<Serializable, Serializable> x = operations.entries(key);
? ? ? ? Map<String, T> map = new HashMap<>();
? ? ? ? try {
? ? ? ? ? ? for (Serializable xa : x.keySet()) {
? ? ? ? ? ? ? ? String keyValue = x.get(xa).toString();
? ? ? ? ? ? ? ? map.put(xa.toString(), JSON.parseObject(keyValue, t));
? ? ? ? ? ? }
? ? ? ? ? ? return map;
? ? ? ? } catch (Exception e) {
? ? ? ? ? ? return null;
? ? ? ? }
? ? }
? ? /**
? ? * 新增hashMap值
? ? *
? ? * @param key
? ? * @param hashKey
? ? * @param hashValue
? ? * @param db
? ? * @return void
? ? * @author Sunhj
? ? * @date 2019年10月26日 9:22
? ? */
? ? public <T> boolean hashPut(Serializable key, Serializable hashKey, T hashValue, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
? ? ? ? operations.put(key, hashKey, JSON.toJSONString(hashValue, SerializerFeature.WriteMapNullValue));
? ? ? ? return true;
? ? }
? ? /**
? ? * 查看hash表中指定字段是否存在
? ? *
? ? * @param key
? ? * @param field
? ? * @param db
? ? * @return boolean
? ? * @author Sunhj
? ? * @date 2019年10月26日 10:32
? ? */
? ? public boolean hashExists(Serializable key, Serializable field, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? HashOperations<Serializable, Serializable, Serializable> operations = redisTemplate.opsForHash();
? ? ? ? return operations.hasKey(key, field);
? ? }
? ? /**
? ? * 存儲(chǔ)在list的頭部,即添加一個(gè)就把它放在最前面的索引處
? ? *
? ? * @param key
? ? * @param value
? ? * @param db
? ? * @return java.lang.Long
? ? * @author sunhj
? ? * @date 2019年10月26日 14:03
? ? */
? ? public Long listLeftPush(Serializable key, Serializable value, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? ListOperations<Serializable, Object> operations = redisTemplate.opsForList();
? ? ? ? return operations.leftPush(key, value);
? ? }
? ? /**
? ? * 獲取所有的KEY
? ? *
? ? * @param key
? ? */
? ? public List<Object> getHashKeys(String key, int db) {
? ? ? ? RedisTemplate<Serializable, Object> redisTemplate = getRedisTemplateByDb(db);
? ? ? ? List<Object> values = redisTemplate.opsForHash().values(key);
? ? ? ? return values;
? ? }
}
這些都是比較簡(jiǎn)單的,,沒什么好說的
然后平常使用redis的時(shí)候,避免不了使用樹形的結(jié)構(gòu),就是

用:隔開的樹形結(jié)構(gòu),但是你用redisTeamplate用get()是拿不到的,而且你就算使用通配符也拿不到,這個(gè)就得看源碼了!具體的我不分析了,不然還是寫一大篇
有一個(gè)api 是可以用通配符的,用

這個(gè)是獲取Redis對(duì)應(yīng)的鍵才可以使用通配符,而且RedisManager也做了一個(gè)運(yùn)算符的展示:

其他的都在上面了,然后后面還要做一個(gè)Redis 的連接池,避免Redis的連接資源浪費(fèi)了,簡(jiǎn)單的就不多說了