Mil*_*lan 4 java couchbase spring-data spring-data-couchbase
有没有一种简单的方法可以将spring数据更新到没有_class属性的文档中?在沙发上,我的sampledata水桶里有这样的东西:
{
"username" : "alice",
"created" : 1473292800000,
"data" : { "a": 1, "b" : "2"},
"type" : "mydata"
}
Run Code Online (Sandbox Code Playgroud)
现在,是否有任何方法可以定义从此文档结构到Java对象的映射(请注意,_class缺少属性并且无法添加属性),反之亦然,这样我就可以从Spring Couchbase数据中获取所有(或大多数)自动魔术功能?
诸如此类:如果type字段的值为“ mydata”,请使用类MyData.java。因此,当执行查找而不是自动添加AND _class = "mydata"到生成的查询add时AND type = "mydata"。
通常,Spring Data需要该_class领域知道反序列化时要实例化的内容。
_class通过覆盖中的typeKey()方法,在Spring Data Couchbase中使用不同的字段名称非常容易AbsctractCouchbaseDataConfiguration。
但是默认情况下,仍然需要一个完全合格的类名
解决这个问题将需要更多的工作:
CouchbaseTypeMapper遵循的模型来实现自己的模型DefaultCouchbaseTypeMapper。在super(...)构造函数中,您需要提供一个附加参数:的列表TypeInformationMapper。默认实现未明确提供一个,因此使用a SimpleTypeInformationMapper,即放置FQN的实现。Map:ConfigurableTypeInformationMapper...将特定的类别名为较短的名称。ConfigurableTypeInformationMapper您想要的用于特定类的别名+一个SimpleTypeInformationMapper在其后的别名(对于序列化一个您没有为其提供别名的类的情况),可以实现您的目标。typeMapper是MappingCouchbaseConverter,您还需要扩展typeMapper,在中使用。(只是实例化您的默认值。MappingCouchbaseConverter使用您的自定义CouchbaseTypeMapper(mappingCouchbaseConverter()方法)的自定义实例。您可以通过创建自定义注释来实现此目的@DocumentType
@DocumentType("billing")
@Document
public class BillingRecordDocument {
String name;
// ...
}
Run Code Online (Sandbox Code Playgroud)
文档将如下所示:
{
"type" : "billing"
"name" : "..."
}
Run Code Online (Sandbox Code Playgroud)
只需创建以下类:创建自定义AbstractReactiveCouchbaseConfiguration或AbstractCouchbaseConfiguration(取决于您使用的变体)
@Configuration
@EnableReactiveCouchbaseRepositories
public class CustomReactiveCouchbaseConfiguration extends AbstractReactiveCouchbaseConfiguration {
// implement abstract methods
// and configure custom mapping convereter
@Bean(name = BeanNames.COUCHBASE_MAPPING_CONVERTER)
public MappingCouchbaseConverter mappingCouchbaseConverter() throws Exception {
MappingCouchbaseConverter converter = new CustomMappingCouchbaseConverter(couchbaseMappingContext(), typeKey());
converter.setCustomConversions(customConversions());
return converter;
}
@Override
public String typeKey() {
return "type"; // this will owerride '_class'
}
}
Run Code Online (Sandbox Code Playgroud)
创建自定义MappingCouchbaseConverter
public class CustomMappingCouchbaseConverter extends MappingCouchbaseConverter {
public CustomMappingCouchbaseConverter(final MappingContext<? extends CouchbasePersistentEntity<?>,
CouchbasePersistentProperty> mappingContext, final String typeKey) {
super(mappingContext, typeKey);
this.typeMapper = new TypeBasedCouchbaseTypeMapper(typeKey);
}
}
Run Code Online (Sandbox Code Playgroud)
和自定义注释@DocumentType
@Persistent
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface DocumentType {
String value();
}
Run Code Online (Sandbox Code Playgroud)
然后创建TypeAwareTypeInformationMapper它,仅检查实体是否被注释,@DocumentType如果是,则使用该注释中的值,如果没有则使用默认值(完全限定的类名)
public class TypeAwareTypeInformationMapper extends SimpleTypeInformationMapper {
@Override
public Alias createAliasFor(TypeInformation<?> type) {
DocumentType[] documentType = type.getType().getAnnotationsByType(DocumentType.class);
if (documentType.length == 1) {
return Alias.of(documentType[0].value());
}
return super.createAliasFor(type);
}
}
Run Code Online (Sandbox Code Playgroud)
然后注册如下
public class TypeBasedCouchbaseTypeMapper extends DefaultTypeMapper<CouchbaseDocument> implements CouchbaseTypeMapper {
private final String typeKey;
public TypeBasedCouchbaseTypeMapper(final String typeKey) {
super(new DefaultCouchbaseTypeMapper.CouchbaseDocumentTypeAliasAccessor(typeKey),
Collections.singletonList(new TypeAwareTypeInformationMapper()));
this.typeKey = typeKey;
}
@Override
public String getTypeKey() {
return typeKey;
}
}
Run Code Online (Sandbox Code Playgroud)