ソースを参照

mongodb 实战1.0

yegang 2 年 前
コミット
2b9ed3b238

+ 4 - 0
pom.xml

@@ -89,6 +89,10 @@
 <!--            <artifactId>hutool-all</artifactId>-->
 <!--            <version>4.5.7</version>-->
 <!--        </dependency>-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-mongodb</artifactId>
+        </dependency>
     </dependencies>
     <build>
         <plugins>

+ 114 - 0
src/main/java/com/sw/controller/ResourceCommentController.java

@@ -0,0 +1,114 @@
+package com.sw.controller;
+
+import com.sw.service.ResourceCommentService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+ 
+
+@RestController
+@RequestMapping(value = "/rc")
+public class ResourceCommentController {
+ 
+    @Autowired
+    private ResourceCommentService resourceCommentService;
+    
+    
+    /**
+     * 列出某个资源的所有评论
+     * 
+     * 客户端页面要做到这些权限限制
+     * 三级按钮:发表评论btn1,回复评论btn2,回复评论的评论btn3
+     * 当前登录用户是本条评论的第一级评论者,
+     *     可以看到发表评论按钮btn1
+     *     不可以看到第二级的回复按钮btn2,即不能给自己的评论回复
+     *     可以看到第三级的按钮btn3,这个按钮可以给回复评论的人回复评论
+     * 
+     * 当前登录用户是本条评论的第二级评论者,即回复评论者
+     *     可以看到发表评论按钮btn1
+     *     可以看到第二级的回复按钮btn2,即可以给他人的评论回复
+     *     不可以看到第三级的按钮btn3,即不可以给自己的回复发表回复评论
+     *     
+     * 当前登录用户不是本条评论的第一级和第二级用户    
+     *     可以看到发表评论按钮btn1
+     *     可以看到第二级的回复按钮btn2,即可以给他人的评论回复
+     *     不可以看到第三级的按钮btn3,只有版主才可以回复评论的评论
+     * 
+     * @param resourceId
+     * @return
+     * @throws Exception
+     * 
+     * example http://localhost:8080/rc/listComments/1
+     */
+    @ResponseBody
+    @RequestMapping(value = "/listComments/{resourceId}")
+    public Object listComments(@PathVariable(value = "resourceId", required = true)Long resourceId) throws Exception {
+        
+        return resourceCommentService.findResourceComment(resourceId);
+    }
+    
+    /**
+     * 发表评论
+     * @param resourceId
+     * @param commentUserId
+     * @param commentUserName
+     * @param commentContent
+     * @return
+     * @throws Exception
+     */
+    @ResponseBody
+    @RequestMapping(value = "/saveComment")
+    public Object saveComment(
+            @RequestParam(value = "resourceId", required = true)Long resourceId, 
+            @RequestParam(value = "commentUserId", required = true)Long commentUserId, 
+            @RequestParam(value = "commentUserName", required = true)String commentUserName, 
+            @RequestParam(value = "commentContent", required = true)String commentContent) throws Exception {
+        return resourceCommentService.saveComment(resourceId, commentUserId, commentUserName, commentContent);
+    }
+    
+    /**
+     * 回复评论
+     * @param id
+     * @param responseUserId
+     * @param responseUserName
+     * @param responseContent
+     * @return
+     * @throws Exception
+     */
+    @ResponseBody
+    @RequestMapping(value = "/saveResponse")
+    public Object saveResponse(
+            @RequestParam(value = "id", required = true)String id, 
+            @RequestParam(value = "responseUserId", required = true)Long responseUserId, 
+            @RequestParam(value = "responseUserName", required = true)String responseUserName, 
+            @RequestParam(value = "responseContent", required = true)String responseContent) throws Exception {
+ 
+        return resourceCommentService.saveResponse(id, responseUserId, responseUserName, responseContent);
+    }
+    
+    /**
+     * 回复评论的评论
+     *     
+     * @param id
+     * @param responseUserId
+     * @param index
+     * @param replyContent
+     * @return
+     * @throws Exception
+     */
+    @ResponseBody
+    @RequestMapping(value = "/saveReply")
+    public Object saveReply(
+            @RequestParam(value = "id", required = true)String id, 
+            @RequestParam(value = "responseUserId", required = true)Long responseUserId, 
+            @RequestParam(value = "index", required = true)Integer index, 
+            @RequestParam(value = "replyContent", required = true)String replyContent) throws Exception {
+        if (null == index) {
+            index = 0;
+        }
+        return resourceCommentService.saveReply(id, responseUserId, index, replyContent);
+    }
+}

+ 9 - 0
src/main/java/com/sw/dao/ResourceCommentRepository.java

@@ -0,0 +1,9 @@
+package com.sw.dao;
+ 
+import com.sw.domain.ResourceComment;
+import org.springframework.data.mongodb.repository.MongoRepository;
+ 
+
+public interface ResourceCommentRepository extends MongoRepository<ResourceComment, String> {
+ 
+}

+ 55 - 0
src/main/java/com/sw/domain/CommentResponse.java

@@ -0,0 +1,55 @@
+package com.sw.domain;
+
+import org.springframework.data.mongodb.core.mapping.Field;
+ 
+public class CommentResponse {
+	/**
+	 * 回复评论的用户ID
+	 */
+	@Field(value = "response_user_id")
+	private Long responseUserId;
+	
+	/**
+	 * 回复评论的用户名
+	 */
+	@Field(value = "response_user_name")
+	private String responseUserName;
+	
+	/**
+	 * 回复的评论内容
+	 */
+	@Field(value = "response_contents")
+	private ResponseContent[] responseContents;
+	
+	/**
+	 * 一楼评论作者 对 回复评论者 的回复
+	 */
+	@Field(value = "get_replys")
+	private ResponseContent[] getReplys;
+	
+	public Long getResponseUserId() {
+		return responseUserId;
+	}
+	public void setResponseUserId(Long responseUserId) {
+		this.responseUserId = responseUserId;
+	}
+	public String getResponseUserName() {
+		return responseUserName;
+	}
+	public void setResponseUserName(String responseUserName) {
+		this.responseUserName = responseUserName;
+	}
+	public ResponseContent[] getResponseContents() {
+		return responseContents;
+	}
+	public void setResponseContents(ResponseContent[] responseContents) {
+		this.responseContents = responseContents;
+	}
+	public ResponseContent[] getGetReplys() {
+		return getReplys;
+	}
+	public void setGetReplys(ResponseContent[] getReplys) {
+		this.getReplys = getReplys;
+	}
+ 
+}

+ 106 - 0
src/main/java/com/sw/domain/ResourceComment.java

@@ -0,0 +1,106 @@
+package com.sw.domain;
+
+import java.util.Date;
+ 
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.index.Indexed;
+import org.springframework.data.mongodb.core.mapping.Document;
+import org.springframework.data.mongodb.core.mapping.Field;
+ 
+@Document(collection = "resource_comment")
+public class ResourceComment {
+	@Id
+	private String id;
+	
+	/**
+	 * 接收评论的资源ID或作品ID
+	 */
+	@Indexed
+	@Field(value = "resource_id")
+	private Long resourceId;
+	
+	/**
+	 * 发表评论的用户ID
+	 */
+	@Indexed
+	@Field(value = "comment_user_id")
+	private Long commentUserId;
+	
+	/**
+	 * 发表评论的用户名
+	 */
+	@Field(value = "comment_user_name")
+	private String commentUserName;
+	
+	/**
+	 * 发表的评论内容
+	 */
+	@Field(value = "comment_content")
+	private String commentContent;
+	
+	/**
+	 * 发表评论的时间
+	 */
+	private Date ctime;
+	
+	/**
+	 * 此条评论的状态:0为正常....
+	 */
+	private String status;
+	
+	/**
+	 * 对此评论的回复
+	 */
+	@Field(value = "comment_responses")
+	private CommentResponse[] commentResponses;
+	
+	public String getId() {
+		return id;
+	}
+	public void setId(String id) {
+		this.id = id;
+	}
+	public Long getResourceId() {
+		return resourceId;
+	}
+	public void setResourceId(Long resourceId) {
+		this.resourceId = resourceId;
+	}
+	public Long getCommentUserId() {
+		return commentUserId;
+	}
+	public void setCommentUserId(Long commentUserId) {
+		this.commentUserId = commentUserId;
+	}
+	public String getCommentUserName() {
+		return commentUserName;
+	}
+	public void setCommentUserName(String commentUserName) {
+		this.commentUserName = commentUserName;
+	}
+	public String getCommentContent() {
+		return commentContent;
+	}
+	public void setCommentContent(String commentContent) {
+		this.commentContent = commentContent;
+	}
+	public Date getCtime() {
+		return ctime;
+	}
+	public void setCtime(Date ctime) {
+		this.ctime = ctime;
+	}
+	public String getStatus() {
+		return status;
+	}
+	public void setStatus(String status) {
+		this.status = status;
+	}
+	public CommentResponse[] getCommentResponses() {
+		return commentResponses;
+	}
+	public void setCommentResponses(CommentResponse[] commentResponses) {
+		this.commentResponses = commentResponses;
+	}
+ 
+}

+ 33 - 0
src/main/java/com/sw/domain/ResponseContent.java

@@ -0,0 +1,33 @@
+package com.sw.domain;
+
+import java.util.Date;
+ 
+public class ResponseContent {
+	
+	private Date ctime;
+	private String content;
+	
+	public ResponseContent() {
+		super();
+	}
+	
+	public ResponseContent(Date ctime, String content) {
+		super();
+		this.ctime = ctime;
+		this.content = content;
+	}
+ 
+	public Date getCtime() {
+		return ctime;
+	}
+	public void setCtime(Date ctime) {
+		this.ctime = ctime;
+	}
+	public String getContent() {
+		return content;
+	}
+	public void setContent(String content) {
+		this.content = content;
+	}
+ 
+}

+ 50 - 0
src/main/java/com/sw/service/ResourceCommentService.java

@@ -0,0 +1,50 @@
+package com.sw.service;
+
+import com.sw.domain.ResourceComment;
+
+import java.util.List;
+ 
+
+public interface ResourceCommentService {
+	
+	/**
+	 * 查询某资源的所有评论
+	 * 
+	 * @param resourceId
+	 * @return
+	 */
+	public List<ResourceComment> findResourceComment(Long resourceId);
+ 
+	/**
+	 * 对指定资源发表评论
+	 * 
+	 * @param resourceId      资源ID
+	 * @param commentUserId   用户ID
+	 * @param commentUserName 用户名
+	 * @param commentContent  评论内容
+	 * @return 1成功,0失败
+	 */
+	public int saveComment(Long resourceId, Long commentUserId, String commentUserName, String commentContent);
+	
+	/**
+	 * 回复评论
+	 * 
+	 * @param id                 原评论的ID
+	 * @param responseUserId     回复评论的用户ID
+	 * @param responseUserName   回复评论的用户名
+	 * @param responseContent    回复的内容
+	 * @return 1成功,0失败
+	 */
+	public int saveResponse(String id, Long responseUserId, String responseUserName, String responseContent);
+ 
+	/**
+	 * 一楼评论者 回复二楼评论者 的评论
+	 * 
+	 * @param id                 原评论的ID
+	 * @param responseUserId     回复评论的用户ID
+	 * @param index              要回复的评论索引值,从0开始
+	 * @param replyContent       一楼评论者 回复的内容
+	 * @return 1成功,0失败
+	 */
+	public int saveReply(String id, Long responseUserId, int index, String replyContent);
+}

+ 0 - 1
src/main/java/com/sw/service/SysUserService.java

@@ -11,5 +11,4 @@ import com.sw.domain.SysUser;
  */
 public interface SysUserService extends IService<SysUser> {
 
-
 }

+ 261 - 0
src/main/java/com/sw/service/impl/ResourceCommentServiceImpl.java

@@ -0,0 +1,261 @@
+package com.sw.service.impl;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+
+import com.sw.dao.ResourceCommentRepository;
+import com.sw.domain.CommentResponse;
+import com.sw.domain.ResourceComment;
+import com.sw.domain.ResponseContent;
+import com.sw.service.ResourceCommentService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Example;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+ 
+
+@Service(value = "resourceCommentService")
+public class ResourceCommentServiceImpl implements ResourceCommentService {
+ 
+	@Autowired
+	private ResourceCommentRepository resourceCommentRepository;
+ 
+	/**
+	 * 查询某个资源的所有评论
+	 */
+	@Override
+	public List<ResourceComment> findResourceComment(Long resourceId) {
+		if (null == resourceId) {
+			return null;
+		}
+		
+		ResourceComment rc = new ResourceComment();
+		rc.setResourceId(resourceId);
+		return resourceCommentRepository.findAll(Example.of(rc));
+	}
+ 
+	/**
+	 * 发表评论
+	 */
+	@Override
+	public int saveComment(Long resourceId, Long commentUserId, String commentUserName, String commentContent) {
+		//数据合法性校验 begin
+		if (null == resourceId || null == commentUserId) {
+			return 0;
+		}
+		
+		if (StringUtils.isEmpty(commentUserName) || StringUtils.isEmpty(commentContent)) {
+			return 0;
+		}
+		//数据合法性校验 end
+		
+		//保存评论 begin
+		ResourceComment rc = new ResourceComment();
+		rc.setResourceId(resourceId);
+		rc.setCommentUserId(commentUserId);
+		rc.setCommentUserName(commentUserName);
+		rc.setCommentContent(commentContent);
+		rc.setCtime(new Date());
+		rc.setStatus("0"); //此处可采用常量或枚举类型
+		resourceCommentRepository.save(rc);
+		//保存评论 end
+		
+		return 0;
+	}
+ 
+	/**
+	 * 回复评论
+	 */
+	@Override
+	public int saveResponse(String id, Long responseUserId, String responseUserName, String responseContent) {
+		//数据合法性校验 begin
+		if (StringUtils.isEmpty(id)) {
+			return 0;
+		}
+		
+		if (null == responseUserId) {
+			return 0;
+		}
+		
+		if (StringUtils.isEmpty(responseUserName) || StringUtils.isEmpty(responseContent)) {
+			return 0;
+		}
+		//数据合法性校验 end
+		
+		//查找指定评论 begin
+		ResourceComment rc = new ResourceComment();
+		rc.setId(id);
+		
+		Optional<ResourceComment> optional = resourceCommentRepository.findOne(Example.of(rc));
+		if (!optional.isPresent()) {
+			//未找到指定的评论
+			return 0;
+		}
+		
+		rc = optional.get();
+		//查找指定评论 end
+		
+		//得到巳有回复
+		CommentResponse[] crs = rc.getCommentResponses();
+		if (null == crs) {
+			//此评论之前没有任何人回复,当前回复作为第一条回复
+			CommentResponse cr = getNewResponse(responseUserId, responseUserName, responseContent);
+			rc.setCommentResponses(new CommentResponse[]{cr});
+			
+			resourceCommentRepository.save(rc);
+			return 1;
+		}
+		
+		//己有人回复过评论,判断responseUserId是否回复过评论 begin
+		//responseUserId之前是否回复过此评论 begin
+		boolean responsed = false;
+		for (int i = 0; i < crs.length; i++) {
+			if (crs[i].getResponseUserId().equals(responseUserId)) {
+				responsed = true; //之前回复过
+				ResponseContent[] rcsNew = getNewResponseContent(responseContent, crs, crs[i].getResponseContents());
+				
+				crs[i].setResponseContents(rcsNew);
+				
+				break; //已经回复,不再继续循环
+			}
+		}
+		//己有人回复过评论,判断responseUserId是否回复过评论 end
+		if (responsed) {
+			//之前,responseUserId已经回复过此评论,在现有回复后追加一个回复即可
+			resourceCommentRepository.save(rc);
+			return 1;
+		}
+		
+		//之前别人回复过此评论,但responseUserId没有回复过此评论 begin
+		//将之前所有人的回复转储到新的数组
+		CommentResponse[] crsNew = new CommentResponse[crs.length + 1];
+		CommentResponse cr = getNewResponse(responseUserId, responseUserName, responseContent);
+		for (int i = 0; i < crs.length; i++) {
+			crsNew[i] = crs[i];
+		}
+		crsNew[crsNew.length - 1] = cr;
+		//之前别人回复过此评论,但responseUserId没有回复过此评论 end
+		rc.setCommentResponses(crsNew);
+		
+		resourceCommentRepository.save(rc);
+		return 1;
+	}
+ 
+	/**
+	 * 回复评论的评论
+	 */
+	@Override
+	public int saveReply(String id, Long responseUserId, int index, String replyContent) {
+		//数据合法性校验 begin
+		if (StringUtils.isEmpty(id)) {
+			return 0;
+		}
+		
+		if (null == responseUserId) {
+			return 0;
+		}
+		
+		if (index < 0) {
+			//索引值不能小于零
+			return 0;
+		}
+		
+		if (StringUtils.isEmpty(replyContent)) {
+			return 0;
+		}
+		//数据合法性校验 end
+		
+		//查找指定评论 begin
+		ResourceComment rc = new ResourceComment();
+		rc.setId(id);
+		
+		Optional<ResourceComment> optional = resourceCommentRepository.findOne(Example.of(rc));
+		if (!optional.isPresent()) {
+			//未找到指定的评论
+			return 0;
+		}
+		
+		rc = optional.get();
+		//查找指定评论 end
+		
+		CommentResponse[] crs = rc.getCommentResponses();
+		if (null == crs || crs.length < 1) {
+			//没有人回复过评论
+			return 0;
+		}
+		
+		for (int i = 0; i < crs.length; i++) {
+			if (responseUserId.equals(crs[i].getResponseUserId())) {
+				//找到responseUserId回复的评论
+				ResponseContent[] rcs = crs[i].getResponseContents();//回复的评论数组
+				if (null == rcs || index >= rcs.length) {
+					//responseUserId没有对评论回复任何内容或index越界,指定的回复不存在,不再继续
+					return 0;
+				}
+				
+				ResponseContent[] grs = crs[i].getGetReplys();
+				if (null == grs) {
+					//之前没有回复过评论的评论
+					grs = new ResponseContent[index+1];
+					ResponseContent reply = new ResponseContent(new Date(), replyContent);
+					grs[index] = reply;
+					crs[i].setGetReplys(grs);
+				} else {
+					//之前回复过评论的评论
+					if (index >= grs.length) {
+						//索引值超过现有回复数组的长度,给数组增长
+						ResponseContent[] grsNew = new ResponseContent[index + 1];
+						ResponseContent reply = new ResponseContent(new Date(), replyContent);
+						grsNew[index] = reply;
+						crs[i].setGetReplys(grsNew);
+					} else {
+						//索引值未超过回复数组的长度,reply内容直接覆盖索引值的reply
+						ResponseContent reply = new ResponseContent(new Date(), replyContent);
+						grs[index] = reply;
+						crs[i].setGetReplys(grs);
+					}
+				}
+				
+				resourceCommentRepository.save(rc);
+				return 1;
+			}
+		}
+		
+		return 0;
+	}
+	
+	private ResponseContent[] getNewResponseContent(String responseContent, CommentResponse[] crs, ResponseContent[] rcs) {
+		ResponseContent[] rcsNew = null;
+		int rcsSize = 0;
+		if (null == rcs) {
+			rcsSize++;
+			rcsNew = new ResponseContent[rcsSize]; //防止程序异常,没有回复
+		} else {
+			rcsSize = rcs.length + 1;
+			rcsNew = new ResponseContent[rcsSize];
+			for (int i = 0; i < rcs.length; i++) {
+				//原先的回复转储到新的数组
+				rcsNew[i] = rcs[i];
+			}
+		}
+		ResponseContent rcon = new ResponseContent();
+		rcon.setCtime(new Date());
+		rcon.setContent(responseContent);
+		rcsNew[rcsSize - 1] = rcon;
+		return rcsNew;
+	}
+ 
+	private CommentResponse getNewResponse(Long responseUserId, String responseUserName, String responseContent) {
+		CommentResponse cr = new CommentResponse();
+		cr.setResponseUserId(responseUserId);
+		cr.setResponseUserName(responseUserName);
+		ResponseContent rct = new ResponseContent();
+		rct.setCtime(new Date());
+		rct.setContent(responseContent);
+		cr.setResponseContents(new ResponseContent[] {rct});
+		return cr;
+	}
+ 
+	
+}

+ 7 - 0
src/main/resources/application.yml

@@ -1,6 +1,13 @@
 server:
   port: 8089
 spring:
+  data:
+    mongodb:
+      host: 192.168.20.85
+      port: 27017
+      database: admin
+      username: root
+      password: '123456'
   application:
     name: mask
   datasource:

+ 86 - 20
src/test/java/com/sw/RedissonTest.java

@@ -24,7 +24,7 @@ import java.util.concurrent.TimeUnit;
 public class RedissonTest {
     @Autowired
     private RedissonClient redissonClient;
-    private CountDownLatch count = new CountDownLatch(2);
+    private CountDownLatch count = new CountDownLatch(3);
 
     @Test
     public void lock() {
@@ -40,8 +40,8 @@ public class RedissonTest {
             } catch (InterruptedException e) {
                 e.printStackTrace();
             } finally {
-                if(lock.isLocked()){
-                    if(lock.isHeldByCurrentThread()){
+                if (lock.isLocked()) {
+                    if (lock.isHeldByCurrentThread()) {
                         lock.unlock();
                     }
                 }
@@ -59,8 +59,8 @@ public class RedissonTest {
             } catch (InterruptedException e) {
                 e.printStackTrace();
             } finally {
-                if(lock.isLocked()){
-                    if(lock.isHeldByCurrentThread()){
+                if (lock.isLocked()) {
+                    if (lock.isHeldByCurrentThread()) {
                         lock.unlock();
                     }
                 }
@@ -96,8 +96,8 @@ public class RedissonTest {
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 } finally {
-                    if(lock.isLocked()){
-                        if(lock.isHeldByCurrentThread()){
+                    if (lock.isLocked()) {
+                        if (lock.isHeldByCurrentThread()) {
                             lock.unlock();
                         }
                     }
@@ -120,8 +120,8 @@ public class RedissonTest {
                     } catch (InterruptedException e) {
                         e.printStackTrace();
                     } finally {
-                        if(lock.isLocked()){
-                            if(lock.isHeldByCurrentThread()){
+                        if (lock.isLocked()) {
+                            if (lock.isHeldByCurrentThread()) {
                                 lock.unlock();
                             }
                         }
@@ -141,6 +141,7 @@ public class RedissonTest {
         }
         log.info("子线程都已执行完毕,main函数可以结束了!");
     }
+
     @Test
     public void trylock2() {
         RLock lock = redissonClient.getLock("mask-" + 1);
@@ -161,17 +162,17 @@ public class RedissonTest {
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 } finally {
-                    if(lock.isLocked()){
-                        if(lock.isHeldByCurrentThread()){
+                    if (lock.isLocked()) {
+                        if (lock.isHeldByCurrentThread()) {
+                            log.info("线程:{},释放了锁", threadName);
                             count.countDown();
                             lock.unlock();
                         }
                     }
-                    log.info("线程:{},释放了锁", threadName);
                 }
             } else {
-                count.countDown();
                 log.info("{}:没有获取到锁,锁已被占用", threadName);
+                count.countDown();
             }
         }).start();
         new Thread(() -> {
@@ -187,17 +188,46 @@ public class RedissonTest {
                     } catch (InterruptedException e) {
                         e.printStackTrace();
                     } finally {
-                        if(lock.isLocked()){
-                            if(lock.isHeldByCurrentThread()){
+                        if (lock.isLocked()) {
+                            if (lock.isHeldByCurrentThread()) {
+                                log.info("线程:{},释放了锁", threadName);
                                 count.countDown();
                                 lock.unlock();
                             }
                         }
-                        log.info("线程:{},释放了锁", threadName);
                     }
                 } else {
+                    log.info("{}:没有获取到锁,锁已被占用", threadName);
                     count.countDown();
+                }
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }).start();
+        new Thread(() -> {
+            String threadName = Thread.currentThread().getName();
+            log.info("线程:{} 正在尝试获取锁。。。", threadName);
+            try {
+                if (lock.tryLock(4000, TimeUnit.MILLISECONDS)) {
+                    try {
+
+                        Thread.sleep(6000);
+                        log.info("{}:业务执行完成", threadName);
+
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    } finally {
+                        if (lock.isLocked()) {
+                            if (lock.isHeldByCurrentThread()) {
+                                log.info("线程:{},释放了锁", threadName);
+                                count.countDown();
+                                lock.unlock();
+                            }
+                        }
+                    }
+                } else {
                     log.info("{}:没有获取到锁,锁已被占用", threadName);
+                    count.countDown();
                 }
             } catch (InterruptedException e) {
                 e.printStackTrace();
@@ -211,6 +241,42 @@ public class RedissonTest {
         log.info("子线程都已执行完毕,main函数可以结束了!");
     }
     @Test
+    public void trylock3(){
+        // 1.获取锁,只要锁的名字一样,获取到的锁就是同一把锁。
+        RLock lock = redissonClient.getLock("WuKong-lock");
+        new Thread(()->{
+
+
+            // 2.加锁
+            lock.lock();
+            try {
+                System.out.println("加锁成功,执行后续代码。线程 ID:" + Thread.currentThread().getId());
+                Thread.sleep(10000);
+            } catch (Exception e) {
+                //TODO
+            } finally {
+                lock.unlock();
+                // 3.解锁
+                System.out.println("Finally,释放锁成功。线程 ID:" + Thread.currentThread().getId());
+            }
+        }).start();
+        new Thread(()->{
+
+            // 2.加锁
+            lock.lock();
+            try {
+                System.out.println("加锁成功,执行后续代码。线程 ID:" + Thread.currentThread().getId());
+                Thread.sleep(10000);
+            } catch (Exception e) {
+                //TODO
+            } finally {
+                lock.unlock();
+                // 3.解锁
+                System.out.println("Finally,释放锁成功。线程 ID:" + Thread.currentThread().getId());
+            }
+        }).start();
+    }
+    @Test
     public void timeout() {
 
         RLock lock = redissonClient.getLock("mask-" + 3);
@@ -225,13 +291,13 @@ public class RedissonTest {
         if (b) {
             try {
 
-                Thread.sleep(5000);
+                Thread.sleep(6000);
                 log.info("{}:业务执行完成", threadName);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             } finally {
-                if(lock.isLocked()){
-                    if(lock.isHeldByCurrentThread()){
+                if (lock.isLocked()) {
+                    if (lock.isHeldByCurrentThread()) {
                         lock.unlock();
                     }
                 }
@@ -240,6 +306,6 @@ public class RedissonTest {
         } else {
             log.info("{}:没有获取到锁,锁已被占用", threadName);
         }
-}
+    }
 
 }

+ 94 - 0
src/test/java/com/sw/ResourceCommentTests.java

@@ -0,0 +1,94 @@
+package com.sw;
+
+import java.util.Optional;
+
+import com.sw.dao.ResourceCommentRepository;
+import com.sw.domain.ResourceComment;
+import com.sw.service.ResourceCommentService;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.data.domain.Example;
+import org.springframework.test.context.junit4.SpringRunner;
+ 
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class ResourceCommentTests {
+ 
+	@Autowired
+	private ResourceCommentRepository resourceCommentRepository;
+	
+	@Autowired
+	private ResourceCommentService resourceCommentService;
+	
+	@Before
+	public void setUp() {
+		
+	}
+	
+	/**
+	 * 测试评论
+	 */
+	@Test
+	public void testSaveComment() {
+		Long resourceId = 1L;
+		Long commentUserId = 1L;
+		String commentUserName = "用户" + commentUserId;
+		String commentContent =   "唐朝最有名的皇帝是李世民 " + System.currentTimeMillis();
+		resourceCommentService.saveComment(resourceId, commentUserId, commentUserName, commentContent);
+	}
+	
+	/**
+	 * 测试评论回复
+	 */
+	@Test
+	public void testSaveResponse() {
+		String id = "6226ba6dc67ad134b608fd88";
+		Long responseUserId = 2L;
+		String responseUserName = "用户" + responseUserId;
+		String responseContent =  "我不认为是李世明,我认为是武则天" + System.currentTimeMillis();
+		
+		resourceCommentService.saveResponse(id, responseUserId, responseUserName, responseContent);
+	}
+	/**
+	 * 测试评论回复
+	 */
+	@Test
+	public void testSaveResponse2() {
+		String id = "6226ba6dc67ad134b608fd88";
+		Long responseUserId = 3L;
+		String responseUserName = "用户" + responseUserId;
+		String responseContent =  "我不认为是李世明,我认为是李渊" + System.currentTimeMillis();
+
+		resourceCommentService.saveResponse(id, responseUserId, responseUserName, responseContent);
+	}
+	/**
+	 * 测试回复评论的评论
+	 */
+	@Test
+	public void testSaveReply() {
+		String id = "6226ba6dc67ad134b608fd88";
+		Long responseUserId = 2L;
+		int index = 0;
+		String replyContent = "我不认为是武则天,我认为是李隆基" + System.currentTimeMillis();
+		
+		resourceCommentService.saveReply(id, responseUserId, index, replyContent);
+	}
+	
+	@Test
+	public void testFind() {
+		ResourceComment rc = new ResourceComment();
+		rc.setResourceId(1L);
+		rc.setCommentUserId(1L);
+		Example<ResourceComment> example = Example.of(rc);
+		Optional<ResourceComment> optional = resourceCommentRepository.findOne(example);
+		Assert.assertTrue(optional.isPresent());
+		Assert.assertEquals("user1", optional.get().getCommentUserName());
+	}
+	
+	
+}