1.创建工程并引入依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.6.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
    </dependency>
</dependencies>

2.创建application.yml

spring:
  #数据源配置
  data:
    mongodb:
      #主机地址
      host: 192.168.43.182
      #数据库
      database: articledb
      #默认端口是27017
      port: 27017
      #也可以使用uri连接
      #uri: mongodb://192.168.43.182:27017/articledb
      #如果数据库需要密码认证
      #uri: mongodb://bobo:123456@192.168.43.182:27017/articledb

3.创建启动类

@SpringBootApplication
public class ArticleApplication {
    public static void main(String[] args) {
        SpringApplication.run(ArticleApplication.class, args);
    }
}

4.启动项目,看是否能正常启动,控制台没有错误

5.文章评论实体类的编写

/**
 * 文章评论实体类
 */
@Document(collection = "comment")// 可以省略,如果省略,则默认使用类名小写映射集合
// 复合索引
// @CompoundIndex( def = "{'userid': 1, 'nickname': -1}")
public class Comment implements Serializable {

    //主键标识,该属性的值会自动对应mongodb的主键字段"_id",如果该属性名就叫“id”,则该注解可以省略,否则必须写
    @Id
    private String id; // 主键
    //该属性对应mongodb的字段的名字,如果一致,则无需该注解
    @Field("content")
    private String content; // 吐槽内容
    private Date publishtime; // 发布日期
    //添加了一个单字段的索引
    @Indexed
    private String userid; // 发布人ID
    private String nickname; // 昵称
    private LocalDateTime createdatetime; // 评论的日期时间
    private Integer likenum; // 点赞数
    private Integer replynum; // 回复数
    private String state;//状态
    private String parentid; // 上级ID
    private String articleid; // 文章id

    /********************* get/set方法 *********************/
}

  说明:
    索引可以大大提升查询效率,一般在查询字段上添加索引,索引的添加可以通过Mongo的命令来添加,也可以在Java的实体类中通过注解添加。
    1)单字段索引注解@Indexed
      声明该字段需要索引,建索引可以大大的提高查询效率。
      Mongo命令参考:db.comment.createIndex({"userid":1})

    2 )复合索引注解@CompoundIndex
      复合索引的声明,建复合索引可以有效地提高多字段的查询效率。
      Mongo命令参考:db.comment.createIndex({"userid":1,"nickname":-1})

6.创建数据访问接口

/**
 * 评论的持久层接口
 */
public interface CommentDao extends MongoRepository<Comment, String> {
}

7.创建业务逻辑类

/**
 * 评论的业务层
 */
@Service
public class CommentService {

    @Autowired
    private CommentDao commentDao;

    /**
     * 保存一个评论
     * @param comment
     */
    public void saveComment(Comment comment) {
        //如果需要自定义主键,可以在这里指定主键;如果不指定主键,MongoDB会自动生成主键
        commentDao.save(comment);
    }

    /**
     * 更新评论
     * @param comment
     */
    public void updateComment(Comment comment) {
        commentDao.save(comment);
    }

    /**
     * 根据id删除评论
     * @param id
     */
    public void deleteCommentById(String id) {
        commentDao.deleteById(id);
    }

    /**
     * 查询所有评论
     * @return
     */
    public List<Comment> findCommentList() {
        return commentDao.findAll();
    }

    /**
     * 根据id查询评论
     * @param id
     * @return
     */
    public Comment findCommentById(String id) {
        return commentDao.findById(id).get();
    }
}

8.测试

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ArticleApplication.class)
public class CommentServiceTest {

    @Autowired
    private CommentService commentService;

    /**
     * 保存一个评论
     */
    @Test
    public void testSaveComment() {
        Comment comment = new Comment();
        comment.setArticleid("100000");
        comment.setContent("测试添加的数据");
        comment.setCreatedatetime(LocalDateTime.now());
        comment.setUserid("1003");
        comment.setNickname("凯撒大帝");
        comment.setState("1");
        comment.setLikenum(0);
        comment.setReplynum(0);

        commentService.saveComment(comment);
    }

    /**
     * 查询所有数据
     */
    @Test
    public void testFindAll() {
        List<Comment> list = commentService.findCommentList();
        System.out.println(list);
    }

    /**
     * 测试根据id查询
     */
    @Test
    public void testFindCommentById() {
        Comment comment = commentService.findCommentById("1");
        System.out.println(comment);
    }
}

MongoTemplate 实现评论点赞

  低效率的点赞代码: CommentService 新增 updateThumbup方法

/**
 * 点赞-效率低
 * @param id
 */
public void updateCommentThumbupToIncrementingOld(String id){
    Comment comment = commentDao.findById(id).get();
    comment.setLikenum(comment.getLikenum() + 1);
    commentDao.save(comment);
}

  以上方法虽然实现起来比较简单,但是执行效率并不高,因为我们只需要将点赞数加 1 就可以了,没必要查询出所有字段修改后再更新所有字段。(蝴蝶效应)
  可以使用MongoTemplate类来实现对某列的操作。

  (1)修改CommentService

//注入MongoTemplate
@Autowired
private MongoTemplate mongoTemplate;
/**
 * 赞数+1
 * @param id
 *   
 */
public void updateCommentLikenum(String id) {
    // 查询对象
    Query query = Query.query(Criteria.where("_id").is(id));
    // 更新对象
    Update update = new Update();
    //局部更新,相当于$set
    // update.set(key,value)
    // 递增$inc
    // update.inc("likenum",1);
    update.inc("likenum");
    // 参数1:查询对象
    // 参数2:更新对象
    // 参数3:集合的名字或实体类的类型Comment.class
    // mongoTemplate.updateFirst(query, update, "comment");
    mongoTemplate.updateFirst(query, update, Comment.class);
}

  (2)测试

/**
 * 点赞数+1
 */
@Test
public void testUpdateCommentLikenum() {
    //对3号文档的点赞数+1
    commentService.updateCommentLikenum("3");
}

 SpringDataMongoDB 连接副本集

  副本集语法:

    mongodb://host1,host2,host3/articledb?connect=replicaSet&slaveOk=true&replicaSet=副本集名字

    slaveOk=true :开启副本节点读的功能,可实现读写分离。
    connect=replicaSet :自动到副本集中选择读写的主机。如果slaveOK是打开的,则实现了读写分离
  修改配置文件application.yml:

spring:
  #数据源配置
  data:
    mongodb:
      #主机地址
      #host: 192.168.43.182
      #数据库
      #database: articledb
      #默认端口是27017
      #port: 27017
      #副本集的连接字符串
      uri: mongodb://192.168.43.182:27017,192.168.43.182:27018,192.168.43.182:27019/articledb?connect=replicaSet&slaveOk=true&replicaSet=myrs

    注意:主机必须是副本集中所有的主机,包括主节点、副本节点、仲裁节点。
  完整的连接字符串的参考:

    MongoDB客户端连接语法

mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]

    mongodb:// 这是固定的格式,必须要指定。

    username:password@ 可选项,如果设置,在连接数据库服务器之后,驱动都会尝试登陆这个数据库

    host1 必须的指定至少一个host, host1 是这个URI唯一要填写的。它指定了要连接服务器的地址。如果要连接副本集,请指定多个主机地址。

    portX 可选的指定端口,如果不填,默认为27017

    /database 如果指定username:password@,连接并验证登陆指定数据库。若不指定,默认打开test 数据库。

    ?options 是连接选项。如果不使用/database,则前面需要加上/。所有连接选项都是键值对name=value,键值对之间通过&或;(分号)隔开

    选项(options):

      

springboot mongodb 新增数据时没有创建集合 spring.data.mongodb.uri_mongodb

 SpringDataMongDB 连接分片集群:

  其连接的是mongs路由,配置和单机mongod的配置是一样的。
  多个路由的时候的SpringDataMongoDB的客户端配置参考如下:

spring:
  #数据源配置
  data:
    mongodb:
      #主机地址
      #host: 192.168.43.182
      #数据库
      #database: articledb
      #默认端口是27017
      #port: 27017
      #副本集的连接字符串
      #uri: mongodb://192.168.43.182:27017,192.168.43.182:27018,192.168.43.182:27019/articledb?connect=replicaSet&slaveOk=true&replicaSet=myrs
      #连接路由字符串
      uri: mongodb://192.168.43.182:27017,192.168.43.182:27117/articledb