java点赞功能实现_JavaWeb中点赞功能的实现及完整实例
实现原理
1、功能描述:一个用户对同一文章只能点赞一次,第二次就是取消赞
2、建立一个点赞表great,字段有文章ID(aid),点赞用户ID(uid)
3、当有用户进行点赞行为时,使用aid和uid搜索点赞表。
若有该记录,则表示用户已经点过赞,本次点击是取消点赞行为,故删除great表中的该条记录,同时将该文章的点赞数减1。
若无该记录,则表示用户是要点赞,故在great表中添加该记录,同时该文章的点赞数加1。
核心代码分析
核心控制器BaseController:
@Controller
public class BaseController {
private final GreatRepository greatRepository;
private final ArticleRepository articleRepository;
//Spring团队推荐的做法是用构造器来引入依赖,[email protected]
@Autowired
public BaseController(GreatRepository greatRepository,
ArticleRepository articleRepository) {
this.greatRepository = greatRepository;
this.articleRepository=articleRepository;
}
@RequestMapping({"/","/index"})
public String index(){
return "index";
}
//添加事务支持
@Transactional
@RequestMapping("/great")
public String great(@Param("aid") int aid, @Param("uid") int uid, Model model){
//查询是否有该用户对该文章的点赞记录
List list=greatRepository.findByAidAndUid(aid,uid);
if (list!=null && list.size()>0){
//如果找到了这条记录,则删除该记录,同时文章的点赞数减1
Great great=list.get(0);
//删除记录
greatRepository.delete(great.getId());
//文章点赞数减1,查询时使用Mysql行级锁解决并发覆盖问题
Article article=articleRepository.findByIdForUpdate(aid);
article.setGreatNum(article.getGreatNum()-1);
articleRepository.saveAndFlush(article);
}else {
//如果没有找到这条记录,则添加这条记录,同时文章点赞数加1
Great great=new Great();
great.setAid(aid);
great.setUid(uid);
//添加记录
greatRepository.saveAndFlush(great);
//文章点赞数加1,查询时使用Mysql行级锁解决并发覆盖问题
Article article=articleRepository.findByIdForUpdate(aid);
article.setGreatNum(article.getGreatNum()+1);
articleRepository.saveAndFlush(article);
}
model.addAttribute("details",articleRepository.findAll());
return "detail";
}
}
Aritcle实体的持久化仓库ArticleRepository
@Repository
public interface ArticleRepository extends JpaRepository{
@Lock(value = LockModeType.PESSIMISTIC_WRITE)
Article findByIdForUpdate(Integer id);
}
[email protected] [email protected]�锁,在事务中,该行级锁能解决对同一条记录的并发修改问题。
代码中已经附有详细注解
完整实例的相关信息
为了突出重点,项目前端较为简陋,功能已经通过测试。
项目采用的框架:
1、容器框架:SpringBoot
2、持久层框架:Spring Data JPA
3、渲染框架:Thymeleaf
4、版本控制:Git
5、依赖:Maven
6、数据库:Mysql
数据库建表文件Schema.sql:
DROP TABLE IF EXISTS `article`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `article` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`num` int(11) DEFAULT ‘0‘,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `article`
--
LOCK TABLES `article` WRITE;
/*!40000 ALTER TABLE `article` DISABLE KEYS */;
INSERT INTO `article` VALUES (1,1),(2,0);
/*!40000 ALTER TABLE `article` ENABLE KEYS */;
UNLOCK TABLES;
--
-- Table structure for table `great`
--
DROP TABLE IF EXISTS `great`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `great` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`aid` int(11) NOT NULL,
`uid` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `great`
--
LOCK TABLES `great` WRITE;
/*!40000 ALTER TABLE `great` DISABLE KEYS */;
INSERT INTO `great` VALUES (5,1,1);
/*!40000 ALTER TABLE `great` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET [email protected]_TIME_ZONE */;
特别说明:本文章的目的只是单纯向大家说明点赞这个功能的实现思路。为了保证逻辑尽量清晰和简单,因而并没有涉及到性能优化。示例代码中的锁机制能保证并发访问下的安全性,但会对系统并发性能产生一定的影响,但在一般系统中,由于大量用户同时对同一文章集中点赞的情况并不常见,因此性能损耗扔在可以接受的范围内。
如果大家在使用过程中确实有高并发的需要,那么可以考虑使用Redis这类缓存数据库来替代mysql。Redis是高性能的内存KV数据库,且是单线程运行的,因此性能和安全性问题都能得到完美的解决。
关于JPA中如何使用行级锁,可以参考这篇文章:https://blog.csdn.net/fengyuxue11011/article/details/47039765
原文:https://www.cnblogs.com/snake23/p/11096752.html
java点赞功能实现_JavaWeb中点赞功能的实现及完整实例相关推荐
- java 遍历request_java 遍历request中的所有表单数据的实例代码
java 遍历request中的所有表单数据的实例代码 实例如下: Enumeration rnames=request.getParameterNames(); for (Enumeration e ...
- java处理日期的类_Java实现的日期处理类完整实例
本文实例讲述了java实现的日期处理类.分享给大家供大家参考,具体如下: 开发中常常要使用日期,先小结如下,以备后用. import java.text.ParseException; import ...
- php中分页公式,php分页函数完整实例代码
本文分享一例php分页函数完整实例代码,使用此函数实现分页效果很不错.分享给大家供大家参考. 具体功能代码如下: /* * Created on 2011-07-28 * 使用方法: require_ ...
- JAVA打印web页面_JavaWeb实现打印功能
废话不多说了,直接给大家贴代码了,具体代码如下所示: function printsetup(){ // 打印页面设置 wb.execwb(8,1); } 整理的关于打印的内容 1.控制"纵 ...
- java web 获取根目录_javaweb中获取服务器端跟目录方法总结
先说一下java工程下目录的获取的几种方法,有用的看客可以看一下: 1.new File("relative path").getAbsolutePath(); 2.System. ...
- java mime上传_JavaWeb中实现文件上传的方式有哪些?
上回我们说了下文件下载的方式有哪些,这次我们从不同的环境下简单来说说文件上传的方式有哪些. 文件上传的方式Servlet2.5 方式 Servlet3.0 方式 SpringMVC 方式 案例实操 S ...
- java 99乘法表对齐_Java实现九九乘法表的完整实例(对齐版)
Java实现九九乘法表 思路: 1.看到九九乘法表就可以想到for循环,1-9可以写成一个for循环,自增1 2.那就是双重for循环,第一个for循环用于生成1-9的数值 3.第二个for循环的终止 ...
- JavaWeb中点赞功能的实现及完整实例
实现原理 1.功能描述:一个用户对同一文章只能点赞一次,第二次就是取消赞 2.建立一个点赞表great,字段有文章ID(aid),点赞用户ID(uid) 3.当有用户进行点赞行为时,使用aid和uid ...
- java点赞功能的实现,类似微信点赞,用户仅能点赞一次,基于redis进行操作
1.redis 基本知识 redis5种基本数据 学习参考链接 缓存点赞信息的数据结构是set集合,不太了解的同学请参考上面的链接 2.实现逻辑 传入点赞人id,被点赞的id,以及点赞的状态statu ...
最新文章
- SAP 差旅报销集成方案的实现
- 本人在学习PHP过程中的随笔心得
- Zynq-7000系统公共资源及特性
- rxjs里concatMap operators的用法
- 震撼世界的基建狂魔,中国制造的超级工程到底有多牛?
- 微博关注者数量在计算中的作用
- Cortex-M系列处理器指令集区别详解
- kudu :impala 和 kuduClient 的选择
- (android实战)创建查看试卷答案功能(类似于疯狂小鸟的选关)
- AndroidStudio_开发工具_调试功能---Android原生开发工作笔记75
- PyTorch——PyTorch也支持通过累加操作实现大的BatchSize的训练
- 把python37添加到环境变量配置_linux设置python环境变量 分类: python ...
- 应用Canary文件类型阻击勒索软件
- 启用zhparser插件时一直报Permission denied
- IntelliJ IDEA库存在却报错找不到的解决办法
- SAP Enable Now
- 记一次联想Y7000P安装黑apple系统地经历
- [QT学习]-调色板|选择文件
- BT源代码学习心得(五):统一网络服务接口--RawServer -- 转贴自 wolfenstein (NeverSayNever)
- 施工现场平面布置及其案例说明
热门文章
- MySQL 限制查询结果的记录数
- 用python画渐变的圆_使用numpy绘制圆形渐变
- 面向对象方法的优势简化软件开发的过程_软件开发技巧的途径
- 没有bug队——加贝——Python 45,46
- java md2_GitHub - edzjx/Md2Crypto
- python 生成字符串_Python字符串生成器,按照特定的顺序
- tcp的无延时发送_高并发架构的TCP知识介绍
- 数据结构--队列、双端队列实际举例详解(Python代码)
- 平行四边形的特殊性质
- 037_自动添加防火墙规则,开启某些服务或端口(适用于 RHEL7)