原标题:Spring Data MongoDB参考文档三(内容来源:Spring中国教育管理中心) 自定义类型映射如果你不想把整个Java类名写成类型信息,而是想用一个key,你可以@TypeAlias在实体类上使用注解。如果你需要更多的自定义映射,看看TypeInformationMapper接口。该接口的实例可以在 上配置DefaultMongoTypeMapper,而后者又可以在 上配置MappingMongoConverter。以下示例显示了如何为实体定义类型别名: 示例 64.为实体定义类型别名 @TypeAlias("pers")class Person { } 请注意,生成的文档包含字段中pers的值_class。 类型别名仅在映射上下文知道实际类型时才有效。所需的实体元数据在第一次保存时确定,或者必须通过配置初始实体集提供。默认情况下,配置类会扫描基础包以寻找潜在的候选者。 @Configuration public class AppConfig extends AbstractMongoClientConfiguration { @Override protected Set<Class<?>> getInitialEntitySet() { return Collections.singleton(Person.class); } // ... } 配置自定义类型映射下面的例子说明如何配置自定义MongoTypeMapper的MappingMongoConverter: 示例 65.MongoTypeMapper使用 Spring Java Config配置自定义 class CustomMongoTypeMapper extends DefaultMongoTypeMapper { //implement custom type mapping here} @Configurationclass SampleMongoConfiguration extends AbstractMongoClientConfiguration { @Override protected String getDatabaseName() { return "database"; } @Bean @Override public MappingMongoConverter mappingMongoConverter() throws Exception { MappingMongoConverter mmc = super.mappingMongoConverter(); mmc.setTypeMapper(customTypeMapper()); return mmc; } @Bean public MongoTypeMapper customTypeMapper() { return new CustomMongoTypeMapper(); } } 请注意,前面的示例扩展了 以下示例显示如何使用 XML 配置自定义MongoTypeMapper: 示例 66.MongoTypeMapper使用 XML配置自定义 <mongo:mapping-converter type-mapper-ref="customMongoTypeMapper"/> <bean name="customMongoTypeMapper" class="com.bubu.mongo.CustomMongoTypeMapper"/> 11.5.3.保存和插入文档的方法有几种方便的方法可MongoTemplate用于保存和插入对象。要对转换过程进行更细粒度的控制,您可以使用MappingMongoConverter - 例如Converter<Person, Document>和注册 Spring 转换器Converter<Document, Person>。 插入和保存操作之间的区别在于,如果对象尚不存在,则保存操作会执行插入操作。 使用保存操作的简单情况是保存一个 POJO。在这种情况下,集合名称由类的名称(非完全限定)确定。您还可以使用特定的集合名称调用保存操作。您可以使用映射元数据来覆盖存储对象的集合。 插入或保存时,如果Id未设置该属性,则假设其值将由数据库自动生成。因此,ObjectId要成功自动生成 an ,类中的Id属性或字段的类型必须是 a String、 anObjectId或 a BigInteger。 以下示例显示了如何保存文档并检索其内容: 示例 67. 使用 MongoTemplate 插入和检索文档 import static org.springframework.data.mongodb.core.query.Criteria.where;import static org.springframework.data.mongodb.core.query.Criteria.query; … Person p = new Person("Bob", 33); mongoTemplate.insert(p); Person qp = mongoTemplate.findOne(query(where("age").is(33)), Person.class); 以下插入和保存操作可用:
也可以使用一组类似的插入操作:
我的文档保存在哪个集合中?有两种方法可以管理用于文档的集合名称。使用的默认集合名称是更改为以小写字母开头的类名称。所以一个com.test.Person类存储在person集合中。您可以通过为@Document注释提供不同的集合名称来对此进行自定义。您还可以通过提供您自己的集合名称作为所选MongoTemplate方法调用的最后一个参数来覆盖集合名称。 插入或保存单个对象MongoDB 驱动程序支持在单个操作中插入文档集合。MongoOperations接口中的以下方法支持此功能:
批量插入多个对象MongoDB 驱动程序支持在一个操作中插入一组文档。MongoOperations接口中的以下方法支持此功能:
11.5.4.更新集合中的文档对于更新,您可以使用 using 更新找到的第一个文档,也可以使用 示例 68. 使用 MongoTemplate import static org.springframework.data.mongodb.core.query.Criteria.where;import static org.springframework.data.mongodb.core.query.Query;import static org.springframework.data.mongodb.core.query.Update; ... WriteResult wr = mongoTemplate.updateMulti(new Query(where("accounts.accountType").is(Account.Type.SAVINGS)), new Update().inc("accounts.$.balance", 50.00), Account.class); 除了Query前面讨论的之外,我们还通过使用Update对象来提供更新定义。该Update班有匹配供MongoDB的更新改进剂的方法。 大多数方法都会返回Update对象,为 API 提供流畅的样式。 运行文档更新的方法
updateFirst不支持订购。请使用findAndModify申请Sort。 Update类中的方法您可以在类中使用一点“'语法糖'” Update,因为它的方法旨在链接在一起。此外,您可以Update通过public static Update update(String key, Object value)使用静态导入来启动新实例的创建。 本Update类包含以下方法:
一些更新修饰符,例如$pushand $addToSet,允许嵌套额外的运算符。 // { $push : { "category" : { "$each" : [ "spring" , "data" ] } } } new Update().push("category").each("spring", "data") // { $push : { "key" : { "$position" : 0 , "$each" : [ "Arya" , "Arry" , "Weasel" ] } } } new Update().push("key").atPosition(Position.FIRST).each(Arrays.asList("Arya", "Arry", "Weasel")); // { $push : { "key" : { "$slice" : 5 , "$each" : [ "Arya" , "Arry" , "Weasel" ] } } } new Update().push("key").slice(5).each(Arrays.asList("Arya", "Arry", "Weasel")); // { $addToSet : { "values" : { "$each" : [ "spring" , "data" , "mongodb" ] } } } new Update().addToSet("values").each("spring", "data", "mongodb"); 11.5.5.“更新”集合中的文档与执行updateFirst操作相关,您还可以执行“upsert”操作,如果找不到与查询匹配的文档,它将执行插入操作。插入的文档是查询文档和更新文档的组合。以下示例显示了如何使用该upsert方法: template.update(Person.class) .matching(query(where("ssn").is(1111).and("firstName").is("Joe").and("Fraizer").is("Update")) .apply(update("address", addr)) .upsert(); upsert不支持订购。请使用findAndModify申请Sort。 11.5.6.在集合中查找和更新文档该findAndModify(…)对方法MongoCollection可以更新的文件,并在单个操作中返回老任或新更新的文件。MongoTemplate提供了四个findAndModify重载方法,它们接受Query和Update类并将 from 转换Document为您的 POJO: <T> T findAndModify(Query query, Update update, Class<T> entityClass);<T> T findAndModify(Query query, Update update, Class<T> entityClass, String collectionName);<T> T findAndModify(Query query, Update update, FindAndModifyOptions options, Class<T> entityClass);<T> T findAndModify(Query query, Update update, FindAndModifyOptions options, Class<T> entityClass, String collectionName); 以下示例将一些Person对象插入容器并执行findAndUpdate操作: template.insert(new Person("Tom", 21)); template.insert(new Person("Dick", 22)); template.insert(new Person("Harry", 23)); Query query = new Query(Criteria.where("firstName").is("Harry"));Update update = new Update().inc("age", 1); Person oldValue = template.update(Person.class) .matching(query) .apply(update) .findAndModifyValue(); // return's old person object assertThat(oldValue.getFirstName()).isEqualTo("Harry"); assertThat(oldValue.getAge()).isEqualTo(23); Person newValue = template.query(Person.class) .matching(query) .findOneValue(); assertThat(newValue.getAge()).isEqualTo(24); Person newestValue = template.update(Person.class) .matching(query) .apply(update) .withOptions(FindAndModifyOptions.options().returnNew(true)) // Now return the newly updated document when updating .findAndModifyValue(); assertThat(newestValue.getAge()).isEqualTo(25); 该FindAndModifyOptions方法可以让你设置的选项returnNew,upsert以及remove从前面的代码片段延伸.An例子如下: Person upserted = template.update(Person.class) .matching(new Query(Criteria.where("firstName").is("Mary"))) .apply(update) .withOptions(FindAndModifyOptions.options().upsert(true).returnNew(true)) .findAndModifyValue() assertThat(upserted.getFirstName()).isEqualTo("Mary"); assertThat(upserted.getAge()).isOne(); 11.5.7.聚合管道更新更新方法公开MongoOperations并通过聚合管道ReactiveMongoOperations接受聚合管道AggregationUpdate。UsingAggregationUpdate允许在更新操作中利用MongoDB 4.2 聚合。在更新中使用聚合允许通过使用单个操作表达多个阶段和多个条件来更新一个或多个字段。 更新可以包括以下阶段:
示例 69. 更新聚合 AggregationUpdate update = Aggregation.newUpdate() .set("average").toValue(ArithmeticOperators.valueOf("tests").avg()) .set("grade").toValue(ConditionalOperators.switchCases( when(valueOf("average").greaterThanEqualToValue(90)).then("A"), when(valueOf("average").greaterThanEqualToValue(80)).then("B"), when(valueOf("average").greaterThanEqualToValue(70)).then("C"), when(valueOf("average").greaterThanEqualToValue(60)).then("D")) .defaultTo("F") ); template.update(Student.class) .apply(update) .all(); db.students.update( { }, [ { $set: { average : { $avg: "$tests" } } }, { $set: { grade: { $switch: { branches: [ { case: { $gte: [ "$average", 90 ] }, then: "A" }, { case: { $gte: [ "$average", 80 ] }, then: "B" }, { case: { $gte: [ "$average", 70 ] }, then: "C" }, { case: { $gte: [ "$average", 60 ] }, then: "D" } ], default: "F" } } } } ], { multi: true } ) 第一$set阶段根据测试字段的平均值计算新的字段平均值。 第二$set阶段根据第一聚合阶段计算的平均字段计算新的字段等级。 管道在学生集合上运行并Student用于聚合字段映射。 将更新应用于集合中的所有匹配文档。 11.5.8.查找和替换文档替换整个的最直接的方法Document是通过它idusingsave方法。然而,这可能并不总是可行的。findAndReplace提供了一种替代方法,允许通过简单的查询来识别要替换的文档。 示例 70. 查找和替换文档 Optional<User> result = template.update(Person.class) .matching(query(where("firstame").is("Tom"))) .replaceWith(new Person("Dick")) .withOptions(FindAndReplaceOptions.options().upsert()) .as(User.class) .findAndReplace(); 使用具有给定域类型的 fluent update API 来映射查询和派生集合名称,或者仅使用MongoOperations#findAndReplace. 映射到给定域类型的实际匹配查询。通过查询提供sort,fields和collation设置。 额外的可选钩子以提供默认值以外的选项,如upsert. 用于映射运算结果的可选投影类型。如果没有给出初始域类型,则使用。 触发实际处理。使用findAndReplaceValue以获得可空的结果,而不是一个Optional。 请注意,更换件不得保留其id本身,因为id现有的Document将被商店本身转移到更换件中。还要记住,它findAndReplace只会根据可能给定的排序顺序替换与查询条件匹配的第一个文档。 |
|
来自: 王先生的内容 > 《Spring国际认证》