点赞操作比较频繁,而且比较随意,所以数据变更很快,如果用mysql,会对mysql产生很大的压力,于是决定使用Redis,防止数据丢失,所以会定期将数据持久化同步到mysql中。
一、Redis 缓存设计及实现
1.1 Redis 安装及运行
linux中的gcc是由GNU推出的一款功能强大的、性能优越的多平台编译器。gcc编译器能将C、C++语言源程序和目标程序编译、连接成可执行文件。
Redis 安装请查阅上一篇教程。
1.2 Redis 与 SpringBoot 项目的整合
1.在 pom.xml 中引入依赖
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>va
2.编写 Redis 配置类
@SuppressWarnings("all")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
1.3 Redis 的数据结构类型
Redis 可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为String(字符串)、List(列表)、Set(集合)、Hash(散列)和 Zset(有序集合)。
下面来对这5种数据结构类型作简单的介绍:
前端点赞图标和手动模拟用户id的编写
模拟用户ID:<input type="text" id="userId"><br>
<span th:if="${isLike==false}">
<span class="glyphicon glyphicon-thumbs-up zan" style="font-size: 25px; cursor: pointer" ></span>
</span>
<span th:if="${isLike==true}">
<span class="glyphicon glyphicon-thumbs-up red zan" style="font-size: 25px; cursor: pointer" ></span>
</span>
<span id="count" th:text="${count}"></span>
</div>
<br>
<div id="show"></div>ml
js和css样式
<style>
.red{
color: red;
}
</style>
<script>
$(function () {
$(".zan").click(function () {
//1.获取用户id--判断是否为空
let userId=$("#userId").val();
if (userId.trim()==''){
alert("必须输入用户id")
return;
}
//2.获取纹章id
let newsId=$("#newsId").val();
alert(newsId);
//3.ajax请求处理
let data={userId:userId,newsId:newsId}
$.getJSON('/news/like',data,function (v) {
//返回值--1 出错了 如果返回 最新数据写到数量的位置
if (v==-1){
alert("点赞失败");
}else {
$("#count").text(v);
$(".zan").addClass("red");
}
})
})
$("#count").click(function () {
let newsId=$("#newsId").val();
$.getJSON('/news/queryLikeUser', {newsId:newsId},function (v) {
for (let id of v){
$("#show").append(id+" ,")
}
})
})
})
后端控制层Controller
/**
* 点赞
* */
@RequestMapping("/like")
@ResponseBody
public long like(Integer userId,Integer newsId){
return newsService.like(userId,newsId);
}
service接口
Long like(Integer userId, Integer newsId);
long queryCount(Integer newsId);
service实现类
public static final String REDIS_NEWS_ZAN_KEY="zan";
@Autowired
private RedisTemplate redisTemplate;
@Override
public Long like(Integer userId, Integer newsId) {
long count=-1;
//写入redis 用户id和新闻id redisTemplate.opsForSet().add(REDIS_NEWS_ZAN_KEY+newsId,userId);
//算出点赞的数量 count=redisTemplate.opsForSet().size(REDIS_NEWS_ZAN_KEY+newsId);
return count;
}
@Override
public long queryCount(Integer newsId) {
return redisTemplate.opsForSet().size(REDIS_NEWS_ZAN_KEY+newsId);
}
因为先不写入MySQL数据库,先不操作dao层,后续进行添加
然后添加展示点赞用户列表
controller
/**
* 点赞用户列表
* */
@RequestMapping("/queryLikeUser")
@ResponseBody
public Set queryLikeUser(Integer newsId){
return newsService.queryLikeUser(newsId);
}
service接口
boolean checkIsLike(int userId, Integer newsId);
Set queryLikeUser(Integer newsId);
service实现
@Override
public boolean checkIsLike(int userId, Integer newsId) {
return redisTemplate.opsForSet().isMember(REDIS_NEWS_ZAN_KEY+newsId,userId);
}
```@Override
public Set queryLikeUser(Integer newsId) {
return redisTemplate.opsForSet().members(REDIS_NEWS_ZAN_KEY+newsId);
}
以上就是简易版点赞功能的设计与实现,其余业务后续再更新。