package com.xiaozhi.blog.redis; import java.nio.charset.Charset; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.PostConstruct; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.BulkMapper; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.query.SortQuery; import org.springframework.data.redis.core.query.SortQueryBuilder; import org.springframework.data.redis.support.atomic.RedisAtomicLong; import org.springframework.data.redis.support.collections.DefaultRedisList; import org.springframework.data.redis.support.collections.RedisList; import org.springframework.stereotype.Component; import com.xiaozhi.blog.utils.KeyUtils; import com.xiaozhi.blog.utils.MentionUtil; import com.xiaozhi.blog.vo.Comment; import com.xiaozhi.blog.vo.CommentShow; import com.xiaozhi.blog.vo.Range; @Component public class CommentDao { private static Log logger = LogFactory.getLog(CommentDao.class); private RedisAtomicLong commentIdCounter; @Autowired private StringRedisTemplate template; @Autowired private RetwisRepository retwisRepository; @Autowired private BlogDao blogDao; @Autowired private MentionUtil mentionUtil; @PostConstruct public void init () { commentIdCounter = new RedisAtomicLong(KeyUtils.globalPid(), template.getConnectionFactory()); } /** * 对微薄进行评论 * @param pid * @param comment * @param blogOwner 微薄对应的拥有者id * @return */ public boolean addComment(final String pid,final Comment comment,final String blogOwner,boolean isReplay) { final String cid = String.valueOf(commentIdCounter.incrementAndGet()); comment.setCommentId(cid); this.handleMentions(comment);//处理提及@用户的评论 final Map<byte[], byte[]> commentMap= new HashMap<byte[], byte[]>(); commentMap.put("uid".getBytes(), comment.getUid().getBytes()); commentMap.put("commentId".getBytes(), comment.getCommentId().toString().getBytes()); if(!isReplay){ commentMap.put("targetBlogId".getBytes(), pid.getBytes());//评论目标为微博 }else{ commentMap.put("targetCommentId".getBytes(), comment.getTargetCommentId().getBytes());//回复目标 } commentMap.put("time".getBytes(), comment.getTime().getBytes()); commentMap.put("content".getBytes(), comment.getContent().getBytes(Charset.forName("UTF-8"))); boolean result = (Boolean) template.execute(new RedisCallback<Object>() { @Override public Object doInRedis(RedisConnection connection)throws DataAccessException { try { connection.multi();//事务开启 connection.hMSet(KeyUtils.commentKey(cid).getBytes(), commentMap);//Hash形式存储评论 connection.lPush(KeyUtils.commentByBlog(pid).getBytes(), cid.getBytes());//加入微薄评论列表 connection.lPush(KeyUtils.postComments(comment.getUid()).getBytes(), cid.getBytes());//发出评论列表 //如果不是自己给自己评论则加入收到评论列表 if(!comment.getUid().equals(blogOwner))connection.lPush(KeyUtils.receiveComments(blogOwner).getBytes(), cid.getBytes()); connection.hIncrBy(KeyUtils.post(pid).getBytes(), "commentNum".getBytes(), 1);//对评论数进行+1操作 connection.exec(); return true; } catch (Exception e) { logger.error("==================> addComment error :"+e.toString()); }finally{ connection.close(); } return false; } }); return result; } /** * 删除微薄评论 * @param name * @param userid * @return */ public boolean removeComment(final String pid,final String commentId,final String uid,final String blogOwner){ boolean result = (Boolean) template.execute(new RedisCallback<Object>() { @Override public Object doInRedis(RedisConnection connection)throws DataAccessException { try { connection.multi();//事务开启 connection.del(KeyUtils.commentKey(commentId).getBytes());//删除评论对象 connection.lRem(KeyUtils.commentByBlog(pid).getBytes(), 0, commentId.getBytes());//删除微薄对应评论Id connection.lRem(KeyUtils.postComments(uid).getBytes(), 0, commentId.getBytes());//删除发出的评论 if(!uid.equals(blogOwner))connection.lRem(KeyUtils.receiveComments(blogOwner).getBytes(), 0, commentId.getBytes());//删除收到的评论 connection.hIncrBy(KeyUtils.post(pid).getBytes(), "commentNum".getBytes(), -1);//对评论数进行-1操作 connection.exec(); return true; } catch (Exception e) { logger.error("==================> removeComment error :"+e.toString()); }finally{ connection.close(); } return false; } }); return result; } /** * 获得一条微博的评论列表 * @param pid * @param userid * @return */ public List<CommentShow> getCommentListByPid(String pid,final String userid){ String cidKey = "commentid:*->"; SortQuery<String> query = SortQueryBuilder.sort(KeyUtils.commentByBlog(pid)).noSort() .get("#") .get(cidKey + "uid") .get(cidKey + "commentId") .get(cidKey + "targetBlogId") .get(cidKey + "time") .get(cidKey + "content") .limit(0,9).build(); BulkMapper<CommentShow, String> hm = new BulkMapper<CommentShow, String>() { public CommentShow mapBulk(List<String> bulk) { CommentShow commentShow = new CommentShow(); commentShow.setContent(mentionUtil.replaceMentions(bulk.get(5))); commentShow.setTime(bulk.get(4)); commentShow.setCommentId(Integer.valueOf(bulk.get(2))); commentShow.setUser(retwisRepository.getUserById(bulk.get(1))); commentShow.setCanDelete(bulk.get(1).equals(userid)?true:false); commentShow.initTimeShow();//初始化时间显示 return commentShow; } }; List<CommentShow> comments = template.sort(query, hm); return comments; } /** * 获得用户收到的评论列表 * @param uid * @return */ public List<CommentShow> getCommentListByReceiveComment(final String uid,Range range){ String cidKey = "commentid:*->"; SortQuery<String> query = SortQueryBuilder.sort(KeyUtils.receiveComments(uid)).noSort() .get("#") .get(cidKey + "uid") .get(cidKey + "commentId") .get(cidKey + "targetBlogId") .get(cidKey + "time") .get(cidKey + "content") .limit(range.being, range.end-range.being+1).build(); BulkMapper<CommentShow, String> hm = new BulkMapper<CommentShow, String>() { public CommentShow mapBulk(List<String> bulk) { CommentShow commentShow = new CommentShow(); commentShow.setWebPost(blogDao.getBlogForCommentINfo(bulk.get(3), false)); commentShow.setContent(mentionUtil.replaceMentions(bulk.get(5))); commentShow.setTime(bulk.get(4)); commentShow.setCommentId(Integer.valueOf(bulk.get(2))); commentShow.setUser(retwisRepository.getUserById(bulk.get(1))); commentShow.setCanDelete(bulk.get(1).equals(uid)?true:false); commentShow.initTimeShow();//初始化时间显示 return commentShow; } }; List<CommentShow> comments = template.sort(query, hm); return comments; } /** * 获得用户收到的评论数 * @param uid * @return */ public int getCommentListByReceiveCommentNum(String uid){ return template.opsForList().size(KeyUtils.receiveComments(uid)).intValue(); } /** * 获得用户发出的评论列表 * @param uid * @return */ public List<CommentShow> getCommentListByPostComment(final String uid,Range range){ String cidKey = "commentid:*->"; SortQuery<String> query = SortQueryBuilder.sort(KeyUtils.postComments(uid)).noSort() .get("#") .get(cidKey + "uid") .get(cidKey + "commentId") .get(cidKey + "targetBlogId") .get(cidKey + "time") .get(cidKey + "content") .limit(range.being, range.end-range.being+1).build(); BulkMapper<CommentShow, String> hm = new BulkMapper<CommentShow, String>() { public CommentShow mapBulk(List<String> bulk) { CommentShow commentShow = new CommentShow(); commentShow.setWebPost(blogDao.getBlogForCommentINfo(bulk.get(3), true)); commentShow.setContent(mentionUtil.replaceMentions(bulk.get(5))); commentShow.setTime(bulk.get(4)); commentShow.setCommentId(Integer.valueOf(bulk.get(2))); commentShow.setUser(retwisRepository.getUserById(bulk.get(1))); commentShow.setCanDelete(bulk.get(1).equals(uid)?true:false); commentShow.initTimeShow();//初始化时间显示 return commentShow; } }; List<CommentShow> comments = template.sort(query, hm); return comments; } /** * 获得用户发出的评论数 * @param uid * @return */ public int getCommentListByPostCommentNum(String uid){ return template.opsForList().size(KeyUtils.postComments(uid)).intValue(); } /** * 提到我的评论列表 * @param uid * @return */ public List<CommentShow> getCommentListByMention(final String uid,Range range){ String cidKey = "commentid:*->"; SortQuery<String> query = SortQueryBuilder.sort(KeyUtils.commentmentions(uid)).noSort() .get("#") .get(cidKey + "uid") .get(cidKey + "commentId") .get(cidKey + "targetBlogId") .get(cidKey + "time") .get(cidKey + "content") .limit(range.being, range.end-range.being+1).build(); BulkMapper<CommentShow, String> hm = new BulkMapper<CommentShow, String>() { public CommentShow mapBulk(List<String> bulk) { CommentShow commentShow = new CommentShow(); commentShow.setWebPost(blogDao.getBlogForCommentINfo(bulk.get(3), true)); commentShow.setContent(mentionUtil.replaceMentions(bulk.get(5))); commentShow.setTime(bulk.get(4)); commentShow.setCommentId(Integer.valueOf(bulk.get(2))); commentShow.setUser(retwisRepository.getUserById(bulk.get(1))); commentShow.setCanDelete(bulk.get(1).equals(uid)?true:false); commentShow.initTimeShow();//初始化时间显示 return commentShow; } }; List<CommentShow> comments = template.sort(query, hm); return comments; } /** * 提到我的评论数 * @param uid * @return */ public int getCommentListByMentionNum(String uid){ return template.opsForList().size(KeyUtils.commentmentions(uid)).intValue(); } /** * 处理提及@用户的事宜 * @param post * @param pid */ private void handleMentions(Comment comment) { // find mentions Collection<String> mentions = mentionUtil.findMentions(comment.getContent()); for (String mention : mentions) { String uid = retwisRepository.findUidByNickname(mention); if (uid != null) { commentmentions(uid).addFirst(comment.getCommentId().toString()); } } } private RedisList<String> commentmentions(String uid) { return new DefaultRedisList<String>(KeyUtils.commentmentions(uid), template); } }