Spring Data MongoDB 教程

保存和插入文档的方法

MongoTemplate 上有几个便捷方法,用于保存和插入你的对象。为了对转换过程有更精细的控制,你可以用 MappingMongoConverter 注册 Spring 转换器 —— 例如 Converter<Person, Document>Converter<Document, Person>

注意:插入操作和保存操作的区别在于,如果对象不存在,则保存操作将执行插入操作。

使用保存操作的简单情况是保存一个 POJO。在这种情况下,集合名称是由类的名称(非完全限定,如 com.hxstrive.springdata.mongo.entity.Person 对象对应的集合名称为 Person)决定的。你也可以用一个特定的集合名称来调用保存操作。你可以使用映射元数据来重写存储对象的集合。

当插入或保存时,如果 id 属性没有被设置,假设它的值将由数据库自动生成。因此,为了成功地自动生成一个 ObjectId,你的类中的 id 属性或字段的类型必须是 StringObjectId BigInteger

以下示例显示了如何保存文档并检索其内容:

package com.hxstrive.springdata.mongodb;

import com.hxstrive.springdata.mongodb.entity.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoTemplate;

import java.util.List;

import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;
import static org.springframework.data.mongodb.core.query.Update.update;

@SpringBootTest
public class SaveTest {

   @Autowired
   private MongoTemplate mongoTemplate;

   @Test
   void contextLoads() {
       Person p = Person.builder().name("Joe").age(34).build();

       // 将对象插入到数据库中
       mongoTemplate.save(p);
       System.out.println("Save: " + p);

       // 查找数据
       p = mongoTemplate.findOne(query(where("name").is("Joe")), Person.class);
       System.out.println("Found: " + p);
   }

}

运行示例,输出如下:

Save: Person(id=63a94f3810de9701d9105fb2, name=Joe, age=34)
Found: Person(id=63a94f3810de9701d9105fb2, name=Joe, age=34)

以下的插入和保存操作是可用的:

  • void save(Object objectToSave)  将对象保存到默认的集合中,即和类名一致的集合

  • void save(Object objectToSave, String collectionName)  将对象保存到指定的集合中

一组类似的插入操作也是可用的:

  • void insert(Object objectToSave)  插入对象到默认的集合中,即和类名一致的集合

  • void insert(Object objectToSave, String collectionName)  插入对象到指定的集合中

我的文件被保存在哪个集合中?

Spring Data MongoDB 提供了两种方法指定我们的对象将被保存到哪个集合中,它们分别如下:

(1)默认使用的集合名是将类名改为以小写字母开头,因此一个 com.test.Person 类被存储在 person 集合中。

(2)通过 @Document 注解指定一个集合名称来保存对象。例如:

package com.hxstrive.springdata.mongodb.entity;

import lombok.Builder;
import lombok.Data;
import lombok.ToString;
import org.springframework.data.annotation.TypeAlias;
import org.springframework.data.mongodb.core.mapping.Document;

// 通过 @Document 注解指定集合名称为 my_person
@Document("my_person")
@TypeAlias("pers")
@Data
@Builder
@ToString
public class Person extends Contact {
   /** 自动映射到 MongoDB 的 _id 字段 */
   private String id;
   private String name;
   private int age;
}

(3)在调用 MongoTemplate 保存/插入方法时的最后一个参数指定集合名称,来覆盖该默认集合名称。例如:

package com.hxstrive.springdata.mongodb;

import com.hxstrive.springdata.mongodb.entity.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoTemplate;
import static org.springframework.data.mongodb.core.query.Criteria.where;
import static org.springframework.data.mongodb.core.query.Query.query;

@SpringBootTest
public class SaveTest2 {

   @Autowired
   private MongoTemplate mongoTemplate;

   @Test
   void contextLoads() {
       Person p = Person.builder().name("Joe").age(34).build();

       // 将对象插入到数据库中
       // 手动指定集合名称为 coll_person
       mongoTemplate.save(p, "coll_person");
       System.out.println("Save: " + p);

       // 查找数据
       // 手动指定集合名称为 coll_person
       p = mongoTemplate.findOne(query(where("name").is("Joe")), Person.class, "coll_person");
       System.out.println("Found: " + p);
   }

}

插入或保存单个对象

MongoDB 驱动程序支持在单个操作中插入文档集合,MongoOperations 接口中的以下方法支持此功能:

  • insert插入一个对象,如果存在具有相同 id 的现有文档,则会生成一个错误。

  • insertAll:接受一个对象的集合作为第一个参数。这个方法检查每个对象,并根据前面指定的规则,将其插入到适当的集合中。

  • save: 保存对象,覆盖任何可能有相同id的对象。

示例:

package com.hxstrive.springdata.mongodb;

import com.hxstrive.springdata.mongodb.entity.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoTemplate;

@SpringBootTest
public class InsertSaveTest {

   @Autowired
   private MongoTemplate mongoTemplate;

   @Test
   void contextLoads() {
       Person p1 = Person.builder().id("1024").name("Joe").age(34).build();
       Person p2 = Person.builder().id("1024").name("Tom").age(30).build();

       // 将对象插入到数据库中
       // OK
       mongoTemplate.save(p1);
       System.out.println("Save p1 = " + p1);

       // OK
       mongoTemplate.save(p2);
       System.out.println("Save p2 = " + p2);

       // Error
       // nested exception is com.mongodb.MongoWriteException: Write operation error on server localhost:27017.
       // Write error: WriteError{code=11000, message='E11000 duplicate key error collection: test.my_person
       // index: _id_ dup key: { : "1024" }', details={}}.
       mongoTemplate.insert(p1);
       System.out.println("Insert p1 = " + p1);
   }

}

在一个批次中插入多个对象

MongoDB 驱动支持在一个操作中插入一个文档集合,MongoOperations 接口中的以下方法支持此功能:

  • insert:该方法以一个集合作为第一个参数。它们在一次批量写入数据库中插入一个对象的列表。

示例:

package com.hxstrive.springdata.mongodb;

import com.hxstrive.springdata.mongodb.entity.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoTemplate;

import java.util.ArrayList;
import java.util.List;

@SpringBootTest
public class BatchInsertTest {

   @Autowired
   private MongoTemplate mongoTemplate;

   @Test
   void contextLoads() {
       Person p1 = Person.builder().id("1024").name("Joe").age(34).build();
       Person p2 = Person.builder().id("1025").name("Tom").age(30).build();
       Person p3 = Person.builder().id("1026").name("Helen").age(39).build();

       List<Person> personList = new ArrayList<>();
       personList.add(p1);
       personList.add(p2);
       personList.add(p3);
       // OK
       //mongoTemplate.insert(personList, Person.class);
       // OK
       mongoTemplate.insert(personList, "my_persson");
   }

}

注意,如果 List 中存在 ID 相等的对象,则保存失败,直到抛出异常的位置开始均保存失败,抛出异常之前的能够正常保存。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号