仿牛客论坛项目day6|redis

一、redis入门

1、NoSQL数据库。支持多种类型的数据结构,如字符串(String),哈希(Hashes),列表(Lists),集合(Sets),有序集合(Sorted sets)等。

2、数据存在内存里,所以读写性能很惊人。同时将内存中的数据以快照或日志的形式保存在硬盘上,以保证数据安全性。

3、典型应用场景:缓存、排行榜、计数器、社交网络、消息队列等。

二、spring整合redis

引入依赖

配置redis

访问redis

三、点赞

功能拆解:

点赞:支持对帖子、评论点赞;第一次点赞,第二次取消点赞

首页点赞数量:统计帖子的点赞数量

详情页点赞数量:统计点赞数量;显示点赞状态

具体实现:

1、数据层:在util里增加RedisKeyUtil类,里面设计点赞数据的存储方式。在redis里,点赞实体的存储格式是:

like:entity:entityType:entityId -> set(userId)

2、服务层:在service里增加LikeService类,里面定义:

点赞(like)的方法(将得到的userid插入value的set里)

查询点赞数量(findEntityLikeCount)的方法(value的set里有多少个userid)

查询某人有没有对某个帖子或详情点赞(findEntityLikeStatus)(查询某userid有没有在value的set里)

3、视图层:在controller里增加LikeController类,里面定义方法,来使用LikeService里的方法。

like:首先从hostholder里获取当前用户,然后调用LikeService里的like方法,调用LikeService里的findEntityLikeCount方法,调用LikeService里的findEntityLikeStatus方法,最后将获取的数量和状态使用map封装后传给页面

4、页面:帖子详情页面(discuss-detail)里修改点赞按钮(帖子、评论)

5、修改首页帖子点赞数量:在首页home controller里的现实帖子的方法里,增加查询帖子点赞数量(findEntityLikeCount)的代码。然后在index.html里修改对应代码。

6、修改首页帖子详情点赞数量:在帖子详情discussPostController里增加显示帖子点赞数量(findEntityLikeCount)和状态(findEntityLikeStatus)的逻辑(注意:这里没有登陆状态为0)。然后在discuss-detail.html里修改对应代码。

四、我收到的赞

功能拆解:

重构点赞功能:以用户为key,记录点赞数量;increment(key),decrement(key)

开发个人主页:以用户为key,查询点赞数量。

具体实现:

重构点赞功能:

1、数据层:在util的RedisKeyUtil类里面增加点赞实体的存储方式(以用户为key存储)。在redis里,某个用户的赞的存储格式是:

like:user:userId -> int

2、服务层:在service的LikeService类里面

重构点赞(like)方法。使得点赞后,以用户为key的value要增或减。

增加查询某个用户获得的赞的数量的方法。

3、视图层:在controller的LikeController类里还是调用LikeService里的方法。

4、页面:帖子详情页面(discuss-detail)里修改点赞按钮(帖子、评论)

开发个人主页:

1、控制层:在usercontroller里增加查看个人主页的方法

2、页面:主页index和个人主页profile

五、关注、取消关注

功能拆解:

需求:开发关注、取消关注功能;统计用户关注数、粉丝数。

关键:如果a关注了b,则a是b的粉丝(follower),b是a的目标(followee);关注的目标可以是用户、帖子、题目等,在实现时将这些目标抽象为实体。

具体实现:

1、数据层:在util的RedisKeyUtil类里设计关注数据的存储方式。在redis里有follower和followee两份数据。

follower:

// 某个实体拥有的粉丝
// follower:entityType:entityId -> zset(userId,now)

followee:

// 某个用户关注的实体
// followee:userId:entityType -> zset(entityId,now)以当前时间排序

2、服务层:在service里增加FollowService类,里面定义:

关注(follow)的方法:插入键值对

注意:在 Spring Data Redis 中,redisTemplate.execute(new SessionCallback()) 允许你在一个 Redis 会话(session)中执行多个命令,而不是为每个命令创建一个新的会话。这在多个命令需要在同一个事务中执行时是很有用的。通常,执行单个 Redis 命令不需要使用 SessionCallback。然而,当你有多个命令需要在同一个事务中执行时,使用 SessionCallback 可以提高效率和保证数据一致性。

取消关注的方法:删除键值对

查询关注的实体的数量:以user为key查询

查询实体的粉丝的数量:以实体为key查询

查询当前用户是否已关注该实体:以user为key,看看能不能查询到这个实体的某个属性

3、视图层:

在controller里增加FollowController类,里面定义如何使用FollowService里的方法。

follow:首先从hostholder里获取当前用户,然后调用FollowService里的follow方法,然后给页面返回消息

unfollow:同上

usercontrolle里,查询关注数量、粉丝数量、是否已关注

4、页面:

修改个人主页(profile)

六、关注列表、粉丝列表

功能拆解:

业务层:

查询某个用户关注的人和粉丝,并分页

表现层:

处理“查询关注的人”、“查询粉丝"请求

编写“查询关注的人”、“查询粉丝"模版

具体实现:

业务层:

FollowService类,里面定义:

查询某用户关注的人:

查询某用户的粉丝:

表现层:

FollowController类,里面定义:

查询某用户关注的人:

查询某用户的粉丝:

是否关注:

页面:profile、follower、followee

七、优化登陆模块

功能拆解:

使用redis存储验证码:验证码需要频繁的访问与刷新,对性能要求很高;验证码不需要永久保存,通常在很短时间后失效;分布式部署时,存在session共享的问题

使用redis存储登陆凭证:处理每次请求时,都需要查询用户的登录凭证,访问的频率很高

使用redis缓存用户信息:处理每次请求时,都要根据凭证查询用户信息,访问的频率非常高。

具体实现:

1、验证码:

数据层:RedisKeyUtil类里设计验证码数据的存储方式。

验证码只用redis存

// 获取验证码的时候,要将验证码和用户对应起来,但这时用户还没登陆
// 所以在用户访问登陆页面时给他发个凭证,将凭证存在cookie里,以凭证标识用户
// kaptcha:owner -> string

表现层:

logincontroller里重构getKaptcha方法:首先生成验证码的图片;然后生成cookie,在cookie里添加验证码的owner;然后将验证码的键值对(owner -> kaptchatext)插入数据库(设置过期时间为60秒

logincontroller里重构login方法:首先从cookie里取出owner并且检查是不是空;然后从redis里以owner为key取出验证码;最后检查数据库和页面输入的验证码是否一致。

2、登陆凭证

数据层:RedisKeyUtil类里设计凭证数据的存储方式。

凭证:只用redis存

// 登录的凭证
// 这里的key是loginticket的ticket值(随机string)
// 本来value应该是loginticket对象,但是存的时候会自动把对象序列化为字符串(里面不仅包括ticket值,还包括userid等信息
// ticket:ticket -> string

业务层:

存凭证:重构userService的login方法:账号密码都验证通过后,生成登陆凭证后,将键值对插入数据库,并将ticket值用map封装(在表现层,会将封装好的ticket用cookie传给服务器,服务器的请求会带着cookie,需要验证登陆凭证的时候就将ticket值从cookie里取,然后服务器会查redis,看登陆凭证是什么状态)

改凭证:重构userService的logout方法:根据ticket值获取loginticket对象;然后将它的status改为1(删除状态);最后再将键值对存回去。(在页面点击了logout,表现层就会调用logout方法,里面调用业务层的logout方法)

取凭证:重构userService的findLoginTicket方法:根据ticket值获取loginticket对象(在表现层,需要验证登陆凭证时,将ticket值从cookie里取,然后服务器会调用findLoginTicket,查redis,看登陆凭证是什么状态)

3、用户:

数据层:RedisKeyUtil类里设计用户数据的存储方式。用redis和mysql存

先定义三种方法:

// 1.优先从缓存中取值
// 2.取不到时初始化缓存数据(从mysql数据库取,然后存入redis)
// 3.数据变更时清除缓存数据

重构findUserById方法:1、优先从缓存中取值,2、取不到时初始化缓存数据

重构activation方法:如果激活成功,就3、数据变更时清除缓存数据

重构updateHeader方法:3、数据变更时清除缓存数据

你可能感兴趣的:(redis,mybatis,数据库)