package com.example.springboot.utils;
public class RedisKeyUtil {
private static String SPLIT = ":";
// 获取粉丝
private static String BIZ_FOLLOWER = "FOLLOWER";
// 关注对象
private static String BIZ_FOLLOWEE = "FOLLOWEE";
// 某个实体的粉丝key
public static String getFollowerKey(int entityType, int entityId) {
return BIZ_FOLLOWER + SPLIT + String.valueOf(entityType) + SPLIT + String.valueOf(entityId);
}
// 每个用户对某类实体的关注key
public static String getFolloweeKey(int userId, int entityType) {
return BIZ_FOLLOWEE + SPLIT + String.valueOf(userId) + SPLIT + String.valueOf(entityType);
}
}
package com.example.springboot.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;
import redis.clients.jedis.*;
import java.io.IOException;
import java.util.List;
import java.util.Set;
@Service
public class JedisAdapter implements InitializingBean {
private static final Logger logger = LoggerFactory.getLogger(JedisAdapter.class);
private JedisPool pool;
//加入
public long zadd(String key, double score, String value) {
Jedis jedis = null;
try {
jedis = pool.getResource();
return jedis.zadd(key, score, value);
} catch (Exception e) {
logger.error("发生异常" + e.getMessage());
} finally {
if (jedis != null) {
jedis.close();
}
}
return 0;
}
//删除
public long zrem(String key, String value) {
Jedis jedis = null;
try {
jedis = pool.getResource();
return jedis.zrem(key, value);
} catch (Exception e) {
logger.error("发生异常" + e.getMessage());
} finally {
if (jedis != null) {
jedis.close();
}
}
return 0;
}
public Jedis getJedis() {
return pool.getResource();
}
// Redis Multi 命令用于标记一个事务块的开始。
public Transaction multi(Jedis jedis) {
try {
return jedis.multi();
} catch (Exception e) {
logger.error("发生异常" + e.getMessage());
} finally {
}
return null;
}
//事务块结束
public List<Object> exec(Transaction tx, Jedis jedis) {
try {
return tx.exec();
} catch (Exception e) {
logger.error("发生异常" + e.getMessage());
tx.discard();
} finally {
if (tx != null) {
try {
tx.close();
} catch (IOException ioe) {
// ..
}
}
if (jedis != null) {
jedis.close();
}
}
return null;
}
//列出成员
public Set<String> zrange(String key, int start, int end) {
Jedis jedis = null;
try {
jedis = pool.getResource();
return jedis.zrange(key, start, end);
} catch (Exception e) {
logger.error("发生异常" + e.getMessage());
} finally {
if (jedis != null) {
jedis.close();
}
}
return null;
}
//反向列出成员
public Set<String> zrevrange(String key, int start, int end) {
Jedis jedis = null;
try {
jedis = pool.getResource();
return jedis.zrevrange(key, start, end);
} catch (Exception e) {
logger.error("发生异常" + e.getMessage());
} finally {
if (jedis != null) {
jedis.close();
}
}
return null;
}
//计算集合中元素的数量
public long zcard(String key) {
Jedis jedis = null;
try {
jedis = pool.getResource();
return jedis.zcard(key);
} catch (Exception e) {
logger.error("发生异常" + e.getMessage());
} finally {
if (jedis != null) {
jedis.close();
}
}
return 0;
}
//判断是否存在
public Double zscore(String key, String member) {
Jedis jedis = null;
try {
jedis = pool.getResource();
return jedis.zscore(key, member);
} catch (Exception e) {
logger.error("发生异常" + e.getMessage());
} finally {
if (jedis != null) {
jedis.close();
}
}
return null;
}
@Override
public void afterPropertiesSet() throws Exception {
}
}
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Response;
import redis.clients.jedis.Transaction;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
@Service
public class FollowService {
@Autowired
JedisAdapter jedisAdapter;
/**
* 用户关注了某个实体,可以关注问题,关注用户,关注评论等任何实体
* @param userId
* @param entityType
* @param entityId
* @return
*/
public boolean follow(int userId, int entityType, int entityId) {
String followerKey = RedisKeyUtil.getFollowerKey(entityType, entityId);
String followeeKey = RedisKeyUtil.getFolloweeKey(userId, entityType);
Date date = new Date();
Jedis jedis = jedisAdapter.getJedis();
//开启redis事务(同时发生或同时不发生)
Transaction tx = jedisAdapter.multi(jedis);
// 实体的粉丝增加当前用户
tx.zadd(followerKey, date.getTime(), String.valueOf(userId));
// 当前用户对这类实体关注+1
tx.zadd(followeeKey, date.getTime(), String.valueOf(entityId));
//结束事务
List<Object> ret = jedisAdapter.exec(tx, jedis);
return ret.size() == 2 && (Long) ret.get(0) > 0 && (Long) ret.get(1) > 0;
}
/**
* 取消关注
* @param userId
* @param entityType
* @param entityId
* @return
*/
public boolean unfollow(int userId, int entityType, int entityId) {
String followerKey = RedisKeyUtil.getFollowerKey(entityType, entityId);
String followeeKey = RedisKeyUtil.getFolloweeKey(userId, entityType);
Date date = new Date();
Jedis jedis = jedisAdapter.getJedis();
Transaction tx = jedisAdapter.multi(jedis);
// 实体的粉丝减少当前用户
tx.zrem(followerKey, String.valueOf(userId));
// 当前用户对这类实体关注-1
tx.zrem(followeeKey, String.valueOf(entityId));
List<Object> ret = jedisAdapter.exec(tx, jedis);
return ret.size() == 2 && (Long) ret.get(0) > 0 && (Long) ret.get(1) > 0;
}
//获得粉丝
public List<Integer> getFollowers(int entityType, int entityId, int count) {
String followerKey = RedisKeyUtil.getFollowerKey(entityType, entityId);
return getIdsFromSet(jedisAdapter.zrevrange(followerKey, 0, count));
}
public List<Integer> getFollowers(int entityType, int entityId, int offset, int count) {
String followerKey = RedisKeyUtil.getFollowerKey(entityType, entityId);
return getIdsFromSet(jedisAdapter.zrevrange(followerKey, offset, offset+count));
}
//获得关注对象
public List<Integer> getFollowees(int userId, int entityType, int count) {
String followeeKey = RedisKeyUtil.getFolloweeKey(userId, entityType);
return getIdsFromSet(jedisAdapter.zrevrange(followeeKey, 0, count));
}
public List<Integer> getFollowees(int userId, int entityType, int offset, int count) {
String followeeKey = RedisKeyUtil.getFolloweeKey(userId, entityType);
return getIdsFromSet(jedisAdapter.zrevrange(followeeKey, offset, offset+count));
}
//获得粉丝数量
public long getFollowerCount(int entityType, int entityId) {
String followerKey = RedisKeyUtil.getFollowerKey(entityType, entityId);
return jedisAdapter.zcard(followerKey);
}
//获得关注者数量
public long getFolloweeCount(int userId, int entityType) {
String followeeKey = RedisKeyUtil.getFolloweeKey(userId, entityType);
return jedisAdapter.zcard(followeeKey);
}
private List<Integer> getIdsFromSet(Set<String> idset) {
List<Integer> ids = new ArrayList<>();
for (String str : idset) {
ids.add(Integer.parseInt(str));
}
return ids;
}
/**
* 判断用户是否关注了某个实体
* @param userId
* @param entityType
* @param entityId
* @return
*/
public boolean isFollower(int userId, int entityType, int entityId) {
String followerKey = RedisKeyUtil.getFollowerKey(entityType, entityId);
return jedisAdapter.zscore(followerKey, String.valueOf(userId)) != null;
}
}