mirror of
https://github.com/LamGC/ContentGrabbingJi.git
synced 2025-07-04 06:17:26 +00:00
[Add][Update] CacheStore-redis 添加 Redis 缓存存储容器的实现模块;
[Add] META-INF/services/* 支持 SPI 机制; [Add] RedisCacheStore, RedisCacheStoreFactory, RedisConnectionPool, RedisUtils 添加相关父类和辅助类; [Add] RedisMapCacheStore, RedisMapCacheStoreTest 添加映射表缓存相关实现及完整单元测试; [Add] RedisSingleCacheStore, RedisSingleCacheStoreTest 添加单项缓存相关实现及完整单元测试; [Update] redis.clients:jedis 更新依赖项版本(3.2.0 -> 3.3.0);
This commit is contained in:
102
ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisCacheStore.java
vendored
Normal file
102
ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisCacheStore.java
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2020 LamGC
|
||||
*
|
||||
* ContentGrabbingJi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* ContentGrabbingJi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.lamgc.cgj.bot.cache.redis;
|
||||
|
||||
import net.lamgc.cgj.bot.cache.CacheKey;
|
||||
import net.lamgc.cgj.bot.cache.CacheStore;
|
||||
import redis.clients.jedis.Jedis;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LamGC
|
||||
*/
|
||||
public abstract class RedisCacheStore<V> implements CacheStore<V> {
|
||||
|
||||
/**
|
||||
* 获取 Key 前缀.
|
||||
* <p>key = getKeyPrefix() + key
|
||||
* @param cacheKey CacheKey 对象.
|
||||
* @return 返回 Key 前缀.
|
||||
*/
|
||||
protected String getKeyString(CacheKey cacheKey) {
|
||||
return getKeyPrefix() + cacheKey.join(RedisUtils.KEY_SEPARATOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Key 的完整前缀.
|
||||
* @return 返回完整前缀.
|
||||
*/
|
||||
protected abstract String getKeyPrefix();
|
||||
|
||||
@Override
|
||||
public boolean setTimeToLive(CacheKey key, long ttl) {
|
||||
String keyString = getKeyString(key);
|
||||
return RedisConnectionPool.executeRedis(jedis -> {
|
||||
Long result;
|
||||
if (ttl >= 0) {
|
||||
result = jedis.pexpire(keyString, ttl);
|
||||
} else {
|
||||
result = jedis.persist(keyString);
|
||||
}
|
||||
return result == RedisUtils.RETURN_CODE_OK;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTimeToLive(CacheKey key) {
|
||||
return RedisConnectionPool.executeRedis(jedis -> {
|
||||
Long ttl = jedis.pttl(getKeyString(key));
|
||||
return ttl < 0 ? -1 : ttl;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public long size() {
|
||||
return RedisConnectionPool.executeRedis(Jedis::dbSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clear() {
|
||||
return RedisConnectionPool.executeRedis(jedis -> RedisUtils.isOk(jedis.flushDB()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists(CacheKey key) {
|
||||
return RedisConnectionPool.executeRedis(jedis -> jedis.exists(getKeyString(key)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(CacheKey key) {
|
||||
return RedisConnectionPool.executeRedis(jedis -> jedis.del(getKeyString(key)) == RedisUtils.RETURN_CODE_OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> keySet() {
|
||||
Set<String> keys = RedisConnectionPool.executeRedis(jedis -> jedis.keys(RedisUtils.KEY_PATTERN_ALL));
|
||||
final int prefixLength = getKeyPrefix().length();
|
||||
Set<String> newKeys = new HashSet<>();
|
||||
for (String key : keys) {
|
||||
newKeys.add(key.substring(prefixLength));
|
||||
}
|
||||
return newKeys;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2020 LamGC
|
||||
*
|
||||
* ContentGrabbingJi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* ContentGrabbingJi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.lamgc.cgj.bot.cache.redis;
|
||||
|
||||
import net.lamgc.cgj.bot.cache.*;
|
||||
import net.lamgc.cgj.bot.cache.convert.StringConverter;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LamGC
|
||||
*/
|
||||
@Factory(name = "Redis")
|
||||
public class RedisCacheStoreFactory implements CacheStoreFactory {
|
||||
@Override
|
||||
public <V> SingleCacheStore<V> newSingleCacheStore(String identify, StringConverter<V> converter) {
|
||||
return new RedisSingleCacheStore<>(identify, converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E> ListCacheStore<E> newListCacheStore(String identify, StringConverter<E> converter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E> SetCacheStore<E> newSetCacheStore(String identify, StringConverter<E> converter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> MapCacheStore<V> newMapCacheStore(String identify, StringConverter<V> converter) {
|
||||
return new RedisMapCacheStore<>(identify, converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canGetCacheStore() {
|
||||
return RedisConnectionPool.available();
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2020 LamGC
|
||||
*
|
||||
* ContentGrabbingJi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* ContentGrabbingJi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.lamgc.cgj.bot.cache.redis;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.JedisPool;
|
||||
import redis.clients.jedis.JedisPoolConfig;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 统一的 Redis 连接池.
|
||||
* @author LamGC
|
||||
*/
|
||||
public class RedisConnectionPool {
|
||||
|
||||
private final static Logger log = LoggerFactory.getLogger(RedisConnectionPool.class);
|
||||
private final static AtomicReference<JedisPool> POOL = new AtomicReference<>();
|
||||
|
||||
public static synchronized void reconnectRedis() {
|
||||
JedisPool jedisPool = POOL.get();
|
||||
if (jedisPool != null && !jedisPool.isClosed()) {
|
||||
return;
|
||||
}
|
||||
JedisPoolConfig config = new JedisPoolConfig();
|
||||
config.setTestOnBorrow(true);
|
||||
config.setTestOnReturn(true);
|
||||
jedisPool = new JedisPool(config);
|
||||
POOL.set(jedisPool);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取一个 Jedis 对象.
|
||||
* <p>注意, 需回收 Jedis 对象, 否则可能会耗尽连接池导致后续操作受到影响.
|
||||
* @return 返回可用的 Jedis 连接.
|
||||
*/
|
||||
public static Jedis getConnection() {
|
||||
JedisPool pool = POOL.get();
|
||||
if (pool == null || pool.isClosed()) {
|
||||
reconnectRedis();
|
||||
pool = POOL.get();
|
||||
if (pool == null) {
|
||||
throw new IllegalStateException("Redis connection lost");
|
||||
}
|
||||
}
|
||||
return pool.getResource();
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行 Redis 操作并返回相关值.
|
||||
* <p>本方法会自动回收 Jedis.
|
||||
* @param function 待运行的操作.
|
||||
* @param <R> 返回值类型.
|
||||
* @return 返回 function 返回的内容.
|
||||
*/
|
||||
public static <R> R executeRedis(Function<Jedis, R> function) {
|
||||
try (Jedis jedis = getConnection()) {
|
||||
return function.apply(jedis);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查 Redis 连接池是否有可用的资源.
|
||||
* @return 如果连接池依然活跃, 返回 true.
|
||||
*/
|
||||
public static boolean available() {
|
||||
JedisPool jedisPool = POOL.get();
|
||||
if (jedisPool == null || jedisPool.isClosed()) {
|
||||
reconnectRedis();
|
||||
if (jedisPool == null || jedisPool.isClosed()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (jedisPool.getNumIdle() == 0) {
|
||||
try (Jedis jedis = jedisPool.getResource()) {
|
||||
return "pong".equalsIgnoreCase(jedis.ping());
|
||||
} catch (Exception e) {
|
||||
log.error("Redis 连接测试时发生异常", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (C) 2020 LamGC
|
||||
*
|
||||
* ContentGrabbingJi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* ContentGrabbingJi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.lamgc.cgj.bot.cache.redis;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import net.lamgc.cgj.bot.cache.CacheKey;
|
||||
import net.lamgc.cgj.bot.cache.MapCacheStore;
|
||||
import net.lamgc.cgj.bot.cache.convert.StringConverter;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Redis Map缓存存储容器.
|
||||
* @param <V> 值类型.
|
||||
* @author LamGC
|
||||
*/
|
||||
public class RedisMapCacheStore<V> extends RedisCacheStore<Map<String, V>> implements MapCacheStore<V> {
|
||||
|
||||
private final String keyPrefix;
|
||||
private final StringConverter<V> converter;
|
||||
|
||||
public RedisMapCacheStore(String keyPrefix, StringConverter<V> converter) {
|
||||
keyPrefix = Strings.nullToEmpty(keyPrefix).trim();
|
||||
if (!keyPrefix.isEmpty() && keyPrefix.endsWith(RedisUtils.KEY_SEPARATOR)) {
|
||||
this.keyPrefix = keyPrefix;
|
||||
} else {
|
||||
this.keyPrefix = keyPrefix + RedisUtils.KEY_SEPARATOR;
|
||||
}
|
||||
|
||||
this.converter = Objects.requireNonNull(converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getKeyPrefix() {
|
||||
return this.keyPrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int mapSize(CacheKey key) {
|
||||
return RedisConnectionPool.executeRedis(jedis -> {
|
||||
String keyString = getKeyString(key);
|
||||
if (jedis.exists(keyString)) {
|
||||
return jedis.hlen(keyString).intValue();
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> mapFieldSet(CacheKey key) {
|
||||
return RedisConnectionPool.executeRedis(jedis -> {
|
||||
String keyString = getKeyString(key);
|
||||
if (jedis.exists(keyString)) {
|
||||
return jedis.hkeys(keyString);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> mapValueSet(CacheKey key) {
|
||||
List<String> rawValueSet = RedisConnectionPool.executeRedis(jedis -> {
|
||||
String keyString = getKeyString(key);
|
||||
if (jedis.exists(keyString)) {
|
||||
return jedis.hvals(keyString);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
|
||||
if (rawValueSet == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Set<V> result = new HashSet<>();
|
||||
for (String rawValue : rawValueSet) {
|
||||
result.add(converter.from(rawValue));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean put(CacheKey key, String field, V value) {
|
||||
Objects.requireNonNull(field);
|
||||
Objects.requireNonNull(value);
|
||||
return RedisConnectionPool.executeRedis(jedis -> {
|
||||
String keyString = getKeyString(key);
|
||||
return jedis.hset(keyString, field, converter.to(value)) == RedisUtils.RETURN_CODE_OK;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putAll(CacheKey key, Map<String, V> map) {
|
||||
Objects.requireNonNull(key);
|
||||
Objects.requireNonNull(map);
|
||||
if (map.size() == 0 && exists(key)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final Map<String, String> targetMap = new HashMap<>(map.size());
|
||||
map.forEach((k, v) -> targetMap.put(k, converter.to(v)));
|
||||
return RedisConnectionPool.executeRedis(jedis -> {
|
||||
String keyString = getKeyString(key);
|
||||
return RedisUtils.isOk(jedis.hmset(keyString, targetMap));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean putIfNotExist(CacheKey key, String field, V value) {
|
||||
Objects.requireNonNull(field);
|
||||
Objects.requireNonNull(value);
|
||||
return RedisConnectionPool.executeRedis(jedis -> {
|
||||
String keyString = getKeyString(key);
|
||||
return jedis.hsetnx(keyString, field, converter.to(value)) == RedisUtils.RETURN_CODE_OK;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(CacheKey key, String field) {
|
||||
Objects.requireNonNull(field);
|
||||
String value = RedisConnectionPool.executeRedis(jedis -> jedis.hget(getKeyString(key), field));
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return converter.from(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeField(CacheKey key, String field) {
|
||||
Objects.requireNonNull(field);
|
||||
return RedisConnectionPool.executeRedis(jedis ->
|
||||
jedis.hdel(getKeyString(key), field) == RedisUtils.RETURN_CODE_OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsField(CacheKey key, String field) {
|
||||
Objects.requireNonNull(field);
|
||||
return RedisConnectionPool.executeRedis(jedis -> jedis.hexists(getKeyString(key), field));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mapIsEmpty(CacheKey key) {
|
||||
return mapSize(key) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearMap(CacheKey key) {
|
||||
Set<String> fields = mapFieldSet(key);
|
||||
if (fields == null) {
|
||||
return false;
|
||||
} else if (fields.size() == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
String[] fieldsArray = new String[fields.size()];
|
||||
fields.toArray(fieldsArray);
|
||||
return RedisConnectionPool.executeRedis(jedis ->
|
||||
jedis.hdel(getKeyString(key), fieldsArray) != RedisUtils.RETURN_CODE_FAILED);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) 2020 LamGC
|
||||
*
|
||||
* ContentGrabbingJi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* ContentGrabbingJi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.lamgc.cgj.bot.cache.redis;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import net.lamgc.cgj.bot.cache.CacheKey;
|
||||
import net.lamgc.cgj.bot.cache.SingleCacheStore;
|
||||
import net.lamgc.cgj.bot.cache.convert.StringConverter;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Redis 单项缓存存储容器.
|
||||
* @param <V> 值类型.
|
||||
* @see net.lamgc.cgj.bot.cache.CacheStore
|
||||
* @see net.lamgc.cgj.bot.cache.SingleCacheStore
|
||||
* @see net.lamgc.cgj.bot.cache.redis.RedisCacheStore
|
||||
* @author LamGC
|
||||
*/
|
||||
public class RedisSingleCacheStore<V> extends RedisCacheStore<V> implements SingleCacheStore<V> {
|
||||
|
||||
private final String keyPrefix;
|
||||
private final StringConverter<V> converter;
|
||||
|
||||
public RedisSingleCacheStore(String keyPrefix, StringConverter<V> converter) {
|
||||
keyPrefix = Strings.nullToEmpty(keyPrefix).trim();
|
||||
if (!keyPrefix.isEmpty() && keyPrefix.endsWith(RedisUtils.KEY_SEPARATOR)) {
|
||||
this.keyPrefix = keyPrefix;
|
||||
} else {
|
||||
this.keyPrefix = keyPrefix + RedisUtils.KEY_SEPARATOR;
|
||||
}
|
||||
|
||||
this.converter = Objects.requireNonNull(converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean set(CacheKey key, V value) {
|
||||
return RedisConnectionPool.executeRedis(jedis ->
|
||||
RedisUtils.isOk(jedis.set(getKeyString(key), converter.to(Objects.requireNonNull(value)))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setIfNotExist(CacheKey key, V value) {
|
||||
return RedisConnectionPool.executeRedis(jedis ->
|
||||
jedis.setnx(getKeyString(key), converter.to(Objects.requireNonNull(value)))
|
||||
== RedisUtils.RETURN_CODE_OK);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(CacheKey key) {
|
||||
String value = RedisConnectionPool.executeRedis(jedis -> jedis.get(getKeyString(key)));
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return converter.from(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getKeyPrefix() {
|
||||
return this.keyPrefix;
|
||||
}
|
||||
}
|
54
ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisUtils.java
vendored
Normal file
54
ContentGrabbingJi-CacheStore-redis/src/main/java/net/lamgc/cgj/bot/cache/redis/RedisUtils.java
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2020 LamGC
|
||||
*
|
||||
* ContentGrabbingJi is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* ContentGrabbingJi is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package net.lamgc.cgj.bot.cache.redis;
|
||||
|
||||
/**
|
||||
* @author LamGC
|
||||
*/
|
||||
public class RedisUtils {
|
||||
|
||||
/**
|
||||
* 返回码 - 成功
|
||||
*/
|
||||
public final static int RETURN_CODE_OK = 1;
|
||||
|
||||
/**
|
||||
* 返回码 - 失败
|
||||
*/
|
||||
public final static int RETURN_CODE_FAILED = 0;
|
||||
|
||||
/**
|
||||
* Key匹配规则 - 所有Key
|
||||
*/
|
||||
public final static String KEY_PATTERN_ALL = "*";
|
||||
|
||||
/**
|
||||
* Key 分隔符
|
||||
*/
|
||||
public final static String KEY_SEPARATOR = ":";
|
||||
|
||||
/**
|
||||
* 检查字符串返回结果是否为操作成功.
|
||||
* @param result 字符串返回结果.
|
||||
* @return 如果为操作成功, 返回 true.
|
||||
*/
|
||||
public static boolean isOk(String result) {
|
||||
return "OK".equalsIgnoreCase(result);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
#
|
||||
# Copyright (C) 2020 LamGC
|
||||
#
|
||||
# ContentGrabbingJi is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# ContentGrabbingJi is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
net.lamgc.cgj.bot.cache.redis.RedisCacheStoreFactory
|
Reference in New Issue
Block a user