文章目录
1.需求分析
当用户进入视频详情页后会当前登录用户与该视频是否有点赞的关系,如果有则返回一个true的值,反之则返回一个false,当用户点击点赞按钮后,会调用点赞的接口,当用户再次点击之后则会调用取消点赞的接口
2.用户的点赞与取消点赞的接口编写
1.数据库表结构分析
关于点赞和取消点赞功能,一共需要关联到3张表的操作
相关联的表如下
表users_like_videos
CREATE TABLE `users_like_videos` (
`id` varchar(64) NOT NULL,
`user_id` varchar(64) NOT NULL COMMENT '用户',
`video_id` varchar(64) NOT NULL COMMENT '视频',
PRIMARY KEY (`id`),
UNIQUE KEY `user_video_rel` (`user_id`,`video_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户喜欢的/赞过的视频'
表users
CREATE TABLE `users` (
`id` varchar(64) NOT NULL,
`username` varchar(20) NOT NULL COMMENT '用户名',
`password` varchar(64) NOT NULL COMMENT '密码',
`face_image` varchar(255) DEFAULT NULL COMMENT '我的头像,如果没有默认给一张',
`nickname` varchar(20) NOT NULL COMMENT '昵称',
`fans_counts` int(11) DEFAULT '0' COMMENT '我的粉丝数量',
`follow_counts` int(11) DEFAULT '0' COMMENT '我关注的人总数',
`receive_like_counts` int(11) DEFAULT '0' COMMENT '我接受到的赞美/收藏 的数量',
PRIMARY KEY (`id`),
UNIQUE KEY `id` (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
表videos
CREATE TABLE `videos` (
`id` varchar(64) NOT NULL,
`user_id` varchar(64) NOT NULL COMMENT '发布者id',
`audio_id` varchar(64) DEFAULT NULL COMMENT '用户使用音频的信息',
`video_desc` varchar(128) DEFAULT NULL COMMENT '视频描述',
`video_path` varchar(255) NOT NULL COMMENT '视频存放的路径',
`video_seconds` float(6,2) DEFAULT NULL COMMENT '视频秒数',
`video_width` int(6) DEFAULT NULL COMMENT '视频宽度',
`video_height` int(6) DEFAULT NULL COMMENT '视频高度',
`cover_path` varchar(255) DEFAULT NULL COMMENT '视频封面图',
`like_counts` bigint(20) NOT NULL DEFAULT '0' COMMENT '喜欢/赞美的数量',
`status` int(1) NOT NULL COMMENT '视频状态:\r\n1、发布成功\r\n2、禁止播放,管理员操作',
`create_time` datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='视频信息表';
当用户对该视频点赞后,会将该用户的id和被点赞的视频的id添加到users_like_videos表,并且根据videoId,去对videos表中该视频的like_counts字段加1,根据该videoId查询到该视频发布者的userid,并将receive_like_counts字段进行+1操作,以上操作就完成了用户对该视频点赞的过程,取消点赞逻辑相同就是根据传入的userid和videoId查询users_like_videos表中的数据,并删除改条数据,并且将之前对应的字段都进行减一的操作即可。
3.点赞接口的实现
1.需求分析
需要前端传来3个参数分别为当前登陆者的id,视频的id,以及视频发布者的id,根据这三个参数对三个表进行相应的关联操作。
2.代码实现
dao层代码
public interface UsersLikeVideosDao extends JpaRepository<UsersLikeVideos,String> ,JpaSpecificationExecutor {
}
service层代码
/**
* 用户点赞功能
* @param id
* @param videoId
* @param videoCreateId
*/
@Override
@Transactional
public void like(String id, String videoId, String videoCreateId) {
//将用户与视频的点赞关系存入表中
UsersLikeVideos usersLikeVideos =new UsersLikeVideos();
usersLikeVideos.setId(IdUtils.getId());
usersLikeVideos.setUserId(id);
usersLikeVideos.setVideoId(videoId);
usersLikeVideosDao.save(usersLikeVideos);
//根据videoId查询视频,并将该视频的喜欢次数+1
Videos videos = videosDao.findOne(videoId);
videos.setLikeCounts(videos.getLikeCounts()+1);
videosDao.save(videos);
//根据视频发布者的id查询发布者信息,并将点赞数+1
Users users = usersDao.findOne(videoCreateId);
users.setReceiveLikeCounts(users.getReceiveLikeCounts()+1);
usersDao.save(users);
}
controller层代码
@ApiOperation(value = "用户点赞功能", notes = "用户点赞功能")
@PostMapping("/like")
public LexJSONResult like(String id,String videoId,String videoCreatedId){
userService.like(id,videoId,videoCreatedId);
return LexJSONResult.ok();
}
4.用户取消点赞接口的实现
1.需求分析
和点赞功能类似,我们还是需要前端传来3个参数,登陆者的id,视频id,视频发布者id,需要根据用户的id和视频的id这两个条件去数据库中精确查找出该条记录,并删除掉该记录,然后在将另外两个表对应的字段减去1即可,另外这些操作都要在一个事务中进行。
2.代码实现
service层代码实现
/**
* 通过用户id和视频id查询 UsersLikeVideos
* @param id
* @param videoId
* @return
*/
List<UsersLikeVideos> findByUserIdAndVideoId(final String id, final String videoId){
//下面的方法为jpa的多条件查询
return usersLikeVideosDao.findAll(new Specification<UsersLikeVideos>() {
@Override
public Predicate toPredicate(Root root, CriteriaQuery cq, CriteriaBuilder cb) {
//将usersLikeVideos实体类中的userid获取,类型为String,并将id的值赋值给他,作为第一个查询条件
Predicate p1 = cb.equal(root.get("userId").as(String.class), id);
//将usersLikeVideos实体类中的videoId获取,类型为String,并将videoId的值赋值给他,作为第二个查询条件
Predicate p2 = cb.equal(root.get("videoId").as(String.class), videoId);
//将这两个条件放到一个数组中
Predicate[] predicate = new Predicate[]{p1, p2};
//最后就根据数组中的这两个条件进行插叙,实现多条件查询
return cb.and(predicate);
}
});
}
/**
* 用户取消点赞
* @param id
* @param videoId
* @param videoCreateId
*/
@Override
@Transactional
public void unlike(final String id, final String videoId, String videoCreateId) {
//调用我们自定义的方法去数据库中查询该记录,并返回一个列表
List<UsersLikeVideos> list = findByUserIdAndVideoId(id, videoId);
//因为该列表中只有一个元素,所以将第一个元素取出来
UsersLikeVideos usersLikeVideos =list.get(0);
//通过该元素的id对该元素进行删除
usersLikeVideosDao.delete(usersLikeVideos.getId());
//通过视频的id查询视频,并将该视频的喜欢数量减一,并保存
Videos videos = videosDao.findOne(videoId);
videos.setLikeCounts(videos.getLikeCounts()-1);
videosDao.save(videos);
//根据发布者的id查询到发布者的用户信息,并将改用户的被点赞数减一,并保存回数据库
Users users = usersDao.findOne(videoCreateId);
users.setReceiveLikeCounts(users.getReceiveLikeCounts()-1);
usersDao.save(users);
}
controller层代码
@ApiOperation(value = "用户取消点赞功能", notes = "用户取消点赞功能")
@PostMapping("/unlike")
public LexJSONResult unlike(String id,String videoId,String videoCreatedId){
userService.unlike(id,videoId,videoCreatedId);
return LexJSONResult.ok();
}
5.查询用户与访问视频是否存在点赞关系的接口
1.需求分析
当用户点开一个视频后,要调用该接口,根据返回值在页面上显示,用户对视频是否点过赞,如果为true就在页面显示已点赞的图标,否则显示未点赞,我们需要前端将用户的id和视频的id传入,并根据这两个条件去数据库中查找,如果查找到记录,则说明用户已经点过赞,就返回一个true给前端,否则就返回false。
2.代码实现
service层代码
/**
* 通过用户id和视频id查询 UsersLikeVideos
* @param id
* @param videoId
* @return
*/
@Transactional
List<UsersLikeVideos> findByUserIdAndVideoId(final String id, final String videoId){
//下面的方法为jpa的多条件查询
return usersLikeVideosDao.findAll(new Specification<UsersLikeVideos>() {
@Override
public Predicate toPredicate(Root root, CriteriaQuery cq, CriteriaBuilder cb) {
//将usersLikeVideos实体类中的userid获取,类型为String,并将id的值赋值给他,作为第一个查询条件
Predicate p1 = cb.equal(root.get("userId").as(String.class), id);
//将usersLikeVideos实体类中的videoId获取,类型为String,并将videoId的值赋值给他,作为第二个查询条件
Predicate p2 = cb.equal(root.get("videoId").as(String.class), videoId);
//将这两个条件放到一个数组中
Predicate[] predicate = new Predicate[]{p1, p2};
//最后就根据数组中的这两个条件进行插叙,实现多条件查询
return cb.and(predicate);
}
});
}
/**
* 查询用户与视频的点赞关系
* @param id
* @param videoId
* @return
*/
@Override
public Boolean findUserIsLike(String id, String videoId) {
List<UsersLikeVideos> list = findByUserIdAndVideoId(id, videoId);
if (list.size()==0){
return false;
}else {
return true;
}
}
controller层代码会放在后面实现,因为判断用户是否给视频点赞会在页面加载的时候就查询,所以不单独写一个接口进行实现,后面会放在查询发布者信息的接口中进行实现