淘先锋技术网

首页 1 2 3 4 5 6 7

1、Spring Boot 与 MongoDB的集成配置

  1. 创建工程

    在spring-boot-nosql下创建spring-boot-nosql-mongodb工程
    在这里插入图片描述

    启动类:

    com.mirson.spring.boot.nosql.mongodb.startup.NosqlMongodbApplication:

    @SpringBootApplication
    @ComponentScan(basePackages = {"com.mirson"})
    @EnableMongoRepositories(basePackages = "com.mirson")
    public class NosqlMongodbApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(NosqlMongodbApplication.class, args);
        }
    
    }
    

    注意, 要使用MongoRepository功能, 需要开启EnableMongoRepositories注解, 扫描Repository接口。

  2. MAVEN依赖

    pom.xml

    <dependencies>
    
            <!-- MongoDB 依赖组件 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-mongodb</artifactId>
            </dependency>
    
            <!-- MongoDB Reactive 依赖组件 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
            </dependency>
    
            <!-- Json 转换组件 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.58</version>
            </dependency>
    
        </dependencies>
    

    这里需要用到JSON作参数数据转换, 引入fastjson组件。

  3. 工程配置

    application.yml文件:

2、MongoTemplate模式运用

  1. 创建实体

    com.mirson.spring.boot.nosql.mongodb.entity.Person:

    @Document(collection="person")
    @Data
    public class Person implements Serializable {
    
        private static final long serialVersionUID = -1L;
    
        @Id
        private String id;
    
        /**
         * 姓名
         */
        @Indexed(unique=true)
        private String name;
    
        /**
         * 年龄
         */
        private Integer age;
    
        /**
         * 省份
         */
        private String province;
    
        /**
         * 创建时间
         */
        @CreatedDate
        Date createDate;
    
    }
    
    • 定义一个用户实体用于测试, 包含姓名、年龄、省份和创建时间。
    • Document注解, 定义collection名称, 相当于数据库的表名。
    • Indexed注解, 建立索引, 提升检索速度, unique=true建立唯一索引。
    • CreatedDate注解, 定义时间, 结合EnableMongoAuditing注解, 新增记录的时候会自动生成当前时间。
  2. 定义CURD等接口

    • 接口定义

      com.mirson.spring.boot.nosql.mongodb.service.IMongoService

      public interface IMongoService {
      
          /**
           * 保存用户信息
           * @param person
           */
          public String save(Person person);
      
          /**
           * 删除用户
           * @param id
           */
          public void delete(String id);
      
      
          /**
           * 查询所有用户
           */
          public List<Person> find(String id);
      
          /**
           * 根据名称模糊查找
           * @param name
           * @return
           */
          public List<Person> findByName(String name);
      
      
          /**
           * 批量保存数据
           * @param personList
           * @return
           */
          public String batchSave(String opt, List<Person> personList);
      
      }
      
      

      覆盖常用的功能接口, 包括模糊匹配, 批量数据保存。

    • 接口实现

      com.mirson.spring.boot.nosql.mongodb.service.MongoTemplateServiceImpl

      @Service
      @Log4j2
      public class MongoTemplateServiceImpl implements IMongoService {
      
          @Autowired
          private MongoTemplate mongoTemplate;
      
          /**
           * 保存对象
           * @param person
           * @return
           */
          @Override
          public String save(Person person) {
              log.info("save person: " + person);
              Person result  = mongoTemplate.save(person);
              return result.getId();
          }
      
          /**
           * 根据ID删除对象
           * @param id
           */
          @Override
          public void delete(String id) {
              log.info("delete person: " + id);
              Query query = new Query(Criteria.where("id").is(id));
              mongoTemplate.remove(query, Person.class);
          }
      
          /**
           * 根据ID查找对象
           * @param id
           * @return
           */
          @Override
          public List<Person> find(String id) {
              log.info(" find person: " + id);
              if(StringUtils.isEmpty(id)){
                  // 为空, 查找所有对象
                  return mongoTemplate.findAll(Person.class);
              }
              // 查找指定对象
              Query query = new Query(Criteria.where("id").is(id));
              return mongoTemplate.find(query, Person.class);
      
          }
      
          /**
           * 根据名称查找对象, 支持模糊匹配
           * @param name
           * @return
           */
          @Override
          public List<Person> findByName(String name) {
              log.info(" findByName, name: " + name);
              Query query = new Query(Criteria.where("name").regex(name));
              return mongoTemplate.find(query, Person.class);
          }
      
          /**
           * 批量保存数据
           * @param personList
           * @return
           */
          @Transactional(rollbackFor = Exception.class)
          public String batchSave(String opt, List<Person> personList) {
              log.info("batchSave, personList: " + personList);
              if(null != personList && !personList.isEmpty()) {
                  // 遍历对象集合
                  for (int i= 0; i< personList.size(); i++) {
                      if(i == 1 && "exception".equals(opt)) {
                          // 手工触发异常, 验证事务有效性
                          throw new RuntimeException("throw manual exception!");
                      }
                      // 保存对象
                      mongoTemplate.save(personList.get(i));
                  }
                  return "batch save success.";
              }
      
              return "empty data.";
          }
      
      }
      
      
      • 根据ID查找对象, 如果ID为空, 则查询获取所有对象数据。

      • 根据名称查找对象, 支持模糊匹配, 通过regex接口实现, 可以支持更灵活的匹配:

        //完全匹配
        Pattern pattern = Pattern.compile("^用户$", Pattern.CASE_INSENSITIVE);
        //右匹配
        Pattern pattern = Pattern.compile("^.*用户$", Pattern.CASE_INSENSITIVE);
        //左匹配
        Pattern pattern = Pattern.compile("^用户.*$", Pattern.CASE_INSENSITIVE);
        //模糊匹配
        Pattern pattern = Pattern.compile("^.*用户.*$", Pattern.CASE_INSENSITIVE);
        Query query = Query.query(Criteria.where(fieldName).regex(pattern));  
        
      • batchSave 批量保存数据, 用到事务, 在MongoTransactionManager事务的使用章节再进行讲解。

    1. 提供Web层调用接口

      因为有几种不同模式的集成使用, 都提供相同的调用接口, 我们把它们做个封装, 不重复编写。

      定义抽象类com.mirson.spring.boot.nosql.mongodb.controller.AbstractController

      public abstract class AbstractController {
      
          /**
           * MongoDB接口操作实现类
           * @return
           */
          public abstract IMongoService getMongoService();
      
          /**
           * 保存用户
           * @param person
           * @return
           */
          @GetMapping("/save")
          public String save(Person person) {
              String id = getMongoService().save(person);
              return "save success. id: " + id;
          }
      
          /**
           * 删除用户
           * @param id
           * @return
           */
          @GetMapping("/delete")
          public String delete(String id) {
              getMongoService().delete(id);
              return "delete success.";
          }
      
          /**
           * 查找用户
           * @param id
           * @return
           */
          @GetMapping("/find")
          @ResponseBody
          public List<Person> find(String id) {
              List<Person> personList = getMongoService().find(id);
              return personList;
          }
      
          /**
           * 根据名称查找, 支持模糊匹配
           * @param name
           * @return
           */
          @GetMapping("/findByName")
          @ResponseBody
          public List<Person> findByName(String name) {
              List<Person> personList = getMongoService().findByName(name);
              return personList;
          }
      
          /**
           * 批量保存, 事务验证
           * @param opt
           * @param personJson
           * @return
           */
          @PostMapping("/batchSave")
          @ResponseBody
          public String batchSave(String opt, String json) {
              List<Person> personList = JSON.parseArray(json,Person.class);
              return getMongoService().batchSave(opt, personList);
          }
      
      }
      
      

      将服务层的接口,提供对外访问调用, 因为所有服务层实现IMongoService接口, 在不同模式下提供getMongoService()方法的具体实现即可。这里父类定义好各接口的访问路径, 子类中再定义@RequestMapping加以前缀识别。

      com.mirson.spring.boot.nosql.mongodb.controller.MongoTemplateController:

      @RestController
      @RequestMapping("/template")
      @Log4j2
      public class MongoTemplateController extends AbstractController{
      
          @Autowired
          private IMongoService mongoTemplateServiceImpl;
      
          @Override
          public IMongoService getMongoService() {
              return mongoTemplateServiceImpl;
          }
      }
      
      

      MongoTemplateController注入mongoTemplateServiceImpl, 实现getMongoService方法。

      RequestMapping定义访问路径要加上/template。

    2. 验证

      • 测试新增功能

        新增一个名为user1, 年龄为21, 省份为江西省的记录

        URL: /template/save?name=user1&age=21&province=江西省
        在这里插入图片描述

        保存成功, 返回ID: 5d7791f55c72e7242ce8ded8

      • 测试更新功能

        调用保存接口, 当传入参数包含ID时, 会自动更新对应记录。

        将年龄由21改为31
        在这里插入图片描述

        更新成功, 查看compass中数据是否一致:
        在这里插入图片描述

        修改成功。

      • 测试删除功能

        将刚才创建的数据删除, 传入ID参数: 5d7791f55c72e7242ce8ded8
        在这里插入图片描述

        成功删除。

      • 测试查询功能

        通过上面测试方法, 重新创建数据, 创建新数据的时候不要指定ID参数。

        指定ID查询记录:

        URL: /template/find?id=5d7793c45c72e7242ce8deda
        在这里插入图片描述

        不传递ID, 查询所有记录:
        URL: /template/find

        在这里插入图片描述

      • 测试模糊查询

        检索所有名称为user的记录

      URL: /template/findByName?name=user
      在这里插入图片描述

      检索所有名称为test的记录, 没有新增此类数据, 查询应为空
      在这里插入图片描述

3、MongoRepository模式运用

  1. 定义JPA接口

    com.mirson.spring.boot.nosql.mongodb.repository.IPersonMongoDao

    @Repository
    public interface IPersonMongoDao extends MongoRepository<Person, String> {
    
        /**
         * 根据ID获取对象
         * @param id
         * @return
         */
        Optional<Person> findById(String id);
    
        /**
         * 根据名称模糊搜索
         * @param name
         * @param pageable
         * @return
         */
        Page<Person> findByNameLike(String name, Pageable pageable);
    
        /**
         * 获取所有对象
         * @param pageable
         * @return
         */
        Page<Person> findAll(Pageable pageable);
    
    }
    
    

    findByNameLike方法, 提供了模糊搜索支持和分页功能, 这些都是JPA内置帮我们实现, 更多用法:

    KeywordSampleLogical result
    AfterfindByBirthdateAfter(Date date){"birthdate" : {"$gt" : date}}
    GreaterThanfindByAgeGreaterThan(int age){"age" : {"$gt" : age}}
    GreaterThanEqualfindByAgeGreaterThanEqual(int age){"age" : {"$gte" : age}}
    BeforefindByBirthdateBefore(Date date){"birthdate" : {"$lt" : date}}
    LessThanfindByAgeLessThan(int age){"age" : {"$lt" : age}}
    LessThanEqualfindByAgeLessThanEqual(int age){"age" : {"$lte" : age}}
    BetweenfindByAgeBetween(int from, int to){"age" : {"$gt" : from, "$lt" : to}}
    InfindByAgeIn(Collection ages){"age" : {"$in" : [ages…]}}
    NotInfindByAgeNotIn(Collection ages){"age" : {"$nin" : [ages…]}}
    IsNotNull, NotNullfindByFirstnameNotNull(){"firstname" : {"$ne" : null}}
    IsNull, NullfindByFirstnameNull(){"firstname" : null}
    Like, StartingWith, EndingWithfindByFirstnameLike(String name){"firstname" : name} (name as regex)
    NotLike, IsNotLikefindByFirstnameNotLike(String name){"firstname" : { "$not" : name }} (name as regex)
    Containing on StringfindByFirstnameContaining(String name){"firstname" : name} (name as regex)
    NotContaining on StringfindByFirstnameNotContaining(String name){"firstname" : { "$not" : name}} (name as regex)
    Containing on CollectionfindByAddressesContaining(Address address){"addresses" : { "$in" : address}}
    NotContaining on CollectionfindByAddressesNotContaining(Address address){"addresses" : { "$not" : { "$in" : address}}}
    RegexfindByFirstnameRegex(String firstname){"firstname" : {"$regex" : firstname }}
    (No keyword)findByFirstname(String name){"firstname" : name}
    NotfindByFirstnameNot(String name){"firstname" : {"$ne" : name}}
    NearfindByLocationNear(Point point){"location" : {"$near" : [x,y]}}
    NearfindByLocationNear(Point point, Distance max){"location" : {"$near" : [x,y], "$maxDistance" : max}}
    NearfindByLocationNear(Point point, Distance min, Distance max){"location" : {"$near" : [x,y], "$minDistance" : min, "$maxDistance" : max}}
    WithinfindByLocationWithin(Circle circle){"location" : {"$geoWithin" : {"$center" : [ [x, y], distance]}}}
    WithinfindByLocationWithin(Box box){"location" : {"$geoWithin" : {"$box" : [ [x1, y1], x2, y2]}}}
    IsTrue, TruefindByActiveIsTrue(){"active" : true}
    IsFalse, FalsefindByActiveIsFalse(){"active" : false}
    ExistsfindByLocationExists(boolean exists){"location" : {"$exists" : exists }}

    MongoDBRepository所提供的不同功能的操作接口:

    Repository: 仅仅是一个标识,表明任何继承它的均为仓库接口类
    CrudRepository: 继承 Repository,实现了一组 CRUD 相关的方法
    PagingAndSortingRepository: 继承 CrudRepository,实现了一组分页排序相关的方法
    MongoRepository: 继承 PagingAndSortingRepository,实现一组 mongodb规范相关的方法

  2. 定义Service实现类

    com.mirson.spring.boot.nosql.mongodb.service.MongoRepositoryServiceImpl

    @Service
    @Log4j2
    public class MongoRepositoryServiceImpl implements IMongoService{
    
        @Autowired
        private IPersonMongoDao personMongoDao;
    
        /**
         * 保存对象
         * @param person
         * @return
         */
        @Override
        public String save(Person person) {
            log.info("repository save person: " + person);
            Person result = personMongoDao.save(person);
            return result.getId();
        }
    
        /**
         * 根据ID删除对象
         * @param id
         */
        @Override
        public void delete(String id) {
            personMongoDao.deleteById(id);
            log.info("repository delete person, id: " + id);
        }
    
        /**
         * 根据ID查找对象
         * @param id
         * @return
         */
        @Override
        public List<Person> find(String id) {
            log.info("repository find person, id: " + id);
            if(!StringUtils.isEmpty(id)) {
                // 根据ID查询
                Optional<Person> personOptional = personMongoDao.findById(id);
                if(personOptional.isPresent()) {
                    return Arrays.asList(personOptional.get());
                }
            }else {
                // 获取所有对象, 支持分页查询
                Pageable pageable = new PageRequest(0, 100);
                Page<Person> personPage = personMongoDao.findAll(pageable);
                return personPage.getContent();
            }
            return null;
        }
    
        /**
         * 根据名称查找对象, 支持模糊匹配
         * @param name
         * @return
         */
        @Override
        public List<Person> findByName(String name) {
            log.info("repository findByName, name: " + name);
            Pageable pageable = new PageRequest(0, 100);
            Page<Person> personPage = personMongoDao.findByNameLike(name, pageable);
            return personPage.getContent();
        }
    
        /**
         * 批量保存数据
         * @param personList
         * @return
         */
        @Transactional(rollbackFor = Exception.class)
        public String batchSave(String opt, List<Person> personList) {
            log.info("repository batchSave, personList: " + personList);
            if(null != personList && !personList.isEmpty()) {
                // 遍历对象集合
                for (int i= 0; i< personList.size(); i++) {
                    if(i == 1 && "exception".equals(opt)) {
                        // 手工触发异常, 验证事务有效性
                        throw new RuntimeException("throw manual exception!");
                    }
                    // 保存对象
                    personMongoDao.save(personList.get(i));
                }
                return "batch save success.";
            }
    
            return "empty data.";
        }
    
    }
    

    根据名称模糊搜索, 调用内置的LIKE接口, 帮我们封装实现了与LIKE类似的模糊匹配功能, 这里加上Pageable参数, 是演示Pageable的用法, 实际工作中, 会对分页的计算做进一步封装, 这里不作详解。

  3. 定义Web层访问接口

    com.mirson.spring.boot.nosql.mongodb.controller.MongoRepositoryController

    @RestController
    @RequestMapping("/repository")
    public class MongoRepositoryController extends AbstractController{
    
        @Autowired
        private IMongoService mongoRepositoryServiceImpl;
    
        @Override
        public IMongoService getMongoService() {
            return mongoRepositoryServiceImpl;
        }
    
    }
    
    

    注入类的名称为mongoRepositoryServiceImpl, 不能写错, 因为有多个实现类, 调用时可以观察日志检查处理类有无配置错误。

  4. 功能验证

    • 保存功能
      在这里插入图片描述

      控制台日志, 正确进入Repository模式处理:

      在这里插入图片描述

    • 删除功能

      在这里插入图片描述

    • 查询功能

      在这里插入图片描述

    • 模糊查询

      在这里插入图片描述

4、MongoTransactionManager事务运用

  1. JAVA CONFIG配置

    使用MongoDB需要开启MongoTransactionManager事务管理器, 默认Spring Boot是不会加载注入。

    com.mirson.spring.boot.nosql.mongodb.config.MongodbConfiguration:

    @Configuration
    @EnableMongoAuditing
    public class MongodbConfiguration {
    
        /**
         * Transaction MongoDB 事务配置
         * @param dbFactory
         * @return
         */
        @Bean
        MongoTransactionManager transactionManager(MongoDbFactory dbFactory) {
            return new MongoTransactionManager(dbFactory);
        }
    
    }
    

    创建MongoTransactionManager, 纳入容器管理。

  2. Service层实现

    前面我们定义了batchSave方法, 这里我们把Template和Repository两种模式都实现事务测试接口进行验证。

    batchSave方法是批量保存用户数据, 事务验证需要模拟一个异常, 触发事务的回滚, 这里通过opt参数来控制, 如果传递值为"exception", 则手动抛出异常, 触发事务回滚机制。

    • Template模式实现类修改

      MongoTemplateServiceImpl:

      /**
           * 批量保存数据
           * @param personList
           * @return
           */
          @Transactional(rollbackFor = Exception.class)
          public String batchSave(String opt, List<Person> personList) {
              log.info("batchSave, personList: " + personList);
              if(null != personList && !personList.isEmpty()) {
                  // 遍历对象集合
                  for (int i= 0; i< personList.size(); i++) {
                      if(i == 1 && "exception".equals(opt)) {
                          // 手工触发异常, 验证事务有效性
                          throw new RuntimeException("throw manual exception!");
                      }
                      // 保存对象
                      mongoTemplate.save(personList.get(i));
                  }
                  return "batch save success.";
              }
      
              return "empty data.";
          }
      
    • Repository模式实现类修改

      MongoRepositoryServiceImpl

          /**
           * 批量保存数据
           * @param personList
           * @return
           */
          @Transactional(rollbackFor = Exception.class)
          public String batchSave(String opt, List<Person> personList) {
              log.info("repository batchSave, personList: " + personList);
              if(null != personList && !personList.isEmpty()) {
                  // 遍历对象集合
                  for (int i= 0; i< personList.size(); i++) {
                      if(i == 1 && "exception".equals(opt)) {
                          // 手工触发异常, 验证事务有效性
                          throw new RuntimeException("throw manual exception!");
                      }
                      // 保存对象
                      personMongoDao.save(personList.get(i));
                  }
                  return "batch save success.";
              }
      
              return "empty data.";
          }
      
  3. WEB层接口

    AbstractController

        /**
         * 批量保存, 事务验证
         * @param opt
         * @param personJson
         * @return
         */
        @PostMapping("/batchSave")
        @ResponseBody
        public String batchSave(String opt, String json) {
            List<Person> personList = JSON.parseArray(json,Person.class);
            return getMongoService().batchSave(opt, personList);
        }
    

    提供两个参数opt, 用于控制是否抛出异常; 另一个json参数是以JSON格式传递多个Person对象, 通过fastjson组件将json字符串转换为对象。

  4. 事务功能验证

    • 为便于演示, 先清除所有数据

      如果数据过多, 可以通过Compass工具,直接将数据库删除, 程序重新启动会自动创建数据库和表。

      在这里插入图片描述

    • Template模式,验证批量保存(不抛出异常)

      在这里插入图片描述

      查询数据:

      在这里插入图片描述

    • Template模式,先清除所有测试数据, 验证批量保存(模拟抛出异常)

      在这里插入图片描述

      查询数据:

      在这里插入图片描述

    • Repository模式, 验证批量保存(不抛出异常, 测试前清除所有数据)

      在这里插入图片描述

      查询数据:

      在这里插入图片描述

    • Repository模式,验证批量保存(模拟抛出异常)。

      在这里插入图片描述

      查询数据:

      在这里插入图片描述

5、ReactiveMongoTemplate响应模式运用

  1. 定义Service层接口

    com.mirson.spring.boot.nosql.mongodb.service.MongoReactiveServiceImpl

    @Service
    @Log4j2
    public class MongoReactiveServiceImpl implements IMongoService {
        
        @Autowired
        private ReactiveMongoTemplate reactiveMongoTemplate;
    
        /**
         * 保存对象
         * @param person
         * @return
         */
        @Override
        public String save(Person person) {
            Mono<Person> result  = reactiveMongoTemplate.save(person);
            result.subscribe(log::info);
            log.info("Reactive save person: " + person);
            return result.block().getId();
        }
    
        /**
         * 根据ID删除对象
         * @param id
         */
        @Override
        public void delete(String id) {
            Query query = new Query(Criteria.where("id").is(id));
            Mono<DeleteResult> result = reactiveMongoTemplate.remove(query, Person.class);
            result.subscribe(log::info);
            log.info("Reactive delete person: " + id);
    
        }
    
        /**
         * 根据ID查找对象
         * @param id
         * @return
         */
        @Override
        public List<Person> find(String id) {
            log.info("Reactive find person: " + id);
            if(StringUtils.isEmpty(id)){
                // 为空, 查找所有对象
                Flux<Person> result = reactiveMongoTemplate.findAll(Person.class);
                return result.collectList().block();
            }
            // 查找指定对象
            Query query = new Query(Criteria.where("id").is(id));
            Flux<Person> result = reactiveMongoTemplate.find(query, Person.class);
            return result.collectList().block();
    
        }
    
        /**
         * 根据名称查找对象, 支持模糊匹配
         * @param name
         * @return
         */
        @Override
        public List<Person> findByName(String name) {
            log.info("Reactive findByName, name: " + name);
            Query query = new Query(Criteria.where("name").regex(name));
            Flux<Person> result = reactiveMongoTemplate.find(query, Person.class);
            return result.collectList().block();
        }
    
        /**
         * 批量保存数据
         * @param personList
         * @return
         */
        @Transactional(rollbackFor = Exception.class)
        public String batchSave(String opt, List<Person> personList) {
            log.info("Reactive batchSave, personList: " + personList);
            if(null != personList && !personList.isEmpty()) {
                // 遍历对象集合
                for (int i= 0; i< personList.size(); i++) {
                    if(i == 1 && "exception".equals(opt)) {
                        // 手工触发异常, 验证事务有效性
                        throw new RuntimeException("throw manual exception!");
                    }
                    // 保存对象
                    Mono<Person> result  = reactiveMongoTemplate.save(personList.get(i));
                    result.block();
                }
                return "Reactive batch save success.";
            }
    
            return "Reactive empty data.";
        }
    
    }
    

    使用Reactive模式, 确保加入spring-boot-starter-data-mongodb-reactive依赖, 该组件会自动装配ReactiveMongoTemplate。Reactive支持阻塞和异步调用, 通过日志打印可以看出其异步特性。

  2. 定义WEB层接口

    com.mirson.spring.boot.nosql.mongodb.controller.MongoReactiveController

    @RestController
    @RequestMapping("/reactive")
    public class MongoReactiveController extends AbstractController {
    
        @Autowired
        private IMongoService mongoReactiveServiceImpl;
    
        @Override
        public IMongoService getMongoService() {
            return mongoReactiveServiceImpl;
        }
    
    }
    
    

    继承AbstractController所提供的接口, 定义RequestMapping路径为“/reactive”。

  3. 验证

    • 保存数据

      在这里插入图片描述

    • 删除数据

      在这里插入图片描述

    • 查询数据

      在这里插入图片描述

    • 模糊查询

      在这里插入图片描述

    • 异步操作日志

      通过刚才调用删除接口的日志打印, 可以看出为Reactive的异步操作特性。

      在这里插入图片描述

6、总结

  • Spring Boot Data MongoDB 集成使用, 主要包含模板模式,JPA Repository 模式和响应模式。 在一般情况下, 采用模板模式即可满足需要, 如果需要用到事务, 查询复杂, 操作量大的话可以采用JPA模式。 交互频繁的场景性下, 建议自定义封装连接池使用, 提升性能与稳定性。
  • MongoDB 有着较高的读性能, 但写性能比较低下, 差距有15倍之多,在使用事务时,多文档事务相对于单文档数据变更性能损耗会更严重,从业务或设计上, 尽量减少多文档事务的使用。