伙伴匹配(后端)-- 根据标签搜索用户

功能需求分析

1.允许用户传入多个标签,多个标签都存在才搜索出来 (目前做的是这个)
2.允许用户传入多个标签,有任何一个标签存在就能搜索出来

两种方式

1.sql查询

根据标签搜索用户业务逻辑(sql)(实现简单)

2.内存查询

内存查询业务逻辑

1.先查询所有用户
2.在内存中判断是否包含要求的标签(灵活)

解析json字符串

为什么需要解析json字符串?

内存中查询出来的一个用户的所有标签是json字符串格式的数据,需要把它解析成集合

什么是序列化反序列化?

序列化:java对象转成json
反序列化:把json转为Java对象

Java json序列化库:

1.fastjson
2.gson

<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.9</version>
</dependency>

3.jackson
4.kryo

内存查询代码

@Override
public List<User> searchUsersBytags(List<String> tags) {
    if (CollectionUtils.isEmpty(tags)) {
        throw new BusinessException(ErrorCode.PARAMS_ERROR);
    }
    //        //从数据库中进行模糊查询
    //        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    //        for(String tag : tags){
    //            queryWrapper.like("tags",tag);
    //        }
    //        List<User> userList = userMapper.selectList(queryWrapper);
    //        //脱敏
    //        return userList.stream().map(user -> getSafetyUser(user)).collect(Collectors.toList());

    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    List<User> userList = userMapper.selectList(queryWrapper);
    Gson gson = new Gson();
    //        for (User user : userList) {
    //内存中用户的标签
    //            String Usertags = user.getTags();
    //            Set<String> tagSet = gson.fromJson(Usertags, new TypeToken<Set<String>>() {
    //            }.getType());
    //  tagSet = Optional.ofNullable(tagSet).orElse(new HashSet<>());
    //遍历传入的标签列表,如果有一个标签用户不存在,就不行,全部存在才可以
    //            for (String tag : tags) {
    //                if (!tagSet.contains(tag)) {
    //                    return false;
    //                }
    //            }
    //            return true;
    //        }
    //语法糖
    return userList.stream().filter(user -> {
        String Usertags = user.getTags();
        if (StringUtils.isBlank(Usertags)) {
            return false;
        }
        Set<String> tagSet = gson.fromJson(Usertags, new TypeToken<Set<String>>() {
        }.getType());
           tagSet = Optional.ofNullable(tagSet).orElse(new HashSet<>());
        for (String tag : tags) {
            if (!tagSet.contains(tag)) {
                return false;
            }
        }
        return true;
    }).map(user -> getSafetyUser(user)).collect(Collectors.toList());
    //        return userList.stream().map(user -> getSafetyUser(user)).collect(Collectors.toList());
}

如何选择

1.如果参数可以分析,根据用户的参数取选择查询方式,比如标签数
2.如果参数不可以分析。并且数据库连接足够,内存空间足够,可以并发同时查询,谁先返回用谁
3.还可以sql查询与内存运算结合,比如先用sql过滤掉部分tag

mybatis-plus开启查询日志

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl 

注意替换项目名

拉取别人的项目记得要ctrl + shift + r将文件名和代码中项目名替换为自己的

出现的小bug

//com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: One record is expected, but the query result is multiple records

//selectOne期望返回1但实际返回了多条
//        User user = userMapper.selectOne(null);

接口实现

    @GetMapping("/search/tags")
    public BaseResponse<List<User>> searchUsersByTags(@RequestParam(required = false) List<String> tags) {
        if(CollectionUtils.isEmpty(tags)){
            return ResultUtils.error(ErrorCode.PARAMS_ERROR);
        }
        List<User> userList = userService.searchUsersBytags(tags);
        return ResultUtils.success(userList);
    }

java8 parallelstream的坑

线程安全问题,数据量小时造成性能开销

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值