Spring整合MongoDB

官方文档地址:https://docs.spring.io/spring-data/mongodb/docs/3.1.3/reference/html/#introduction

 

一、 Spring整合MongoDB 

1、依赖

        <!--mongo-->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
            <version>3.1.3</version>
        </dependency>

        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongodb-driver-sync</artifactId>
            <version>4.1.1</version>
        </dependency>

将Spring的版本更改为 5.3.3: <spring.framework.version>5.3.3</spring.framework.version>

若springboot版本为2.4.2,则Spring版本就是 5.3.3

 

2、将MongoClient交给Spring IOC容器管理

 MongoConfig.java

@Configuration
public class MongoConfig {

    @Bean
    public MongoClient mongoClient() {
        // 使用更高级的配置MongoClientSettings(请注意,这些不是建议值)
//        MongoClientSettings settings = MongoClientSettings.builder()
//                .applyConnectionString(new ConnectionString("mongodb://127.0.0.1:37017/db_name"))
//                .applyToConnectionPoolSettings(builder -> ConnectionPoolSettings.builder()
//                        .maxConnectionLifeTime(10, TimeUnit.SECONDS)
//                        .maxWaitTime(15, TimeUnit.SECONDS)
//                        .maxConnectionIdleTime(30, TimeUnit.SECONDS)
//                        .maintenanceFrequency(10, TimeUnit.SECONDS)
//                        .maintenanceInitialDelay(11, TimeUnit.SECONDS)
//                        .minSize(10)
//                        .maxSize(20)
//                        .build())
//                .build();
//        return MongoClients.create(settings);
        return MongoClients.create("mongodb://127.0.0.1:37017/db_name");

    }

//    @Bean
//    public MongoDatabaseFactory mongoDatabaseFactory() {
//        return new SimpleMongoClientDatabaseFactory(mongoClient(), "db_name");
//    }

//    @Bean
//    public MongoTemplate mongoTemplate() {
//        return new MongoTemplate(mongoDatabaseFactory());
//    }
    
    @Bean
    public MongoTemplate mongoTemplate() {
        return new MongoTemplate(mongoClient(),"db_name");
    }

}

3、简单使用示例

    @Autowired
    private MongoTemplate mongoTemplate;

    @Test
    void mongoTest() {
        Map<String, Object> record = new HashMap<>(4);
        record.put("_id", "1");
        record.put("name", "hello mongo");
        // 插入
        Map<String, Object> result = mongoTemplate.insert(record, "cf_products");
        // 查询
        List<Map> cfProductsMapList = mongoTemplate.findAll(Map.class,"cf_products");
    }

 数据:

> db.cf_products.find().pretty()
{ "_id" : "1", "name" : "hello mongo" }

 

 

 

二、SpringBoot整合MongoDB 

Springboot版本为2.4.2

1、依赖

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

 2、application.properties中配置连接信息

#mongodb://user:pwd@ip1:port1,ip2:port2/database
spring.data.mongodb.uri=mongodb://127.0.0.1:37017/db_name

 3、简单使用示例

   @Autowired
    private MongoTemplate mongoTemplate;

    @Test
    void mongoTest() {
        Map<String, Object> record = new HashMap<>(4);
        record.put("_id", "1");
        record.put("name", "hello mongo");
        // 插入
        Map<String, Object> result = mongoTemplate.insert(record, "cf_products");
        // 查询
        List<Map> cfProductsMapList = mongoTemplate.findAll(Map.class,"cf_products");
    }

 

 

 

MongoTeplate简介

  org.springframework.data.mongodb.core.MongoTemplate

  MongoTemplate是Spring对MongoDB支持的核心,并且是线程安全的,可以在多个实例之间复用。

  提供了创建,更新,删除和查询MongoDB的快捷操作,并提供了 domain 对象和 mongoDB document之间的映射。

  MongoDB文档和域类之间的映射是通过委托MongoConverter接口的实现来完成的。Spring提供了MappingMongoConverter实现,但您也可以编写自己的转换器

 

  MongoTemplate进行CRUD操作:

  1、插入

//  保存对象到mongodb
mongoTemplate.save(user);
mongoTemplate.insert(user);
//  根据集合名称保存list到mongodb
mongoTemplate.save(list,"mongodb_user");
mongoTemplate.insert(list,"mongodb_user");

 

 

 

  2、查询

Query query = Query.query(Criteria.where("name").is("yang"));
mongoTemplate.find(query,User.class,"mongodb_user");

// 查询全部
mongoTemplate.findAll(User.class,"mongodb_user");

// 分页查询
Pageable pageable = PageRequest.of(page - 1, pageSize, Sort.by(Sort.Order.desc("date")));
Query query = new Query().with(pageable);
mongoTemplate.find(query, User.class,"mongodb_user");

 

  3、更新

// 查询不存在则插入,存在则更新
Query query = Query.query(Criteria.where("video_id").is(albumId));
Update update = Update.update("trace_id", MDCUtil.getTraceId())
                    .set("update_time", new Date())
                    .set("album_id", albumId)
                    .set("video_id", videoId)
                    .set("origin_data", originData);
mongoTemplate.upsert(query, update, collectionName);

 

  

  4、删除 

//  根据条件删除
mongoTemplate.remove(query);

 

 批处理

  注意:查询使用 _id,或者给查询条件字段创建索引

  批处理模式:

    /**
	 * Mode for bulk operation.
	 **/
	enum BulkMode {
		/** 按顺序执行批量操作。第一个错误出现时将取消处理. */
		ORDERED,
		/** 并行执行批量操作,出现错误将继续处理. */
		UNORDERED
	};

  批量upset:

List<Pair<Query, Update>> pairList = new ArrayList<>();
        // 入MongoDB临时库
        for (AlbumContent albumContent : albumContents) {
            String albumId = albumContent.getCover_id();
            String originData = JacksonUtil.toString(albumContent);
            // 查询不存在则插入,存在则更新
            Query query = Query.query(Criteria.where("_id").is(albumId));
            Update update = Update.update("trace_id", MDCUtil.getTraceId())
                    .set("_id", albumId)
                    .set("album_id", albumId)
                    .set("origin_data", originData);
                    .set("update_time", new Date())
            Pair<Query, Update> pair = Pair.of(query, update);
            pairList.add(pair);
        }       
        // 批量upset
        BulkOperations bulkOperations = mongoTemplate.bulkOps(BulkOperations.BulkMode.ORDERED, collectionName);
        bulkOperations.upsert(pairList);
        BulkWriteResult bulkWriteResult = bulkOperations.execute();

  分页查询:

                Query query = new Query();
                query.addCriteria(new Criteria());
                long count = mongoTemplate.count(query, collName);
                // 每页查询20条
                int pageSize = 20;
                // 总页数
                long num = count % pageSize == 0 ? count / pageSize : count / pageSize + 1;
                // 执行分页查询
                int pageNum = 1;
                while (pageNum <= num) {
                    query.skip((pageNum - 1) * pageSize);
                    query.limit(pageSize);
                    pageNum++;
                    List<Map> datas = mongoTemplate.find(query, Map.class, ablumCollName);
                    for (Map<String, Object> data : datas) {
                        // 数据业务处理
                        ...
                    }
                }

 

 

如何_id在映射层中处理字段

   MongoDB要求您有一个_id用于所有文档的字段。如果不提供,驱动程序将为分配ObjectId一个生成的值。

  当您使用时MappingMongoConverter,某些规则将控制Java类中的属性如何映射到此_id字段:

    ① 用@Id(org.springframework.data.annotation.Id)注释的属性或字段映射到该_id字段。

    ② 没有注释但已命名的属性或字段id映射到该_id字段

 

 

问题总结:

  1、Exception authenticating MongoCredential

Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='crawler_rw', source='admin', password=<hidden>, mechanismProperties=<hidden>}; 
nested exception is com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='crawler_rw', source='admin', password=<hidden>, mechanismProperties=<hidden>}

  原因,mongo.url没有指定数据库,导致使用默认的数据库admin  

  解决方案:

    mongo.url带上数据库名称 :mongodb://user:pwd@ip1:port1,ip2:port2/database  

 

END.

posted @ 2021-02-20 17:52  杨岂  阅读(1047)  评论(0编辑  收藏  举报