springboot3集成低版本的mongo

随手记

问题背景

当项目确定技术中为springboot3(3.3.1),jdk17,vue3后,风风火火地开搞,当搞的差不多了,要连mongo时,才发现mongo服务版本为3.2.12,版本太低,以至于springboot3无法连接。

maven依赖:

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

  

报错信息:

org.springframework.data.mongodb.UncategorizedMongoDbException: Server at  ip:port reports wire version 4, but this version of the driver requires at least 6 (MongoDB 3.6).

 

研究过程

 springboot3-mongo的集成包。可以分解成以下依赖:

        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongodb-driver-sync</artifactId>
            <version>5.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>bson</artifactId>
            <version>5.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongodb-driver-core</artifactId>
            <version>5.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
            <version>4.3.1</version>
        </dependency>

尝试单独更换不同版本的驱动,不同版本的核心依赖包,结果都不行,与springboot3-mongo的集成包版本不匹配。最终放弃使用springboot集成的包

 

解决方案

使用单独的java-mongo依赖,引入spring-data依赖,让mongo对象可以给到spring去管理(IOC),一个可以的包集合如下:

 <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongodb-driver-sync</artifactId>
            <version>4.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>bson</artifactId>
            <version>4.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongodb-driver-core</artifactId>
            <version>4.7.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
            <version>4.0.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-commons</artifactId>
            <version>3.0.12</version>
        </dependency>

  

因为不和springboot去做绑定,所以需要自己处理连接mongo的账号密码,例子:MongoConfig.java

package xxxx.config;

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoTemplate;

/**
 * @Description: 自定义一个mongoTemplate,交给springboot管理
 * 文档:https://www.mongodb.com/zh-cn/docs/drivers/java/sync/v4.7/quick-start/
 *      https://docs.spring.io/spring-data/data-mongodb/reference/mongodb/template-collection-management.html
 * @Author hxh
 * @date 2024/8/2 14:30
 */
@Configuration
public class MongoConfig {
    @Value("${spring.data.mongodb.uri}")
    private String mongoUri;

    @Value("${spring.data.mongodb.database}")
    private String mongoDatabase;

    @Bean
    MongoClient mongoClient() {
        return MongoClients.create(mongoUri);
    }

    @Bean
    MongoTemplate mongoTemplate(MongoClient mongoClient) {
        return new MongoTemplate(mongoClient, mongoDatabase);
    }

}

  

mongo的实体类对象,可以像springboot集成那样,使用@Document,@Indexed注解,例子:

@Data
@Document(collection = "test_collection")
public class TestMongo{
    @Indexed
    private String testId;

    @Indexed
    private String testIndex;

    private String content;
}

  

用法:

    @Autowired
    MongoTemplate mongoTemplate;

    find方法:
    Query query = new Query();
    query.addCriteria(Criteria.where("字段名称").is(字段值).and("字段名称").is(字段值));
    mongoTemplate.find(query, 对象.class)

  增删查改和集成springboot的用法一样,不过多赘述。

 

 

踩坑

自定义mongo数据转对象的方法:

/**
 * @Description: 自定义mongo数据向对象转化的逻辑
 * 大坑:
 * 1、不应该使用springboot自带的@ReadingConverter,实现Converter<Document, 对象类性> 接口的形式自定义,
 * 因为mongoTemplate不是使用springboot集成管理,即使被扫描到,注册到bean也无效!!!
 *
 * 2、不应该使用mongo-java官网提供的编解码器,实现Codec的方式自定义,因为这里的用法不是官网原生用法,而是集成在spring-data中
 *
 * 3、spring-data官网中只是提了一下,并没有详细的转换说明:
 * https://docs.spring.io/spring-data/data-mongodb/reference/mongodb/template-config.html
 *
 * 所以要么有mongo-java原生方法,要么使用springboot集成方法,spring-data集成方法跟弃子一样,又没文档,又难用,C++
 * @Author hxh
 * @date 2024/8/7 10:26
 */
import cn.hutool.json.JSONUtil;
import org.apache.commons.lang3.StringUtils;
import org.bson.Document;
import org.bson.conversions.Bson;
import org.springframework.data.mongodb.core.convert.DbRefResolver;
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;

public class CustomMongoConverter extends MappingMongoConverter {

    public CustomMongoConverter(DbRefResolver dbRefResolver, MongoMappingContext mongoMappingContext) {
        super(dbRefResolver, mongoMappingContext);
    }

    @Override
    public <S extends Object> S read(Class<S> clazz, Bson bson) {
        if (clazz.equals(自定义对象.class)) {
            Document document = (Document) bson;
       
               xxxx
            }
            return (S) 自定义对象;
        } else {
            return super.read(clazz, bson);
        }
    }


}

  相应地,mongotemplate创建时,要设置这个转换器

@Configuration
public class MongoConfig {
    @Value("${spring.data.mongodb.uri}")
    private String mongoUri;

    @Value("${spring.data.mongodb.database}")
    private String mongoDatabase;

    @Bean
    MongoClient mongoClient() {
        return MongoClients.create(mongoUri);
    }

    @Bean
    MongoTemplate mongoTemplate(MongoClient mongoClient) {
        MongoDatabaseFactory mongoDbFactory = new SimpleMongoClientDatabaseFactory(mongoClient,mongoDatabase);
        DefaultDbRefResolver dbRefResolver = new DefaultDbRefResolver(mongoDbFactory);
        CustomMongoConverter mongoConverter = new CustomMongoConverter(dbRefResolver, new MongoMappingContext());
        return new MongoTemplate(mongoDbFactory, mongoConverter);
    }

}

  

 

posted @ 2024-08-05 09:55  q彩虹海q  阅读(414)  评论(0)    收藏  举报