Для пары Key / Value Key-value Value redis, после многих времен шага на яму мы суммировали набор правил; эта статья в основном объясняет правила определения и меры предосторожности при определении пар клавиши / значение значения ключей.
В первой статье рассказывается, как определить клиент REDIS и интеграционную память Dubbo; когда мы действительно начнем разработку, он вдруг обнаружит, что немного неясно, как определить формат значения ключа и значения Redis, не волнуйтесь, мы сразу же Вы можете понять, как определить и использовать, давайте начнем объяснять, как это определить.
Два решения для интеграции Redis с Spring+Dubbo
1. Формат значения Redis
При традиционной разработке Java нам нужны объектно-ориентированные идеи.По сравнению с объектами, более часто используемые и быстро конвертируемые форматыJSON
Есть еще три популярные библиотеки для обработки данных JSON в Java.FastJSON
,Gson
иJackson
, я не буду здесь приводить их достоинства и недостатки, в этой статье используется АлиFastJSON
.
упомянутый вышеJSON
, это потому, что в хранилище Redis мы используем его для хранения значения value, зачем мы это делаем? В основном потому, что формат json имеет следующие преимущества:
· 1.标准,主流数据交换格式
· 2.简单,结构清晰,相对于XML来说更加的轻量级,易于解析
· 3.语言无关,任何语言都能轻松搞它
· 4.类型安全,值是有类型的,比如整数、字符串、布尔等
Давайте посмотрим, как использовать json для хранения значения, код выглядит следующим образом:
/**
* 在redis数据库中插入 key和value 并且设置过期时间
*
* @param key k
* @param value v
* @param exp 过期时间 s
* @return boolean
*/
@Override
public boolean set(String key, V value, int exp) {
Jedis jedis = null;
// 将 value 转换成 json 对象
// String jKey = JSON.toJSONString(key);
String jValue = JSON.toJSONString(value);
// 操作是否成功
boolean isSucess = true;
if (StringUtils.isEmpty(key)) {
LOG.info("key is empty");
return false;
}
try {
// 获取客户端对象
jedis = redisCache.getResource();
// 执行插入
jedis.setex(key, exp, jValue);
} catch (Exception e) {
LOG.info("client can't connect server");
isSucess = false;
if (null != jedis) {
// 释放jedis对象
redisCache.brokenResource(jedis);
}
return false;
} finally {
if (isSucess) {
// 返还连接池
redisCache.returnResource(jedis);
}
}
return true;
}
В коде мы преобразуем значение redis перед его сохранением, а также преобразуем объект V в объект json и сохраняем его; давайте посмотрим на формат значения значения в redis:
Выше мы видим, что в инструменте визуализации Redis rdm (Redis Desktop Manager) значение, соответствующее ключу key, очень четко отображается в json, что нам очень удобно для просмотра данных, хранящихся в Redis.
Я не знаю, если у вас нет, у меня есть примечание в коде выше, и код выглядит следующим образом:
// String jKey = JSON.toJSONString(key);
Эта строка означает jsonize ключа, разве это не означает, что json очень дружелюбен? Так зачем комментировать эту строку? Ниже поясняется, почему это делается.
Прежде всего, данные в формате json станут строкой String в формате josn, например"zhangsan"
, когда эта строка хранится как ключ, она по умолчанию будет иметь характеристики json, то есть двойные кавычки""
Он также будет занесен в настройки ключей redis, поэтому значения ключей, которые мы видим в rdm, будут занесены по умолчанию.""
, это действительно не очень красиво, особенно для нашего сложного бизнеса, как использовать правила ключ-значение для определения папок бизнес-линий в rdm я расскажу позже.
2. Формат ключа Redis
Вышеупомянутое простое хранилище ключей, такое какzhangsan
В это время можно удовлетворить обычные потребности, но в реальном бизнесе хранение ключевых ключей часто бывает очень сложным, например, у нас сейчас есть требование:
需求:根据基础数据系统中的数据字典类型查询对应的字典集合
В настоящее время бизнес, на который мы должны обратить внимание, усложняется, и обычный метод хранения ключей не может быть использован.Вышеуказанные требования можно условно разделить на:
1.系统:基础数据系统
2.模块:数据字典
3.方法:根据数据字典类型查询
4.参数:字典类型
Зачем так разделять? Для удобочитаемости, а также для абстрагирования правил хранения ключей; поскольку бизнес сложный, им нелегко управлять и находить слишком много ключей, когда мы определяем слишком много ключей.系统-模块-方法-参数
С таким определением правила мы можем четко понять, что делает значение, хранящееся в ключе redis, а также его можно сгруппировать в rdm, о чем речь пойдет позже.
Вставьте абстрактный класс инструмента Redis, определенный в соответствии с этим правилом ниже:
package com.yclimb.mdm.redis;
/**
* Redis 工具类
*
* @author yclimb
* @date 2018/4/19
*/
public class RedisUtils {
/**
* 主数据系统标识
*/
public static final String KEY_PREFIX = "mdm";
/**
* 分割字符,默认[:],使用:可用于rdm分组查看
*/
private static final String KEY_SPLIT_CHAR = ":";
/**
* redis的key键规则定义
* @param module 模块名称
* @param func 方法名称
* @param args 参数..
* @return key
*/
public static String keyBuilder(String module, String func, String... args) {
return keyBuilder(null, module, func, args);
}
/**
* redis的key键规则定义
* @param module 模块名称
* @param func 方法名称
* @param objStr 对象.toString()
* @return key
*/
public static String keyBuilder(String module, String func, String objStr) {
return keyBuilder(null, module, func, new String[]{objStr});
}
/**
* redis的key键规则定义
* @param prefix 项目前缀
* @param module 模块名称
* @param func 方法名称
* @param objStr 对象.toString()
* @return key
*/
public static String keyBuilder(String prefix, String module, String func, String objStr) {
return keyBuilder(prefix, module, func, new String[]{objStr});
}
/**
* redis的key键规则定义
* @param prefix 项目前缀
* @param module 模块名称
* @param func 方法名称
* @param args 参数..
* @return key
*/
public static String keyBuilder(String prefix, String module, String func, String... args) {
// 项目前缀
if (prefix == null) {
prefix = KEY_PREFIX;
}
StringBuilder key = new StringBuilder(prefix);
// KEY_SPLIT_CHAR 为分割字符
key.append(KEY_SPLIT_CHAR).append(module).append(KEY_SPLIT_CHAR).append(func);
for (String arg : args) {
key.append(KEY_SPLIT_CHAR).append(arg);
}
return key.toString();
}
/**
* redis的key键规则定义
* @param redisEnum 枚举对象
* @param objStr 对象.toString()
* @return key
*/
public static String keyBuilder(RedisEnum redisEnum, String objStr) {
return keyBuilder(redisEnum.getKeyPrefix(), redisEnum.getModule(), redisEnum.getFunc(), objStr);
}
}
Этот текстовый код имеет описанный выше分割字符,默认[:],使用:可用于rdm分组查看
;Ключ Redis по умолчанию разделен двоеточием.Преимущество в том, что его можно группировать и просматривать в виде папок в rdm, как показано на рисунке:
3. Используйте классы enum для определения правил
Вышеприведенный класс инструментов имеет следующий код, который назначается в виде перечисления:
/**
* redis的key键规则定义
* @param redisEnum 枚举对象
* @param objStr 对象.toString()
* @return key
*/
public static String keyBuilder(RedisEnum redisEnum, String objStr) {
return keyBuilder(redisEnum.getKeyPrefix(), redisEnum.getModule(), redisEnum.getFunc(), objStr);
}
Вот код класса перечисления:
package com.yclimb.mdm.redis;
/**
* Redis 枚举类
*
* @author yclimb
* @date 2018/4/19
*/
public enum RedisEnum {
/**
* 数据字典Service - 根据字典类型查询字典数据
*/
MDM_MSTDATADICTIONARYSERVICE_QUERYLISTBYENTITYREDIS(
RedisUtils.KEY_PREFIX, "MstDataDictionaryService", "queryListByEntityRedis", "数据字典Redis缓存");
/**
* 系统标识
*/
private String keyPrefix;
/**
* 模块名称
*/
private String module;
/**
* 方法名称
*/
private String func;
/**
* 描述
*/
private String remark;
RedisEnum(String keyPrefix, String module, String func, String remark) {
this.keyPrefix = keyPrefix;
this.module = module;
this.func = func;
this.remark = remark;
}
getter and setter....
}
Используя приведенный выше класс перечисления, вы можете определить требуемый тип перечисления в соответствии с модулем и методом, который прост в управлении и обслуживании, а также очень удобен в использовании.Код использования выглядит следующим образом:
@Override
public List<MstDataDictionary> queryListByEntityRedis(MstDataDictionary mstDataDictionary) {
// redis key 获取
String redisKey = RedisUtils.keyBuilder(RedisEnum.MDM_MSTDATADICTIONARYSERVICE_QUERYLISTBYENTITYREDIS, (null == mstDataDictionary ? "" : mstDataDictionary.toString()));
// 查询redis缓存
List<MstDataDictionary> mstDataDictionaryList = (List<MstDataDictionary>) redisCacheService.get(redisKey);
// 如果没有缓存则查询数据库后赋值
if (mstDataDictionaryList == null || mstDataDictionaryList.size() <= 0) {
mstDataDictionaryList = mstDataDictionaryMapper.queryListByEntity(mstDataDictionary);
redisCacheService.set(redisKey, mstDataDictionaryList);
}
return mstDataDictionaryList;
}
Хорошо, я почти закончил здесь.Согласно вышеупомянутому методу подмодуля, настройте имя ключа Redis и используйте json для хранения формата значения;
Также можно использовать определение правила для ключевых ключей.Constants
Для реализации используются константные классы, а конкретные правила зависят от личных предпочтений и потребностей.
Эпилог
Конкретный код класса инструмента определения правила приведен выше, и это также исходный код.
Эта статья окончена, обратите внимание на официальный аккаунт, чтобы увидеть больше! ! !