0
点赞
收藏
分享

微信扫一扫

【MongoDB】3. springboot整合MongoDB实战测试

圣杰 2022-01-24 阅读 202

1. 假装这是个前言

在前面的博客中我写了MongoDB Shell基本指令操作,而在开发中,我们通常是用代码去操作数据库的,对于java来说有许多的方式去操作数据库,一个是用Java原生的JDBC接口,要去下载MongoDB的jdbc驱动包,但我们开发往往不会使用原生的jdbc,原生的jdbc每一次操作都得自己建立起连接,想要细细了解MongoDB的jdbc驱动的可以点这个MongoDB Driver官方帮助文档进行学习,所以我们这一篇博客,写的是用springboot去整合MongoDB,springboot里面自带了一个MongoDB的依赖,叫spring-data-mongo

2. 演示

2.1 导入依赖

导入spring-data-mongodb依赖

        <!--MongoDb依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
            <version>2.6.2</version>
        </dependency>

目录结构如下
在这里插入图片描述

2.2 编写配置文件

编写配置文件application.yaml

spring:
  data:
    mongodb:
      host: localhost
      port: 27017
      database: test
#      我这里的数据库没有设用户名和密码,所以密码和用户名就没指定了
#      也可以用下面这种方式写,效果等同于上面的host port database分开写的效果
#      uri: mongodb://localhost:27017/person
server:
  port: 8888

2.3 编写映射实体类

PersonInfo.java

package edu.jsu.mongodemo.pojo.dto;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

import java.io.Serializable;
import java.util.List;

/**
 * @author Mo
 * @createTime 2022/1/20 15:41
 * @description
 */
@Data
@Document(collection = "person")
public class PersonInfo implements Serializable {
    //  标记主键
    @Id
    private String  id;
    //  标记字段
    @Field
    private String name;
    //  可以映射数据库内字段名称
    @Field(value = "score_list")
    private List<SubjectScore> subjectScoreList;
}

SubjectScore.java

package edu.jsu.mongodemo.pojo.dto;

import org.springframework.data.mongodb.core.mapping.Field;

/**
 * @author Mo
 * @createTime 2022/1/23 15:43
 * @description
 */
@Data
public class SubjectScore {
    @Field("subject_name")
    private String subjectName;
    private Double score;
}

2.4 CRUD编写

2.4.1 Bson文档格式

/* 1 */
{
    "_id" : ObjectId("61ed0eafc2da593110662f7e"),
    "name" : "mo",
    "scoreList" : [ 
        {
            "subjectName" : "语文",
            "score" : 83
        }, 
        {
            "subjectName" : "数学",
            "score" : 150
        }, 
        {
            "subjectName" : "英语",
            "score" : 666
        }
    ],
    "_class" : "edu.jsu.mongodemo.pojo.dto.PersonInfo"
}

/* 2 */
{
    "_id" : ObjectId("61ed5c816d978a6bfe8b50a3"),
    "name" : "C4ptainMo",
    "scoreList" : [ 
        {
            "subjectName" : "语文",
            "score" : 104
        }, 
        {
            "subjectName" : "数学",
            "score" : 114
        }, 
        {
            "subjectName" : "英语",
            "score" : 118
        }
    ],
    "_class" : "edu.jsu.mongodemo.pojo.dto.PersonInfo"
}

/* 3 */
{
    "_id" : ObjectId("61ed5cb36d978a6bfe8b50a4"),
    "name" : "ProphetMo",
    "scoreList" : [ 
        {
            "subjectName" : "语文",
            "score" : 104
        }, 
        {
            "subjectName" : "数学",
            "score" : 99
        }, 
        {
            "subjectName" : "英语",
            "score" : 134
        }
    ],
    "_class" : "edu.jsu.mongodemo.pojo.dto.PersonInfo"
}

2.4.2 Controller层

package edu.jsu.mongodemo.controller;

import edu.jsu.mongodemo.pojo.dto.PersonInfo;
import edu.jsu.mongodemo.pojo.vo.CommonResult;
import edu.jsu.mongodemo.service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * @author Mo
 * @createTime 2022/1/20 23:23
 * @description
 */
@RestController
@RequestMapping("/test")
public class TestController {
    @Autowired
    private TestService testService;

    @PostMapping("/add")
    public CommonResult addPerson(@RequestBody PersonInfo personInfo) {
        return testService.addPerson(personInfo);
    }

    @PostMapping("/delete")
    public CommonResult deletePerson(@RequestParam("Id")String Id) {
        return testService.deletePerson(Id);
    }

    @PostMapping("/updateScore")
    public CommonResult updatePersonScore(@RequestParam("Id")String Id, @RequestParam("score")Integer score) {
        return testService.updatePersonScore(Id, score);
    }

    @GetMapping("/queryAllPerson")
    public CommonResult queryAllPerson() {
        return testService.queryPersonList();
    }

    @PostMapping("/queryById")
    public CommonResult queryPersonById(@RequestParam("Id")String Id) {
        return testService.queryPersonById(Id);
    }
}

2.4.2 Service层

因为是演示,我就直接把实现写在Service里面了

package edu.jsu.mongodemo.service;

import edu.jsu.mongodemo.dao.TestDao;
import edu.jsu.mongodemo.pojo.dto.PersonInfo;
import edu.jsu.mongodemo.pojo.vo.CommonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author Mo
 * @createTime 2022/1/21 0:51
 * @descripton
 */
@Service
public class TestService {
    @Autowired
    private TestDao testDao;

    public CommonResult addPerson(PersonInfo personInfo) {
        testDao.addPerson(personInfo);
        return new CommonResult(200, "添加成功");
    }

    public CommonResult deletePerson(String Id) {
        testDao.deletePerson(Id);
        return new CommonResult(200, "删除成功");
    }

    public CommonResult updatePersonScore(String Id, Integer score) {
         testDao.updatePersonScore(Id, score);
         return new CommonResult(200, "修改成功");
    }

    public CommonResult queryPersonById(String Id) {
        return new CommonResult(200, "查询成功", testDao.findPersonById(Id));
    }

    public CommonResult queryPersonList() {
        return new CommonResult(200, "查询成功", testDao.queryPersonList());
    }
}

2.4.3 dao层编写

package edu.jsu.mongodemo.dao;

import edu.jsu.mongodemo.pojo.dto.PersonInfo;

import java.util.List;

/**
 * @author Mo
 * @createTime 2022/1/22 16:07
 * @description 使用mongodbTemplate进行数据操作,适合复杂的数据操作,推荐使用
 */
public interface TestDao {
    void addPerson(PersonInfo personInfo);

    void deletePerson(String id);

    void updatePersonScore(String id, Integer score, String subjectName);

    List<PersonInfo> queryPersonList();

    PersonInfo findPersonById(String id);
}

dao层实现层

package edu.jsu.mongodemo.dao.daoImpl;

import com.mongodb.client.result.UpdateResult;
import edu.jsu.mongodemo.dao.TestDao;
import edu.jsu.mongodemo.pojo.dto.PersonInfo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;

import java.io.Serializable;
import java.util.List;

/**
 * @author Mo
 * @createTime 2022/1/22 16:07
 * @description
 */
@Repository
public class TestDaoImpl implements TestDao {
    @Autowired
    private MongoTemplate mongoTemplate;

    private static final Log log = LogFactory.getLog(TestDaoImpl.class);

    @Override
    public void addPerson(PersonInfo personInfo) {
//        有两种mongoTemplate提供的CRUD方法,
//        一套需要指明操作的集合,一套不需要指明,
//        根据传入映射对象的注释来判断,
//        例如PersonInfo类,如果没有@Document注释那么默认为类名作为集合名插入
//        mongoTemplate.insert(personInfo);
        Serializable person1 = mongoTemplate.insert(personInfo, "person");
        //  输出序列化对象
        log.info(person1);
    }

    @Override
    public void deletePerson(String id) {
        Serializable andRemove = mongoTemplate.findAndRemove(Query.query(
                Criteria.where("id").is(id)
        ), PersonInfo.class, "person");
        log.info(andRemove);
    }

    @Override
    public void updatePersonScore(String id, Integer score, String subjectName) {
        Query query = new Query(Criteria.where("id").is(id)
                //  在查询里面写出子查询条件
                .and("scoreList.subjectName").is(subjectName));
        //  这个update方法相当于一个静态工厂,会生成一个Update对象,并执行set方法,上面的那个Criteria.where()同理
        Update update = Update.update("scoreList.$.score", score);

        //  写法1
        PersonInfo oldPersonInfo = mongoTemplate.update(PersonInfo.class)
                //  匹配符合query的对象
                .matching(query)
                //  修改操作
                .apply(update)
                //  执行
                .findAndModifyValue();
        //  输出执行修改前的数据
        log.info("old PersonInfo: " + oldPersonInfo);

        PersonInfo newPersonInfo = mongoTemplate.query(PersonInfo.class)
                .matching(query)
                .oneValue();
        //  输出修改后的数据
        log.info("new PersonInfo: " + newPersonInfo);
        PersonInfo personInfo = mongoTemplate.update(PersonInfo.class)
                .matching(query)
                .apply(Update.update("scoreList.$.score", 100))
                //  用这个可以添加修改时的选项,这里是返回修改后的值,区别于上面那个修改
                .withOptions(FindAndModifyOptions.options().returnNew(true))
                .findAndModifyValue();
        log.info("optional update result: " + personInfo);

        //  写法2
        UpdateResult updateResult = mongoTemplate.updateFirst(query, Update.update("scoreList.$.score", 666), PersonInfo.class);
        log.info("update result: " + updateResult);
    }

    @Override
    public List<PersonInfo> queryPersonList() {
        List<PersonInfo> personInfoList = mongoTemplate.findAll(PersonInfo.class, "person");
        log.info("queried PersonInfoList: " + personInfoList);
        return personInfoList;
    }

    @Override
    public PersonInfo findPersonById(String id) {
        PersonInfo one = mongoTemplate.findOne(Query.query(Criteria.where("id").is(id)), PersonInfo.class, "person");
        log.info(one);
        return one;
    }
}

期间遇到了许多问题,比如说集合里面的名字命名规范最好不要有下划线“_”,不然无法识别会报错,再然后就是文档的子嵌套查询,查询方式可以看我写的更新操作,我一直在想那个update的filterArray()方法咋用,在StackOverflow上也找了半天,下次等有时间去好好看看官方文档,不过最后还是解决了这个问题,在Query里面就限定好要查询的内容就行,被这么个问题卡这么久,血压都升上来了。

至此,spring-data-mongodb已经入门上手了,还有个分页查询我没写着里面来,等下次有时间再更新下分页查询的写法,其实也很简单就是query().skip(/ 跳过的数据数 /).limit(/每一页的数据量/)这样就实现了分页查询哈哈哈哈哈,下次详细说说,溜了

举报

相关推荐

0 条评论