美文网首页
SpringBoot MongoDB 整合

SpringBoot MongoDB 整合

作者: 赛亚人之神 | 来源:发表于2018-10-18 21:09 被阅读100次

    添加 Maven 依赖

          <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
            <version>${springboot.version}</version>
          </dependency>
    

    去除自动化配置

    @SpringBootApplication(exclude = {
        DataSourceAutoConfiguration.class,
        MybatisAutoConfiguration.class,
        MapperAutoConfiguration.class,
        PageHelperAutoConfiguration.class,
        RabbitAutoConfiguration.class,
        MongoAutoConfiguration.class,
    
    //    SecurityAutoConfiguration.class
    })
    
    1. 配置 MongoDbFactory
    @Bean
      public MongoDbFactory mongoDbFactory() throws UnknownHostException {
    
        MongoClientURI mongoClientURI = new MongoClientURI(mongoDbProperties.getUri());
        MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoClientURI);
    
        return mongoDbFactory;
      }
    
    1. 配置模板方法 MongoTemplate
    @Bean
      public MongoTemplate mongoTemplate() throws UnknownHostException {
    //    MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());
        MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), mappingMongoConverter());
    
        return mongoTemplate;
      }
    
    1. spring-data-mongodbTypeConverterdomain objects 映射为 DBObject时会自动给 Document添加一个 _class
      spring-data-mongodb 是为了在把 Document 转换成 Java 对象时能够转换到具体的子类
    /**
       * 调用 mongoTemplate 的save方法时
       * spring-data-mongodb 的 TypeConverter 会自动给 Document 添加一个 _class
       * spring-data-mongodb 是为了在把 Document 转换成 Java 对象时能够转换到具体的子类
       * @return
       * @throws UnknownHostException
       */
      @Bean
      public MappingMongoConverter mappingMongoConverter() throws UnknownHostException {
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory());
        MongoMappingContext mappingContext = new MongoMappingContext();
        mappingContext.setApplicationContext(applicationContext);
    
        MappingMongoConverter mappingMongoConverter = new MappingMongoConverter(dbRefResolver, mappingContext);
    //    CustomConversions conversions = new CustomConversions(null);
    //    mappingMongoConverter.setCustomConversions(conversions);
    // 设置为 null,防止添加 _class
        mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
        return mappingMongoConverter;
      }
    

    完整 MongoConfiguration 配置如下

    @Configuration
    @EnableMongoRepositories(basePackages = {MongoConfiguration.BASE_PACKAGES})
    public class MongoConfiguration {
    
      public static final String BASE_PACKAGES = "com.magic.platform.**.mongo.dao";
    
      @Autowired
      private MongoDbProperties mongoDbProperties;
    
      @Autowired
      private ApplicationContext applicationContext;
    
    
      @Bean
      public MongoDbFactory mongoDbFactory() throws UnknownHostException {
    
        MongoClientURI mongoClientURI = new MongoClientURI(mongoDbProperties.getUri());
        MongoDbFactory mongoDbFactory = new SimpleMongoDbFactory(mongoClientURI);
    
        return mongoDbFactory;
      }
    
      /**
       * 调用 mongoTemplate 的save方法时
       * spring-data-mongodb 的 TypeConverter 会自动给 Document 添加一个 _class
       * spring-data-mongodb 是为了在把 Document 转换成 Java 对象时能够转换到具体的子类
       * @return
       * @throws UnknownHostException
       */
      @Bean
      public MappingMongoConverter mappingMongoConverter() throws UnknownHostException {
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory());
        MongoMappingContext mappingContext = new MongoMappingContext();
        mappingContext.setApplicationContext(applicationContext);
    
        MappingMongoConverter mappingMongoConverter = new MappingMongoConverter(dbRefResolver, mappingContext);
    //    CustomConversions conversions = new CustomConversions(null);
    //    mappingMongoConverter.setCustomConversions(conversions);
    
        mappingMongoConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
        return mappingMongoConverter;
      }
    
      @Bean
      public MongoTemplate mongoTemplate() throws UnknownHostException {
    //    MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());
        MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), mappingMongoConverter());
    
        return mongoTemplate;
      }
    
      /**
       * 设置 mongodb page helper 工具类
       * @return
       * @throws UnknownHostException
       */
      @Bean
      public MongoPageHelper mongoPageHelper() throws UnknownHostException {
        return new MongoPageHelper(mongoTemplate());
      }
    
    
    }
    

    MongoDbProperties 配置

    @Data
    @Configuration
    @ConfigurationProperties(prefix = "mongo")
    @PropertySource(value = "classpath:env/mongodb.properties", ignoreResourceNotFound = true, encoding = "UTF-8")
    public class MongoDbProperties {
    
      private String uri = "mongodb://localhost/test";
    
    }
    

    mongodb.properties 配置

    mongodb.uri=mongodb://localhost/test
    

    附录:MongoPageHelper 分页工具

    @Component
    public class MongoPageHelper {
    
      public static final int FIRST_PAGE_NUM = 1;
      public static final String ID = "_id";
    
      private final MongoTemplate mongoTemplate;
    
      @Autowired
      public MongoPageHelper(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
      }
    
      /**
       * 分页查询,直接返回集合类型的结果.
       */
      public <T> MongoPageResult<T> pageQuery(Query query, Class<T> entityClass,  Integer pageNum, Integer pageSize) {
        return pageQuery(query, entityClass, Function.identity(), pageNum, pageSize, null);
      }
    
      /**
       * 分页查询,不考虑条件分页,直接使用skip-limit来分页
       */
      public <T, R> MongoPageResult<R> pageQuery(Query query, Class<T> entityClass, Function<T, R> mapper,  Integer pageNum, Integer pageSize) {
        return pageQuery(query, entityClass, mapper, pageNum, pageSize, null);
      }
    
      /**
       *
       * @param query Mongo Query对象,构造你自己的查询条件
       * @param entityClass Mongo collection 定义的 entity class,用来确定查询哪个集合
       * @param mapper 映射器,你从db查出来的list的元素类型是entityClass, 如果你想要转换成另一个对象,比如去掉敏感字段等,可以使用mapper来决定如何转换
       * @param pageSize 分页的大小
       * @param pageNum 当前页
       * @param lastId 条件分页参数, 区别于skip-limit,采用find(_id>lastId).limit分页.
       *      * 如果不跳页,像朋友圈,微博这样下拉刷新的分页需求,需要传递上一页的最后一条记录的ObjectId。 如果是null,则返回pageNum那一页
       * @param <T> collection定义的class类型
       * @param <R> 最终返回时,展现给页面时的一条记录的类型
       * @return 一个封装page信息的对象
       */
      public <T, R> MongoPageResult<R> pageQuery(Query query, Class<T> entityClass, Function<T, R> mapper, Integer pageNum, Integer pageSize, String lastId) {
        //分页逻辑
        long total = mongoTemplate.count(query, entityClass);
        final Integer pages = (int) Math.ceil(total / (double) pageSize);
        if (pageNum <= 0 || pageNum > pages) {
          pageNum = FIRST_PAGE_NUM;
        }
    
        final Criteria criteria = new Criteria();
        if (!StringUtils.isEmpty(lastId)) {
          if (pageNum != FIRST_PAGE_NUM) {
            criteria.and(ID).gt(new ObjectId(lastId));
          }
          query.limit(pageSize);
        } else {
          int skip = pageSize * (pageNum - 1);
          query.skip(skip).limit(pageSize);
        }
    
        final List<T> entityList = mongoTemplate.find(query.addCriteria(criteria).with(new Sort(Lists.newArrayList(new Order(Direction.ASC, ID)))), entityClass);
    
        final MongoPageResult<R> pageResult = new MongoPageResult<>();
        pageResult.setTotal(total);
        pageResult.setPages(pages);
        pageResult.setPageSize(pageSize);
        pageResult.setPageNum(pageNum);
        pageResult.setList(entityList.stream().map(mapper).collect(Collectors.toList()));
        return pageResult;
      }
    }
    

    相关文章

      网友评论

          本文标题:SpringBoot MongoDB 整合

          本文链接:https://www.haomeiwen.com/subject/qptezftx.html