package org.example.userlike;
public enum LikedStatusEum {
LIKE(1,"点赞"),
UNLIKE(0,"取消点赞");
private final Integer status;
private final String statusName;
LikedStatusEum(Integer status, String statusName) {
this.status = status;
this.statusName = statusName;
}
public Integer getStatus() {
return status;
}
public String getStatusName() {
return statusName;
}
}
package org.example.userlike;
public class RedisKeyUtils {
/**
* 保存用户点赞数据的key
*
* @date 2021/9/26 14:44
*/
public static final String MAP_KEY_USER_LIKED = "MAP_USER_LIKED";
/**
* 保存用户被点赞数量的key
*
* @date 2021/9/26 14:44
*/
public static final String MAP_KEY_USER_LIKED_COUNT = "MAP_USER_LIKED_COUNT";
/**
* 拼接被点赞的用户id和点赞的人的id作为key。格式 222222::333333
*
* @param likedUserId 被点赞的人id
* @param likedPostId 点赞的人的id
* @return
*/
public static String getLikedKey(String likedUserId, String likedPostId) {
return likedUserId +
"::" +
likedPostId;
}
}
package org.example.userlike;
import lombok.Data;
import java.io.Serializable;
@Data
public class UserLikCountDTO implements Serializable {
private String infoId;
private Integer value;
public UserLikCountDTO(String infoId, Integer value) {
this.infoId = infoId;
this.value = value;
}
}
package org.example.userlike;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserLikesDto {
private String infoId;
private String likeUserId;
private Integer status;
}
package org.example.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.data.redis.core.StringRedisTemplate;
@Configuration
@EnableCaching
public class RedisConfig {
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Bean
public KeyGenerator keyGenerator() {
return (target, method, params) -> {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
};
}
// @Bean
// public CacheManager cacheManager(RedisTemplate redisTemplate) {
// return new RedisCacheManager(redisTemplate);
// }
@Bean
public StringRedisSerializer stringRedisSerializer() {
return new StringRedisSerializer();
}
@Bean("redisTemplate")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer<Object> 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);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.setKeySerializer(stringRedisSerializer());
template.setHashKeySerializer(stringRedisSerializer());
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}
package org.example.business;
import org.example.userlike.UserLikCountDTO;
import org.example.userlike.UserLikesDto;
import java.util.List;
public interface UserLikeService {
Object likeStatus(String infoId, String likeUserId);
List<UserLikesDto> getLikedDataFromRedis();
List<UserLikCountDTO> getLikedCountFromRedis();
}
package org.example.business.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.example.business.UserLikeService;
import org.example.entity.UserLikesEntity;
import org.example.mapper.UserLikesDao;
import org.example.userlike.LikedStatusEum;
import org.example.userlike.RedisKeyUtils;
import org.example.userlike.UserLikCountDTO;
import org.example.userlike.UserLikesDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class UserLikeServiceImpl implements UserLikeService {
private final RedisTemplate redisTemplate;
private final UserLikesDao userLikesDao;
public Object likeStatus(String infoId, String likeUserId) {
if (redisTemplate.opsForHash().hasKey(RedisKeyUtils.MAP_KEY_USER_LIKED, RedisKeyUtils.getLikedKey(infoId, likeUserId))) {
String o = redisTemplate.opsForHash().get(RedisKeyUtils.MAP_KEY_USER_LIKED, RedisKeyUtils.getLikedKey(infoId, likeUserId)).toString();
if ("1".equals(o)) {
unLikes(infoId, likeUserId);
return LikedStatusEum.UNLIKE;
}
if ("0".equals(o)) {
likes(infoId, likeUserId);
return LikedStatusEum.LIKE;
}
}
UserLikesEntity userLikes = userLikesDao.selectOne(Wrappers.<UserLikesEntity>lambdaQuery().eq(UserLikesEntity::getInfoId,infoId).eq(UserLikesEntity::getLikeUserId,likeUserId));
if (userLikes == null) {
UserLikesEntity userLikes1 = new UserLikesEntity();
userLikes1.setInfoId(infoId);
userLikes1.setLikeUserId(likeUserId);
userLikesDao.insert(userLikes1);
likes(infoId, likeUserId);
return LikedStatusEum.LIKE;
}
if (userLikes.getStatus() == 1) {
unLikes(infoId, likeUserId);
return LikedStatusEum.UNLIKE;
}
if (userLikes.getStatus() == 0) {
likes(infoId, likeUserId);
return LikedStatusEum.LIKE;
}
return "";
}
public void likes(String infoId, String likeUserId) {
String likedKey = RedisKeyUtils.getLikedKey(infoId, likeUserId);
redisTemplate.opsForHash().increment(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, infoId, 1);
redisTemplate.opsForHash().put(RedisKeyUtils.MAP_KEY_USER_LIKED, likedKey, LikedStatusEum.LIKE.getStatus());
}
public void unLikes(String infoId, String likeUserId) {
String likedKey = RedisKeyUtils.getLikedKey(infoId, likeUserId);
redisTemplate.opsForHash().increment(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, infoId, -1);
redisTemplate.opsForHash().delete(RedisKeyUtils.MAP_KEY_USER_LIKED, likedKey);
}
public List<UserLikesDto> getLikedDataFromRedis() {
Cursor<Map.Entry<Object, Object>> scan = redisTemplate.opsForHash().scan(RedisKeyUtils.MAP_KEY_USER_LIKED, ScanOptions.NONE);
List<UserLikesDto> list = new ArrayList<>();
while (scan.hasNext()) {
Map.Entry<Object, Object> entry = scan.next();
String key = (String) entry.getKey();
String[] split = key.split("::");
String infoId = split[0];
String likeUserId = split[1];
Integer value = (Integer) entry.getValue();
//组装成 UserLike 对象
UserLikesDto userLikeDetail = new UserLikesDto(infoId, likeUserId, value);
list.add(userLikeDetail);
//存到 list 后从 Redis 中删除
// redisTemplate.opsForHash().delete(RedisKeyUtils.MAP_KEY_USER_LIKED, key);
}
return list;
}
public List<UserLikCountDTO> getLikedCountFromRedis() {
Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, ScanOptions.NONE);
List<UserLikCountDTO> list = new ArrayList<>();
while (cursor.hasNext()) {
Map.Entry<Object, Object> map = cursor.next();
String key = (String) map.getKey();
Integer value = (Integer) map.getValue();
UserLikCountDTO userLikCountDTO = new UserLikCountDTO(key, value);
list.add(userLikCountDTO);
// redisTemplate.opsForHash().delete(RedisKeyUtils.MAP_KEY_USER_LIKED_COUNT, key);
}
return list;
}
}
@GetMapping("/userLinke")
public Object userLinke(){
return userLikeService.likeStatus("1","2");
}
@GetMapping("/getLikedDataFromRedis")
public List<UserLikesDto> getLikedDataFromRedis(){
return userLikeService.getLikedDataFromRedis();
}
@GetMapping("/getLikedCountFromRedis")
public List<UserLikCountDTO> getLikedCountFromRedis(){
return userLikeService.getLikedCountFromRedis();
}
package org.example.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
@Data
@TableName("user_likes")
public class UserLikesEntity {
@TableId("id")
private String id;
@TableField("info_id")
private String infoId;
@TableField("create_time")
private Date createTime;
@TableField("like_user_id")
private String likeUserId;
@TableField("update_time")
private Date updateTime;
@TableField("status")
private Integer status;
}
package org.example.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.util.Date;
@Data
@TableName("video")
public class VideoEntity {
@TableId("likes_number")
private String id;
/**
* 点赞数
*/
@TableField("likes_number")
private Integer likesNumber;
/**
* 评论数
*/
@TableField("comments_number")
private Integer commentsNumber;
/**
* 分享数
*/
@TableField("share_number")
private Integer shareNumber;
@TableField("create_time")
private Date createTime;
@TableField("create_user")
private String createUser;
@TableField("update_time")
private Date updateTime;
@TableField("update_user")
private String updateUser;
}
server:
port: 8282
spring:
#数据库配置
datasource:
type: com.alibaba.druid.pool.DruidDataSource
#初始化时建立物理连接的个数,连接池的设置config druid
druid:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://175.18.147.97:3306/nacos?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
username: admin
password:
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: true
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: zccz-admin
login-password: 123456
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
# redis 配置
redis:
# 地址
host: 192.168.1.7
# 密码
password: 1234
# 端口,默认为6379
port: 6379
# 数据库索引
database: 0
# 连接超时时间
timeout: 10s
lettuce:
pool:
# 连接池中的最小空闲连接
min-idle: 0
# 连接池中的最大空闲连接
max-idle: 8
# 连接池的最大数据库连接数
max-active: 8
# #连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
CREATE TABLE `user_likes` (
`id` varchar(32) NOT NULL COMMENT '点赞信息ID',
`info_id` varchar(32) DEFAULT NULL COMMENT '点赞对象id',
`create_time` datetime DEFAULT NULL COMMENT '时间',
`like_user_id` varchar(32) DEFAULT NULL COMMENT '点赞人ID',
`update_time` datetime DEFAULT NULL,
`status` int(11) DEFAULT '0' COMMENT '0 取消 1 点赞',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `agdkey` (`like_user_id`,`info_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='点赞记录表';
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>nacos</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>provider</module>
<module>customer</module>
</modules>
<packaging>pom</packaging>
<name>nacos</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<spring.boot.version>2.1.0.RELEASE</spring.boot.version>
<!-- <spring.boot.version>2.6.5</spring.boot.version>-->
<spring.cloud.alibaba.version>2.1.0.RELEASE</spring.cloud.alibaba.version>
<java.version>1.8</java.version>
<lombok.version>1.18.24</lombok.version>
<druid-spring-boot.version>1.2.11</druid-spring-boot.version>
<mybatis-plus-boot.version>3.5.2</mybatis-plus-boot.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring.cloud.alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- aop切面 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.5</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<!--数据库连接-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid-spring-boot.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus-boot.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>