0
点赞
收藏
分享

微信扫一扫

获得问题标签列表

灵魂跑者 2022-02-28 阅读 25

在这里插入图片描述
考虑到一个问题相关到标签一旦选定就很少更改,所以在Question设计一个冗余类tag_names,储存当前问题相关名称,这样查询标签的时候就不用进行复杂关联查询了。

  • 但是客服端如何做到完整的Tag信息呢,可以在服务器端利用缓存的tag信息组装一个信息。

首先为Question类型添加tags属性,表示当前Question完整Tag信息利用注解@TableField(exist = false)通知MyBatisPlus,这个属性不来自数据库。避免发生映射故障。

为了提高查询性能,在TagServiceImpl中添加一个散列表,缓存全部Tag信息。这里为了解决散列表被并发访问的问题,采用ConcurrentHashMap类型散列表,这个类来自Java并发包,相对于HashMap提供了并发安全功能。并且其内部分段式加锁机制,可以保证并且安全情况下具有更好的访问性能。这个散列表在加载Tag数据时候一同被初始化。

接口

Map<String, Tag> getName2TagMap();

实现

//注入map,key是String类型,value是tag类型
private final Map<String,Tag> name2TagMap = new ConcurrentHashMap<>();

    @Override
    public List<Tag> getTags() {
        if(tags.isEmpty()){
            //进行同步
            synchronized (tags){
                //再次检查
                if (tags.isEmpty()){
                    //list() 是Mybatis plus提供的方法,在ServiceImpl中定义
                    //继承与ServiceImpl的方法,方法的作用就是返回数据库中Tag对象
                    tags.addAll(list());
                    //tag的name作为key,把tag放进去
                    tags.forEach(tag -> name2TagMap.put(tag.getName(),tag));
                    log.debug("加载tag列表{}",tags);
                    log.debug("加载了Map{}",name2TagMap);
                }
            }
        }
        return tags;
    }

    @Override
    public Map<String, Tag> getName2TagMap() {
        if (tags.isEmpty()){
            getTags();
        }

        return name2TagMap;
    }

测试方法

@Test
    public void getName2TagMap(){
        Map<String,Tag > tagMap = tagService.getName2TagMap();
        tagMap.forEach((name,tag) -> System.out.println(name + ":" + tag));
    }
举报

相关推荐

0 条评论