实现原理

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团队推荐的做法是用构造器来引入依赖,而不是直接使用@Autowired引入@Autowiredpublic 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<Great> list=greatRepository.findByAidAndUid(aid,uid);if (list!=null && list.size()>0){//如果找到了这条记录,则删除该记录,同时文章的点赞数减1Great great=list.get(0);//删除记录greatRepository.delete(great.getId());//文章点赞数减1,查询时使用Mysql行级锁解决并发覆盖问题Article article=articleRepository.findByIdForUpdate(aid);article.setGreatNum(article.getGreatNum()-1);articleRepository.saveAndFlush(article);}else {//如果没有找到这条记录,则添加这条记录,同时文章点赞数加1Great 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<Article,Integer>{@Lock(value = LockModeType.PESSIMISTIC_WRITE)Article findByIdForUpdate(Integer id);
}

注意其中使用了@Lock注解以及 LockModeType.PESSIMISTIC_WRITE来让JPA使用数据库层的行级锁,在事务中,该行级锁能解决对同一条记录的并发修改问题。

代码中已经附有详细注解

完整实例的相关信息

为了突出重点,项目前端较为简陋,功能已经通过测试。
项目采用的框架:
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 TIME_ZONE=@OLD_TIME_ZONE */;

项目已经上传到Github,欢迎大家克隆学习。
项目地址:https://github.com/Dodozhou/greate_test
(若没有Github账户的同学,可以在评论区留言你的邮箱,我会将zip压缩包发到你的邮箱)(喜欢的请别忘了点赞哟,这是对我莫大的鼓励:-D)

特别说明:本文章的目的只是单纯向大家说明点赞这个功能的实现思路。为了保证逻辑尽量清晰和简单,因而并没有涉及到性能优化。示例代码中的锁机制能保证并发访问下的安全性,但会对系统并发性能产生一定的影响,但在一般系统中,由于大量用户同时对同一文章集中点赞的情况并不常见,因此性能损耗扔在可以接受的范围内。

如果大家在使用过程中确实有高并发的需要,那么可以考虑使用Redis这类缓存数据库来替代mysql。Redis是高性能的内存KV数据库,且是单线程运行的,因此性能和安全性问题都能得到完美的解决。

关于JPA中如何使用行级锁,可以参考这篇文章:https://blog.csdn.net/fengyuxue11011/article/details/47039765

JavaWeb中点赞功能的实现及完整实例相关推荐

  1. java点赞功能实现_JavaWeb中点赞功能的实现及完整实例

    实现原理 1.功能描述:一个用户对同一文章只能点赞一次,第二次就是取消赞 2.建立一个点赞表great,字段有文章ID(aid),点赞用户ID(uid) 3.当有用户进行点赞行为时,使用aid和uid ...

  2. php中分页公式,php分页函数完整实例代码

    本文分享一例php分页函数完整实例代码,使用此函数实现分页效果很不错.分享给大家供大家参考. 具体功能代码如下: /* * Created on 2011-07-28 * 使用方法: require_ ...

  3. php ajax 点赞实例下载,php+mysql结合Ajax实现点赞功能完整实例

    时间:2015-03-03来源:www.aspku.com 作者:源码库 文章热度: ℃ 这篇文章主要介绍了php+mysql结合Ajax实现点赞功能,以一个完整实例形式详细分析了实现点赞功能中涉及的 ...

  4. ajax mysql点赞_php+mysql结合Ajax实现点赞功能完整实例

    php+mysql结合Ajax实现点赞功能完整实例 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 // ...

  5. 微信小程序动态点赞php,在微信小程序中如何实现点赞功能

    这篇文章主要介绍了微信小程序基于本地缓存实现点赞功能的方法,涉及微信小程序界面布局.事件响应及缓存操作等相关实现技巧,需要的朋友可以参考下 本文实例讲述了微信小程序基于本地缓存实现点赞功能的方法.分享 ...

  6. php中引入jquery文件_WP模板开发中,怎样给wordpress网站的文章,添加点赞功能?...

    我们在网上浏览某些网站的文章时,在文章的结尾处,都会有一个点赞的按钮,如果觉得文章内容非常不错,就可以点击这个"点赞"按钮,给这篇文章进行点赞一下.在wordpress网站的模板主 ...

  7. php微信小程序如何无限点赞,小程序中点赞和收藏功能的实现代码

    小程序中的点赞功能和收藏功能是必不可少的,那么该如何实现点赞和收藏两个功能呢?本篇文章将给大家分享小程序中的点赞功能和收藏功能的代码实现. 收藏功能:focusFavoriteTab: functio ...

  8. 第5章第21节:实现Widget对应的完整应用中的功能 [SwiftUI快速入门到实战]

    本节继续天气小组件的制作,您将实现Widget对应的完整应用中的功能,用户可以在应用中挑选目标城市,再由Widget显示该城市的天气信息. 由于要在应用和Widget之间传递数据,所以需要将应用和Wi ...

  9. android listview高级,Android中Listview点赞功能的实现

    最近这段时间一直在看Android,利用Listview去实现点赞功能,下面给大家介绍下基本思路. 基本思路: 进入界面–>获取数据–> 在Listview中显示–> 通过map集合 ...

最新文章

  1. ASP.NET AJAX Debugging and Tracing
  2. 【牛客 - 181C】序列(前缀和,二分,可用set维护)(有坑)
  3. pyinstaller打包的文件运行失败:numpy.core.multiarray failed to import
  4. mysql log stats_MySQL慢查询之pt-query-digest分析慢查询日志
  5. 安卓短信功能全解:调用系统短信功能发送短信、彩信,使用SmsManager发送短信,并监听发送短信的投递情况,使用广播接收器监听接收的短信。
  6. mysql出错代码表
  7. nice值 linux进程,Linux进程优先级和nice值
  8. Lingo软件入门【数学建模】
  9. JVM性能优化之JVM调优
  10. Jeecg框架中的一些常用属性(query,dictionary,funname,formatterjs,replace)
  11. 2022-2027年中国智能硬件行业市场深度分析及发展战略规划报告
  12. 联想台式计算机 不启动u盘,联想电脑不能u盘启动怎么办
  13. linux虚拟磁盘服务,hintsoft Linux iscsi虚拟磁盘完全教程及优化攻略
  14. dns服务器修改失败,dns错误重新设置方法
  15. 浙江卫视的万峰纯粹一烂人
  16. pta基础编程题目集 7-1 厘米换算英尺英寸
  17. Singularity 快速上手, 带你飞
  18. 斐讯n1盒子装网易音乐命令版
  19. 北京大额股票配资 北京股票金融配资
  20. map操作 java,Java中Map基本操作

热门文章

  1. Python绘图笔记
  2. [总结]视音频编解码技术零基础学习方法
  3. Jscex没有xxxAsync().stop()怎么办?
  4. 计算机专业毕设太难做不出来怎么办?
  5. word批量导入试题,一键组卷,单机软件题库管家迎来1.2版本
  6. 2020年C/C++精选面试题及答案(三)
  7. Windows自带虚拟化服务工具Hyper-V学习了解和实操
  8. 学习方法之——费曼技巧学习
  9. bookmarks_2021_9_28
  10. html2day(合并单元格,有序、无序列表,input、select、textarea表单)