第七节 数据字典:Hash哈希

一、心法

        Redis hash 是一个 string 类型的 field 和 value 的映射表,当然这里的string类型是指将数据序列化后的字符串。

        常见业务场景就是来缓存键值对。我举个例子,有一个班级里有三十个学生,每个学生都有唯一的学号,那么就能够使用Redis的hash进行存储。班级作为标识这些学生一个共性(key),也就是说可以通过这个班级来找到这群学生。在这群学生里面,每个学生(value)又有唯一的一个标识,例如学号(field)来区分他们。

         数据结构:  key班级  ------  field 学号  -----  value 具体学生

         因此,立刻想到使用Hash缓存的心法:有一个能够筛选出一组数据的标识key。在这组被筛选出来的数据中,每个数据自身又有一个唯一的标识符field,以此来标识它value。有着这类特点的数据,可以使用Redis的hash作为缓存。

        常见业务场景

(一)缓存字典表。一个简单的字典表,参照下图。type字段作为key, code字段作为field,对应的记录们作为value。

(二)缓存普通表 。表名(key)用于筛选一组数据(这张表里的所有数据),记录的主键ID(field)作为每条数据(value)的唯一标识符。

二、使用Hash示例

        页面上经常有类似于下拉框的键值对。比如,颜色、性别。这些数据都会存放在系统的字典表中。

        我考虑在系统上线的时候,把字典表的所有数据统统加载到Redis的缓存中。并且在每次操作字典表的时候,更新缓存。

        

        比如有上面的这张字典表。假设有管理页面,加入一条记录,如果操作字典表成功,那么就查询这张字典表的所有数据,将其加入到Redis的缓存中。例如color作为type,能够标识出颜色大类。sex作为type,能够表示出性别大类。

        数据结构示意图如下: 

        Key     -----------------    field  ---------------------   value

  自定义常量                     type字段        对应种类的多条记录List<Parameter>

public Integer addParameter(Parameter parameter) {

        parameter.setId(null);
        mapper.insertSelective(parameter);

        if (parameter.getId() > 0) {
            //实时同步缓存
            cacheAllConfig();
        }

        return parameter.getId();
    }

    private void cacheAllConfig() {
        //清除上次缓存
        redisTemplate.delete(Constant.MAP_KEY);
        HashOperations<String, String, List<Parameter>> hashOperations = this.getHashOperations();
        //获取字典表的所有数据
        List<Parameter> parameters = mapper.getAll();
        //字典表的type作为唯一标识符,标识一组数据
        for (Parameter parameter : parameters) {
            //对应API命令  Hget  key field
            List<Parameter> parametersList = hashOperations.get(Constant.MAP_KEY, parameter.getType());
            if (parametersList == null || parametersList.isEmpty()) {
                //如果添加的种类参数不在缓存中,那么就创建一个List
                parametersList = new ArrayList<>();
            }
            parametersList.add(parameter);
            hashOperations.put(Constant.MAP_KEY, parameter.getType(), parametersList);
        }
    }

private HashOperations getHashOperations() {
        return redisTemplate.opsForHash();
    }

        如何获取呢?

public Map<String, List<Parameter>> getParameter() {
        HashOperations<String, String, List<Parameter>> hashOperations = getHashOperations();
        //Hash的entries命令,获取key对应的所有的 field - value
        //这里的field就是 type, value就是type对应的多条记录
        Map<String, List<Parameter>> result = hashOperations.entries(Constant.MAP_KEY);
        return result;
    }

    public List<Parameter> getParameterByType(final String type) {
        HashOperations<String, String, List<Parameter>> hashOperations = getHashOperations();
        //基础的get命令   hget key filed 
        List<Parameter> result = hashOperations.get(Constant.MAP_KEY, type);
        return result;
    }


private HashOperations getHashOperations() {
        return redisTemplate.opsForHash();
    }

        我先添加一个字典表数据,触发上面的加载缓存操作,把所有字典表数据根据type,加载进Redis缓存中。

       再在页面上请求所有字典表数据,当然这些数据全部来自Redis中,就能避免与DB进行交互。

        最后测试,根据type来获取指定的字典表数据。

发布了315 篇原创文章 · 获赞 243 · 访问量 26万+

猜你喜欢

转载自blog.csdn.net/yanluandai1985/article/details/104382513