当前位置: 首页 > article >正文

微头条业务流程

微头条业务流程

    • 1.用户业务
      • 1.1 用户登录业务
      • 1.2 获取用户信息服务
      • 1.3 用户注册业务
    • 2. 微头条页面业务
      • 2.1 导航栏回显
      • 2.2 显示分页查询首页头条信息(重点!!)
        • 动态SQL元素解析
        • MyBatis Plus分页插件
        • 分页逻辑
      • 2.3 根据id查询头条详情(重点!!)
        • `LEFT JOIN`操作:
        • 乐观锁机制的作用
      • 3.文章业务
        • 3.1发布文章
        • 3.2 修改文章(考虑并发)
        • 注意事项
        • 3.3 删除文章
        • 注意事项
        • 3.4显示文章回显(容易被忽略)

1.用户业务

1.1 用户登录业务

思考:

  • 用户未注册时登录,数据库没有该用户信息,导致用户名查询失败,返回一个失败的结果。并且提醒用户去注册!
  • 用户注册了,数据库有用户信息,查询用户信息过关,下一步进行密码验证,验证的时候,注意密码的格式,因为用户输入的密码是明文,而数据库存储的是Md5加密后的密文,在进行密码验证时,需要将明文密码加密后,进行比较。
  • 成功,将该用户Uid生成一个token返回给前端,用于用户后续访问业务时,不需要重复进行登陆验证。
  • 失败提醒用户密码错误!重搞。

功能概述
此方法用于处理用户登录请求,主要步骤包括:

  1. 根据提供的用户名查询数据库,获取用户信息。
  2. 验证用户提供的密码是否与数据库中存储的MD5加密后的密码匹配。
  3. 如果验证成功,生成JWT Token并返回给调用在这里插入图片描述

流程:

  • 数据库查询
    • 使用LambdaQueryWrapper构建构建一个查询Sql,通过eq方法指定username字段与传入的用户名相等。
    • 调用userMapper.selectOne()执行SQL查询,获取用户记录。
  • 密码验证
    • 检查数据库返回的用户对象是否为空,若为空则返回USERNAME_ERROR错误码。
    • 若用户对象非空,比较用户提供的明文密码经MD5加密后的值与数据库中存储的密码是否一致。
  • Token生成与返回
    • 密码验证成功后,使用jwtHelper.createToken()方法,传入用户UID生成JWT Token。
    • 将生成的Token封装至Map中,并通过Result.ok()方法构建成功响应,返回给前端。

注意!

  • 密码处理:用户输入的密码应被视为明文,在与数据库存储的密码比较前需先进行MD5加密
  • Token格式:返回前端之前,Token格式需要和前端比对是否一致。

1.2 获取用户信息服务

思考:

  • 用户登录后,想要查看用户信息,需要通过数据库查询该用户的Uid后返回数据的。所以,这个Uid就是前端携带的token,当你访问信息时,必须携带token,此时想要查看业务,就要验证!
  • 第一关,验证token令牌有效期,如果没问题,通过token获取Uid
  • 第二关,查询(验证)该Uid是否存在于数据库中,存在进行下一步
  • 第三关,返回数据时,需要注意,这个数据是前端需要的,所以返回数据的格式也是前端命名好的,保持格式一致!

功能描述

客户端发送请求,提交token请求头,后端根据token请求头获取登录用户的详细信息并响应给客户端进行存储

  1. 验证token是否在有效期内。
  2. token中解析出用户ID。
  3. 根据用户ID查询数据库,获取用户信息。
  4. 返回用户信息(排除密码)。
    在这里插入图片描述
    在这里插入图片描述

流程:

  • Token有效性检查
    • 使用jwtHelper.isExpiration(token)方法检查token是否已过期。
    • token过期,则直接返回NOTLOGIN错误码,表示用户未登录状态。
  • 解析用户UID
    • 通过jwtHelper.getUserId(token)方法从token中提取用户UID。
  • 数据库查询
    • 使用userMapper.selectById(userId)方法根据用户ID查询用户信息。
  • 构建响应结果
    • 若查询到的用户信息非空,清除用户对象的密码字段,避免泄露敏感信息。
    • 注意! 将用户信息封装至Map时,看清楚!存入的键值对是否是前端需要的内容!通过Result.ok()方法构建成功响应,返回给前端。

1.3 用户注册业务

思考:

  • 注册用户,首先需要查看用户名是否被占用,其次需要对密码进行Md5加密,最后,将用户信息添加到数据库中,返回给前端一个200即可
    在这里插入图片描述

流程:

  • 用户名唯一性校验
    • 使用LambdaQueryWrapper构建查询条件,通过eq方法指定username字段与待注册的用户名相等。
    • 调用userMapper.selectCount()执行SQL查询,统计符合条件的用户数量。
    • 若查询结果大于0,表明用户名已被占用,返回USERNAME_USED错误码。
  • 密码加密
    • 在存储用户信息前,使用MD5Util.encrypt()方法对用户密码进行MD5加密处理,增强账户安全性。
  • 数据库插入操作
    • 调用userMapper.insert()方法将处理后的用户信息插入数据库。
    • 打印插入操作影响的行数,用于调试或监控。
  • 响应构建
    • 插入操作完成后,构建成功响应,返回给前端。

2. 微头条页面业务

2.1 导航栏回显

在这里插入图片描述

进入新闻首页,查询所有分类并动态展示新闻类别栏位

思考:直接查询分类的所有信息,返回给前端就行,注意返回数据的格式!

方法1:
在这里插入图片描述
方法2:
在这里插入图片描述

2.2 显示分页查询首页头条信息(重点!!)

在这里插入图片描述

客户端:向服务端发送查询关键字,新闻类别,页码数,页大小
服务端:根据条件搜索分页信息,返回:含页码数,页大小,总页数,总记录数,当前页数据等信息,并根据时间降序,浏览量降序排序


在这里插入图片描述
在这里插入图片描述

思考分析:

  • 前端需要返回一大堆信息,看json数据后,发现
    • pageData是根据关键字查询的信息
    • pageInfo显示的是页面的信息
  • 分析pageData,他是一个[]包围着很多个{},所以是列表嵌套着Map集合,所以返回前端数据的是一个List《map》对象
  • 根据前端请求参数,获取关键字,通过关键字进行查询,注意!查询SQL需要自定义!
  • 同时,我mapper调用完selectMyPage方法后返回的结果是一个IPage类型的数据,然后通过实现类Page调用这些数据存进一个List《map》的列表中。
  • 此时PageData的工作完毕,下面是pageInfo的业务
    • PageInfo里包含两部分:PageData和页面的数据,页面数据直接可以get到,PageInfo是一个Map所以直接put就行了。

在这里插入图片描述

动态SQL元素解析
  • TIMESTAMPDIFF函数:MySQL特有的函数,用于计算两个日期或时间之间的差值。在这个查询中,它被用来计算每条记录的create_time与当前时间NOW()之间的时间差,单位是小时。
  • <if>标签:MyBatis的动态SQL标签之一,用于根据条件决定是否包含某些SQL片段。
    • 第一个<if>标签检查portalVo.keyWords是否非空且长度大于0,如果条件成立,则在SQL中添加基于title字段的模糊搜索条件,搜索包含portalVo.keyWords的记录。
    • 第二个<if>标签检查portalVo.type是否不等于0,如果条件成立,则在SQL中添加基于type字段的精确匹配条件。

SQL执行逻辑
selectMyPage方法被调用时,MyBatis Plus会做以下几件事:

  1. 根据page对象的pageNumpageSize属性,自动修改SQL语句以包含LIMIT子句,从而实现分页查询。
  2. 根据portalVo对象的属性动态生成SQL语句的WHERE子句。
  3. 执行修改后的SQL语句,获取数据。
  4. 将查询结果填充到IPage对象中,包括当前页的数据记录和分页信息。
    在这里插入图片描述
MyBatis Plus分页插件

IPage接口与Page类:

  • IPage<T>是MyBatis Plus提供的分页接口,它扩展了PageInfo<T>,包含了分页查询所需的主要信息,如当前页码、每页数量、总页数、总记录数等。
  • Page<T>IPage<T>的一个实现类,用于创建分页查询的实例,可以设置当前页码和每页记录数。
分页逻辑

在MyBatis Plus中,IPage接口和它的实现类Page被设计用于处理分页查询。当你创建一个Page实例并调用Mapper中的分页查询方法时,MyBatis Plus会自动在底层执行分页逻辑,包括SQL语句的修改以适应分页需求。

IPage<Map> selectMyPage(IPage page,@Param("portalVo") PortalVo portalVo);

headlineMapper.selectMyPage(page, portalVo);这行代码实际上是在调用Mapper接口中的selectMyPage方法,该方法接受两个参数:一个IPage<Map>类型的page对象和一个portalVo对象,后者包含了分页查询所需的额外参数,如关键词和分类类型。

在Mapper的XML文件中,<select id="selectMyPage">定义了自定义的SQL语句,其中使用了TIMESTAMPDIFF函数来计算时间差,并且通过<if>标签实现了动态SQL,根据portalVo对象的属性决定是否添加额外的过滤条件。

因此!!当你调用page.getRecords()时,你实际上是在访问IPage对象中已经填充的数据记录,这些记录是通过执行自定义SQL语句并应用分页逻辑后得到的。getRecords()方法返回的是一个List<Map>,其中每一项Map代表了一条查询结果,键对应于SQL语句中选择的列名。

业务流程:

  • 分页查询
    • 创建IPage<Map>类型的page对象,设置当前页码和每页显示的记录数。
    • 调用headlineMapper.selectMyPage(page, portalVo)执行自定义SQL分页查询,填充page对象。
  • 数据提取与封装
    • page对象中提取查询结果,即当前页的数据记录,转换为List<Map>类型。
    • 提取分页信息,包括当前页码、页大小、页总数、总记录数,封装至Map对象中。
  • 响应构建
    • 将分页数据和信息封装至Map对象中,构建为pageInfo
    • 最终通过Result.ok()方法构建成功响应,返回给前端。

2.3 根据id查询头条详情(重点!!)

在这里插入图片描述

  • 用户点击"查看全文"时,向服务端发送新闻id
  • 后端根据新闻id查询完整新闻文章信息并返回
  • 后端要同时让新闻的浏览量+1

在这里插入图片描述

思考分析:

  • 由于每一篇文章都有对应的Hid,所以查看文章是通过Hid查询的,前端点击查看全文后,会给后端传入一个hid,这个hid就是当前用户点击的新闻id,直接查询返回一个Map类型的Headline对象即可。
  • 注意!后端要同时让新闻的浏览量+1!要考虑并发问题!如果没有适当的并发控制,可能会导致阅读量更新不准确。
  • 并且数据同步是需要更新的,所以还有一步,new一个Headline对象,把当前查询结果的值传入Headline中,在通过Hid进行更新。因为乐观锁机制的缘故,需要把Version字段传入Headline中,这样,并发才能解决!

在这里插入图片描述

LEFT JOIN操作:
  • 首先与news_type表左连接,连接条件是news_headlinetype字段等于news_typetid字段。
  • 然后与news_user表左连接,连接条件是news_headlinepublisher字段等于news_useruid字段。
  • 左连接保证了即使关联表中没有匹配记录,主表的记录也会被返回,同时关联表的字段会被填充为NULL。
    在这里插入图片描述
    在这里插入图片描述
乐观锁机制的作用
  1. 检测并发修改: 当多个用户几乎同时尝试更新同一条记录时,乐观锁机制可以检测到是否有其他事务在当前事务开始后修改了这条记录。这是通过检查版本号(version字段)是否与上次读取时相同来实现的。
  2. 防止数据冲突: 在上述代码中,当一个用户读取头条详情并准备更新阅读量时,如果在此期间另一个用户也修改了同一条记录,乐观锁机制将阻止第一个用户的更新操作,因为第一个用户的版本号不再匹配数据库中的最新版本号。
  3. 维护数据一致性: 通过在更新操作中包含版本号的检查,乐观锁确保只有当数据未被其他事务修改时,更新才会成功。这样就避免了可能的数据不一致问题,提高了系统的数据完整性和可靠性。

在代码中,乐观锁的实现是通过以下步骤完成的:

  1. 读取头条详情: 使用headlineMapper.queryDetailMap(hid)查询头条详情,其中包括了版本号version
  2. 更新阅读量: 创建Headline对象,设置其hidversionpageViews字段。这里的version字段就是用于乐观锁检查的版本号。
  3. 尝试更新数据: 调用headlineMapper.updateById(headline)更新头条记录。在MyBatis Plus中,updateById方法会自动生成包含版本号检查的SQL语句,以确保版本号未变时才执行更新。
  4. 处理更新结果: 如果更新成功,说明没有其他事务在此期间修改了数据;如果更新失败(通常是由于版本号不匹配),则需要处理这种冲突情况,例如抛出异常或提示用户数据已变更。

业务流程:

  1. 用户行为触发:
    • 用户在前端界面点击某头条新闻的“查看全文”。
  2. 后端处理请求:
    • 后端接收请求,从中提取头条的hid(头条ID)。
  3. 查询头条详情:
    • 调用headlineMapper.queryDetailMap(hid),执行SQL查询,获取头条的详细信息,包括当前阅读量。
  4. 阅读量更新:
    • 根据查询结果,创建Headline对象,将阅读量加1,并尝试更新数据库记录,利用版本号检查处理并发问题。
  5. 响应前端:
    • 成功更新后,将头条详情作为响应返回给前端,展示头条全文内容。

3.文章业务

3.1发布文章

在这里插入图片描述

  • 用户在客户端输入发布的新闻信息完毕后
  • 发布前先请求后端的登录校验接口验证登录
  • 登录通过则提交新闻信息
  • 后端将新闻信息存入数据库

思考:

  • 发布文章是在用户登录完成后操作业务,所以发布前需要验证用户登录的token,如果验证成功,通过token生成用户ID存入数据库。
  • 注意!提交文章意味着修改文章的创建和更新时间,所以时间也要存入数据库。同时,访问量也需要初始化0,新发表的文章是没有访问量的!
    在这里插入图片描述
3.2 修改文章(考虑并发)

思考:

  • 重点!更新数据首先考虑并发,
    • 通过文章的Hid查询该文章的Version,将Version存入headline中(这里的headline是前端传过来的)
    • 注意!修改文章同时修改了文章时间!把当前时间传入即可
    • mapper进行update即可。(这里用的是updateById,如果传入的是一个对象,MybatisPlus会自动识别该对象的id字段!)

在这里插入图片描述

注意事项
  • 乐观锁机制:
    • 使用版本号进行乐观锁控制,防止并发修改冲突,确保数据一致性。
  • 时间戳更新:
    • 每次更新头条信息时,都应更新updateTime字段,以记录最近一次修改的时间。
  • 完整性检查:
    • 在更新前,确保headline对象的所有必填属性都已正确填充,避免因属性缺失导致的更新失败。
3.3 删除文章

思考:

  • 通过前端单击删除按钮后,传入hid字段,后端拿到后直接删即可。

在这里插入图片描述

注意事项
  • 别全删了= =
3.4显示文章回显(容易被忽略)

在这里插入图片描述

  • 前端先调用登录校验接口,校验登录是否过期
  • 登录校验通过后 ,则根据新闻id查询新闻的完整信息并响应给前端

在这里插入图片描述

思考:

  • 已知前端完成登录校验,只需要通过前端给的Hid进行查询,返回Json数据中,键是headline!值就是headline对象!
    在这里插入图片描述

http://www.kler.cn/a/513004.html

相关文章:

  • RV1126+FFMPEG推流项目(8)AENC音频编码模块
  • 三格电子——MODBUS TCP 转 CANOpen 协议网关
  • vulnhub靶场【IA系列】之Tornado
  • 如何在龙蜥 OS(AliOS)上安装极狐GitLab?
  • 简述mysql 主从复制原理及其工作过程,配置一主两从并验证。
  • Jenkins-pipeline Jenkinsfile说明
  • 实战演示:利用ChatGPT高效撰写论文
  • 【C/C++实现】直接插入排序(图例--超详细解析,小白一看就会!)
  • 【单片机通过蜂鸣器模拟警号 救护车 警车 等声音 】
  • node.js+npm的环境配置以及添加镜像(保姆级教程)
  • [LeetCode] 哈希表 I — 242#有效的字母异位词 | 349#两个数组的交集 | 202#快乐数 | 1#两数之和
  • 【Rust自学】13.10. 性能对比:循环 vs. 迭代器
  • Excel 技巧12 - 如何在Excel中输入对号叉号(★),字体Wingdings2
  • 鸿蒙Harmony json转对象(1)
  • Golang 生态学习
  • Git原理与应用(三)【远程操作 | 理解分布式 | 推送拉取远程仓库 | 标签管理】
  • 网络协议如何确保数据的安全传输?
  • 虚幻商城 Fab 免费资产自动化入库
  • bcache的基本操作
  • PHP装修行业小程序
  • [Collection与数据结构] PriorityQueue与堆
  • 数据结构-LinkedList和链表
  • 《贪心算法:原理剖析与典型例题精解》
  • 2024年AI大模型技术年度总结与应用实战:创新与突破并进
  • Spring Boot Starter探秘:全面了解 spring-boot-starter-web
  • 小程序获取微信运动步数