Redis устанавливает определение правила «ключ-значение» и меры предосторожности (с классом инструментов)

Java Redis задняя часть JSON

Для пары 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:

zhangsan

Выше мы видим, что в инструменте визуализации Redis rdm (Redis Desktop Manager) значение, соответствующее ключу key, очень четко отображается в json, что нам очень удобно для просмотра данных, хранящихся в Redis.

Я не знаю, если у вас нет, у меня есть примечание в коде выше, и код выглядит следующим образом:

// String jKey = JSON.toJSONString(key);

Эта строка означает jsonize ключа, разве это не означает, что json очень дружелюбен? Так зачем комментировать эту строку? Ниже поясняется, почему это делается.

Прежде всего, данные в формате json станут строкой String в формате josn, например"zhangsan", когда эта строка хранится как ключ, она по умолчанию будет иметь характеристики json, то есть двойные кавычки""Он также будет занесен в настройки ключей redis, поэтому значения ключей, которые мы видим в rdm, будут занесены по умолчанию."", это действительно не очень красиво, особенно для нашего сложного бизнеса, как использовать правила ключ-значение для определения папок бизнес-линий в rdm я расскажу позже.

json zhangsan

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Для реализации используются константные классы, а конкретные правила зависят от личных предпочтений и потребностей.

Эпилог

Конкретный код класса инструмента определения правила приведен выше, и это также исходный код.

Эта статья окончена, обратите внимание на официальный аккаунт, чтобы увидеть больше! ! !


关注我的公众号