SpringBoot中使用MongoDB

目录

搭建实体类

基本的增删改查操作

分页查询

使用MongoTemplate实现复杂的功能


引入依赖

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

在application.yml中写配资

spring:
  data:
    mongodb:
      # 主机地址
      host: 47.115.217.159
      # 端口
      port: 27017
      # 数据库名称
      database: test

启动项目,如果成功启动,说明基础配资没有问题

搭建实体类

MongoDB中的集合结构

字段名称字段含义字段类型备注
_idIDObjectId或StringMongo的主键字段,唯一标识每条评论记录
articleid文章IDString评论所属文章的唯一标识符
content评论内容String用户发表的评论内容
userid评论人IDString发表评论的用户的唯一标识符
nickname评论人昵称String发表评论的用户昵称
createdatetime评论的日期时间Date评论创建的时间戳
likenum点赞数Int32评论获得的点赞数量
replynum回复数Int32评论收到的回复数量
state状态String评论的状态,"0"表示不可见,"1"表示可见
parentid上级IDString如果为"0",表示这是文章的顶级评论;否则,表示这是对另一条评论的回复

实体类

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
/**
 * 文章评论实体类
 */
//把一个java类声明为mongodb的文档,可以通过collection参数指定这个类对应的文档。
//@Document(collection="mongodb 对应 collection 名")
@Document(collection="comment")//可以省略,如果省略,则默认使用类名小写映射集合
//复合索引
// @CompoundIndex( def = "{'userid': 1, 'nickname': -1}")
@Data
@ToString
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;
}

说明:

索引可以大大提升查询效率,一般在查询字段上添加索引,索引的添加可以通过Mongo的命令来添加,也可以在Java的实体类中通过注解添加。

1)单字段索引注解@Indexed

声明该字段需要索引,建索引可以大大的提高查询效率。

2)复合索引注解@CompoundIndex

复合索引的声明,建复合索引可以有效地提高多字段的查询效率。

基本的增删改查操作

(1)创建数据访问接口 

public interface CommentDao extends MongoRepository<Comment,String> {
}

MongoRepository这个类它封装了很多基本的MongoDB操作,类似于关系型数据库的mybatis-plus。

(2)创建业务逻辑类

@Service
public class CommentService {

    //注入dao
    @Autowired
    private CommentDao commentDao;
    /**
     * 保存一个评论
     * @param comment
     */
    public void saveComment(Comment comment){
    //如果需要自定义主键,可以在这里指定主键;如果不指定主键,MongoDB会自动生成主键
    //设置一些默认初始值。。。
    //调用dao
        commentDao.save(comment);
    }
    /**
     * 更新评论
     * @param comment
     */
    public void updateComment(Comment comment){
        //调用dao
        commentDao.save(comment);
    }
    /**
     * 根据id删除评论
     * @param id
     */
    public void deleteCommentById(String id){
        //调用dao
        commentDao.deleteById(id);
    }
    /**
     * 查询所有评论
     * @return
     */
    public List<Comment> findCommentList(){
        //调用dao
        return commentDao.findAll();
    }
    /**
     * 根据id查询评论
     * @param id
     * @return
     */
    public Comment findCommentById(String id){
        //调用dao
        return commentDao.findById(id).get();
    }
    
}

(3)新建测试类,测试保存和查询所有:

@SpringBootTest
class ApplicationTests {


	//注入Service
	@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();
		for (Comment comment : list) {
			System.out.println(comment);
		}
	}
	/**
	 * 测试根据id查询
	 */
	@Test
	public void testFindCommentById(){
		Comment comment = commentService.findCommentById("1");
		System.out.println(comment);
	}


}

保存评论测试结果:

查询所有评论测试结果

根据Id查询测试结果

分页查询

需求:查询UserId相同的全部数据,并且分页显示

实现:

(1)CommentDao新增方法定义

@Repository
public interface CommentDao extends MongoRepository<Comment,String> {
    Page<Comment> findAllByUserid(String userid, Pageable pageable);
}

这里面定义方法必须按照指定的格式来定义,比如想要查询方法,就需要以findBy开头,By后面的要与形参的第一个参数名称相同。

(2)CommentService新增方法

public Page<Comment> findCommentByUserId(String id,int page, int size){
    return commentDao.findAllByUserid(id,PageRequest.of(page-1, size));
}

(3)测试用例

    @Test
	public void testFindCommentListPageByParentid(){
		Page<Comment> pageResponse = commentService.findCommentByUserId( "1003",1, 2);
		System.out.println("----总记录数:"+pageResponse.getTotalElements());
		System.out.println("----当前页数据:");
		for (Comment comment : pageResponse.getContent()) {
			System.out.println(comment);
		}
	}

运行结果

使用MongoTemplate实现复杂的功能

前面MongoDB自动提供的那些功能都比较基础,功能都比较单一,如果要实现功能性复杂一点的语句,就需要借助MongoTemplate来实现。

需求:将指定id的likenum加1

根据上面的基本功能实现

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

以上方法虽然实现起来比较简单,但是执行效率并不高,因为我只需要将点赞数加1就可以了,没必要查询出所有字段修改后再更新所有字段。

所以使用MongoTemplate实现

实现:

(1)修改CommentService

    @Autowired
    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");
    }

(2)测试

    @Test
	public void testUpdateCommentLikenum(){
		//对3号文档的点赞数+1
		System.out.println("修改之前的数据:");
		System.out.println(commentService.findCommentById("3").getLikenum());
		commentService.updateCommentLikenum("3");
		System.out.println("修改之后的数据:");
		System.out.println(commentService.findCommentById("3").getLikenum());
	}

运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值