Spring认证中国教育管理中心-Spring Data MongoDB教程三

自定义类型映射

如果你不想把整个Java类名写成类型信息,而是想用一个key,你可以@TypeAlias在实体类上使用注解。如果你需要更多的自定义映射,看看TypeInformationMapper接口。该接口的实例可以在上配置DefaultMongoTypeMapper,而后者又可以在上配置MappingMongoConverter。以下示例显示了如何为实体定义类型别名:

示例64.为实体定义类型别名

@TypeAlias("pers")classPerson{}

请注意,生成的文档包含字段中pers的值_class。

类型别名仅在映射上下文知道实际类型时才有效。所需的实体元数据在第一次保存时确定,或者必须通过配置初始实体集提供。默认情况下,配置类会扫描基础包以寻找潜在的候选者。

@ConfigurationpublicclassAppConfigextsAbstractMongoClientConfiguration{@OverrideprotectedSetClass?getInitialEntitySet(){();}//}

配置自定义类型映射

下面的例子说明如何配置自定义MongoTypeMapper的MappingMongoConverter:

示例65.MongoTypeMapper使用SpringJavaConfig配置自定义

classCustomMongoTypeMapperextsDefaultMongoTypeMapper{//implementcustomtypemappinghere}
@ConfigurationclassSampleMongoConfigurationextsAbstractMongoClientConfiguration{@OverrideprotectedStringgetDatabaseName(){return"database";}@Bean@OverridepublicMappingMongoConvertermappingMongoConverter()throwsException{MappingMongoConvertermmc=();(customTypeMapper());returnmmc;}@BeanpublicMongoTypeMappercustomTypeMapper(){returnnewCustomMongoTypeMapper();}}

请注意,前面的示例扩展了AbstractMongoClientConfiguration类并覆盖了MappingMongoConverter我们配置自定义MongoTypeMapper.

以下示例显示如何使用XML配置自定义MongoTypeMapper:

示例66.MongoTypeMapper使用XML配置自定义

mongo:mapping-convertertype-mapper-ref="customMongoTypeMapper"/beanname="customMongoTypeMapper"class=""/
11.5.3.保存和插入文档的方法

有几种方便的方法可MongoTemplate用于保存和插入对象。要对转换过程进行更细粒度的控制,您可以使用MappingMongoConverter-例如ConverterPerson,Document和注册Spring转换器ConverterDocument,Person。

插入和保存操作之间的区别在于,如果对象尚不存在,则保存操作会执行插入操作。

使用保存操作的简单情况是保存一个POJO。在这种情况下,集合名称由类的名称(非完全限定)确定。您还可以使用特定的集合名称调用保存操作。您可以使用映射元数据来覆盖存储对象的集合。

插入或保存时,如果Id未设置该属性,则假设其值将由数据库自动生成。因此,ObjectId要成功自动生成an,类中的Id属性或字段的类型必须是aString、anObjectId或aBigInteger。

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

示例67.使用MongoTemplate插入和检索文档

;;…Personp=newPerson("Bob",33);(p);Personqp=(query(where("age").is(33)),);

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

voidsave(ObjectobjectToSave):将对象保存到默认集合。

voidsave(ObjectobjectToSave,StringcollectionName):将对象保存到指定的集合。

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

voidinsert(ObjectobjectToSave):将对象插入到默认集合中。

voidinsert(ObjectobjectToSave,StringcollectionName):将对象插入到指定的集合中。

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

有两种方法可以管理用于文档的集合名称。使用的默认集合名称是更改为以小写字母开头的类名称。所以一个类存储在person集合中。您可以通过为@Document注释提供不同的集合名称来对此进行自定义。您还可以通过提供您自己的集合名称作为所选MongoTemplate方法调用的最后一个参数来覆盖集合名称。

插入或保存单个对象

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

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

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

save:保存对象,覆盖任何可能具有相同id.

批量插入多个对象

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

插入方法:以aCollection作为第一个参数。它们在单个批量写入数据库中插入对象列表。

11.5.4.更新集合中的文档

对于更新,您可以使用using更新找到的第一个文档,也可以使用方法更新找到的与查询匹配的所有文档。以下示例显示了SAVINGS我们使用$inc运算符向余额添加一次性50.00美元奖金的所有帐户的更新:

示例68.使用MongoTemplate

;;;WriteResultwr=(newQuery(where("").is()),newUpdate().inc("accounts.$.balance",50.00),);

除了Query前面讨论的之外,我们还通过使用Update对象来提供更新定义。该Update班有匹配供MongoDB的更新改进剂的方法。

大多数方法都会返回Update对象,为API提供流畅的样式。

运行文档更新的方法

updateFirst:用更新的文档更新与查询文档条件匹配的第一个文档。

updateMulti:使用更新的文档更新与查询文档条件匹配的所有对象。

updateFirst不支持订购。请使用findAndModify申请Sort。

Update类中的方法

您可以在类中使用一点“'语法糖'”Update,因为它的方法旨在链接在一起。此外,您可以Update通过publicstaticUpdateupdate(Stringkey,Objectvalue)使用静态导入来启动新实例的创建。

本Update类包含以下方法:

Update(Stringkey,Objectvalue)使用$addToSet更新修饰符的addToSet更新

Update(Stringkey)使用$currentDateupdate修饰符更新currentDate

UpdatecurrentTimestamp(Stringkey)使用$currentDate更新修饰符更新$typetimestamp

Updateinc(Stringkey,Numberinc)使用$inc更新修饰符更新

Update(Stringkey,Objectmax)使用$max更新修饰符的最大更新

Updatemin(Stringkey,Objectmin)使用$min更新修饰符进行更新

Update(Stringkey,Numbermultiplier)使用$mul更新修饰符乘以更新

Update(Stringkey,)使用$pop更新修饰符弹出更新

Update(Stringkey,Objectvalue)使用$pull更新修饰符拉取更新

Update(Stringkey,Object[]values)使用$pullAll更新修饰符pullAll更新

Update(Stringkey,Objectvalue)使用$push更新修饰符推送更新

UpdatepushAll(Stringkey,Object[]values)使用$pushAll更新修饰符更新

Update(StringoldName,StringnewName)使用$rename更新修饰符重命名更新

Update(Stringkey,Objectvalue)使用$set更新修饰符设置更新

Update(Stringkey,Objectvalue)使用$setOnInsert更新修饰符setOnInsert更新

Update(Stringkey)使用$unset更新修饰符取消设置更新

一些更新修饰符,例如$pushand$addToSet,允许嵌套额外的运算符。

//{$push:{"category":{"$each":["spring","data"]}}}newUpdate().push("category").each("spring","data")//{$push:{"key":{"$position":0,"$each":["Arya","Arry","Weasel"]}}}newUpdate().push("key").atPosition().each(("Arya","Arry","Weasel"));//{$push:{"key":{"$slice":5,"$each":["Arya","Arry","Weasel"]}}}newUpdate().push("key").slice(5).each(("Arya","Arry","Weasel"));//{$addToSet:{"values":{"$each":["spring","data","mongodb"]}}}newUpdate().addToSet("values").each("spring","data","mongodb");

11.5.5.“更新”集合中的文档

与执行updateFirst操作相关,您还可以执行“upsert”操作,如果找不到与查询匹配的文档,它将执行插入操作。插入的文档是查询文档和更新文档的组合。以下示例显示了如何使用该upsert方法:

().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:

TTfindAndModify(Queryquery,Updateupdate,ClassTentityClass);TTfindAndModify(Queryquery,Updateupdate,ClassTentityClass,StringcollectionName);TTfindAndModify(Queryquery,Updateupdate,FindAndModifyOptionsoptions,ClassTentityClass);TTfindAndModify(Queryquery,Updateupdate,FindAndModifyOptionsoptions,ClassTentityClass,StringcollectionName);

以下示例将一些Person对象插入容器并执行findAndUpdate操作:

(newPerson("Tom",21));(newPerson("Dick",22));(newPerson("Harry",23));Queryquery=newQuery(("firstName").is("Harry"));Updateupdate=newUpdate().inc("age",1);PersonoldValue=().matching(query).apply(update).findAndModifyValue();//return'soldpersonobjectassertThat(()).isEqualTo("Harry");assertThat(()).isEqualTo(23);PersonnewValue=().matching(query).findOneValue();assertThat(()).isEqualTo(24);PersonnewestValue=().matching(query).apply(update).withOptions(().returnNew(true))//();assertThat(()).isEqualTo(25);

该FindAndModifyOptions方法可以让你设置的选项returnNew,upsert以及remove从前面的代码片段延伸.An例子如下:

Personupserted=().matching(newQuery(("firstName").is("Mary"))).apply(update).withOptions(().upsert(true).returnNew(true)).findAndModifyValue()assertThat(()).isEqualTo("Mary");assertThat(()).isOne();
11.5.7.聚合管道更新

更新方法公开MongoOperations并通过聚合管道ReactiveMongoOperations接受聚合管道AggregationUpdate。UsingAggregationUpdate允许在更新操作中利用聚合。在更新中使用聚合允许通过使用单个操作表达多个阶段和多个条件来更新一个或多个字段。

更新可以包括以下阶段:

(…).toValue(…​)→$set:{…​}

(…​)→$unset:[…​]

(…​)→$replaceWith:{…​}

示例69.更新聚合

AggregationUpdateupdate=().set("average").toValue(("tests").avg()).set("grade").toValue((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"));().apply(update).all();
({},[{$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.查找和替换文档

OptionalUserresult=().matching(query(where("firstame").is("Tom"))).replaceWith(newPerson("Dick")).withOptions(().upsert()).as().findAndReplace();

使用具有给定域类型的fluentupdateAPI来映射查询和派生集合名称,或者仅使用MongoOperationsspring认证java程序员Spring#

发布于 2025-12-14
33
目录

    推荐阅读