JavaWeb中点赞功能的实现及完整实例
2019-08-16 09:20:48来源:博客园 阅读 ()
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团队推荐的做法是用构造器来引入依赖,而不是直接使用@Autowired引入
@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<Great> 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<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 */;
特别说明:本文章的目的只是单纯向大家说明点赞这个功能的实现思路。为了保证逻辑尽量清晰和简单,因而并没有涉及到性能优化。示例代码中的锁机制能保证并发访问下的安全性,但会对系统并发性能产生一定的影响,但在一般系统中,由于大量用户同时对同一文章集中点赞的情况并不常见,因此性能损耗扔在可以接受的范围内。
如果大家在使用过程中确实有高并发的需要,那么可以考虑使用Redis这类缓存数据库来替代mysql。Redis是高性能的内存KV数据库,且是单线程运行的,因此性能和安全性问题都能得到完美的解决。
关于JPA中如何使用行级锁,可以参考这篇文章:https://blog.csdn.net/fengyuxue11011/article/details/47039765
原文链接:https://www.cnblogs.com/snake23/p/11096752.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:十五:建造者模式
- nacos~配置中心功能~springboot的支持 2020-06-10
- java8 stream的分组功能,具体时候是真的好用 2020-06-10
- Spring Enable***功能 2020-05-27
- 开发API动态接口的点赞功能(基于spring-boot开发) 2020-05-19
- CRM系统用户登录功能如何实现?Java高级项目实战必学 2020-05-16
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash