<2021SC@SDUSC>山东大学软件工程应用与实践JPress代码分析(十三)

2021SC@SDUSC

本篇文章围绕UserOpenidService、UserTagService两个接口以及实现类进行代码分析,主要内容为JPress对于第三方的访问的使用的信息记录,以及用户增加用户标签的非主要功能方法的实现。

一、UserOpenidService

JPress搭建网站支持用户的第三方访问,如wechat、qq、钉钉、微博、github、gitee等,由此产生UserOpenidService与UserOpenidServiceProvider。

1.1 数据库表

因为JPress构建网站后,支持第三方的访问,因此需要给每个用户的每个第三方适配id。因此使用user_openid表。
在这里插入图片描述

1.2 UserOpenidService接口用途

因为对于该类的使用之处多在于用户登录、用户注销以及发布文章时的身份标识,因此接口多为增删改查的用途。

List<UserOpenid> findListByColumns(Columns columns);

根据某个列值(属性)查询数据,返回UserOpenid类的对象。

boolean batchDeleteByIds(Object... ids);

根据多个id批量删除user_openid数据

Page<UserOpenid> paginate(int page, int pageSize);

使用分页技术对查询的用户第三方进行分页,适用于超级管理员批量查询用户时使用。

User findByTypeAndOpenId(String type, String openId);

根据第三方id以及第三方的类型查询出对应的用户账号

void batchDeleteByUserId(Object userId);

批处理删除用户id相关的第三方信息,用于删除该用户时同时对多个第三方的注销。

1.3 UserOpenidServiceProvider

UserOpenidServiceProvider提供对接口的方法实现。重要方法的解析如下:

@Override
@Cacheable(name = "useropenid",key = "#(type)-#(openId)")
public User findByTypeAndOpenId(String type, String openId) {
    if (StrUtil.isBlank(type) || StrUtil.isBlank(openId)){
        return null;
    }
    UserOpenid userOpenid = DAO.findFirstByColumns(Columns.create("type", type).eq("value", openId));
    return userOpenid != null ? userService.findById(userOpenid.getUserId()) : null;
}
  • findByTypeAndOpenId方法为通过第三方的类型与对应的第三方openid进行用户的查找,返回user对象。
  • 使用@Cacheable注解,将查询的结果存储在缓存当中,key为(type)-(openId)的形式,name为useropenid。
  • 使用底层的DAO层首先查找userOpenid ,其中使用了io.jboot.db.model.Columns;的属性操作的create与eq方法。如果查询成功,通过userOpenid 查询表中该openid对应的user对象。
@Override
public void shouldUpdateCache(int action, Model model, Object id) {
   if (model instanceof UserOpenid){
       UserOpenid userOpenid = (UserOpenid) model;
       Jboot.getCache().remove("useropenid",userOpenid.getType()+"-"+userOpenid.getValue());
   }
}
  • shouldUpdateCache方法意为将状态设置为应该更新缓存,待自动更新缓存时会将对应内容更新。
  • 如果model(代表一行数据或一个对象)是UserOpenid类的实例对象,则将model转换为UserOpenid类。
  • 通过Jboot的getCache的方法读取缓存,并将对应key的缓存值删除,以利于下次更新缓存。

二、UserTagService

本类的接口与实现类实现了用户对自己的tag的增加和删除,有利于在使用SEO关键字时搜索到对应的用户。

2.1 数据库表

首先需要一个记录tag的数据库表。
在这里插入图片描述
有了tag以及id之后,因为每个用户有多个tag,所以需要一张tag与user的映射表。
在这里插入图片描述

2.2 UserTagService接口用途

撇开对tag的简单增删改查的接口不谈,UserTagService中还有部分重要接口函数。

Page<UserTag> paginateByColumns(int page, int pageSize, Columns columns, String orderBy);

对固定的columns进行排序,返回Page对象

List<UserTag> findListByUserId(Object userId);

通过用户的id找到他本人所有的用户tag,返回tag的列表。

List<UserTag> findHotList(int count);

通过计数,找到热度最高的tag的列表。

void doUpdateTags(long userId, Long[] tagIds);

输入一串tag的id,更新用户的tag。

2.3 UserTagServiceProvider

UserOpenidServiceProvider提供对接口的方法实现。重要方法的解析如下:

@Override
public List<UserTag> findListByUserId(Object userId) {
    List<Record> mapping = Db.find("select * from user_tag_mapping where user_id = ?",userId);
    if (mapping == null || mapping.isEmpty()){
        return null;
    }

    return mapping.stream()
            .map(record -> findById(record.get("tag_id")))
            .collect(Collectors.toList());

}
  • findListByUserId方法的目的为通过用户的id找到他本人所有的用户tag,返回tag的列表。
  • 通过Db查询到user_tag_mapping中对应该用户的所有tagid。
  • 使用stream()方法获得集合操作的数据流,并在user_tag表中用map()方法得到了对应的tag值。

注:stream()的使用

  • Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。
  • 特点:
  1. 不是数据结构,不会保存数据。
  2. 不会修改原来的数据源,它会将操作后的数据保存到另外一个对象中。(保留意见:毕竟peek方法可以修改流中元素)
  3. 惰性求值,流在中间处理过程中,只是对操作进行了记录,并不会立即执行,需要等到执行终止操作的时候才会进行实际的计算。
@Override
public void doUpdateTags(long userId, Long[] tagIds) {
    Db.tx(() -> {
        Db.update("delete from user_tag_mapping where user_id = ?", userId);

        if (tagIds != null && tagIds.length > 0) {
            List<Record> records = new ArrayList<>();
            for (long tagId : tagIds) {
                Record record = new Record();
                record.set("user_id", userId);
                record.set("tag_id", tagId);
                records.add(record);
            }
            Db.batchSave("user_tag_mapping", records, records.size());
        }

        return true;
    });
}
  • doUpdateTags方法的作用是根据输入的一组tagId的值更新tag。
  • 实现通过Db操作,删除用户与tag表之间的映射的信息。
  • 在通过传入的tagId数组,重新生成Record 信息,添加入user_tag_mapping表中,实现了读目前tag的映射的更新。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值