类型转换
基于约定的映射
当未提供额外的映射元数据时,Neo4j 转换器有一些对象映射约定。约定如下:
-
Java 类短名称以以下方式映射到主标签:类
com.bigbank.SavingsAccount
映射到savingsAccount
主标签。 -
转换器使用在其上注册的任何 Spring Converter 来覆盖对象属性到节点字段和值的默认映射。
-
对象的字段用于与图中的字段相互转换。不使用公共的
JavaBean
属性。 -
如果您有一个非零参数构造函数,且其参数名称与节点的顶级属性名称匹配,则使用该构造函数。否则,使用零参数构造函数。如果存在多个非零参数构造函数,则会抛出异常。
我们开箱即用地支持广泛的类型转换。支持的 Cypher 类型列表请参阅官方驱动手册:类型映射。
原始类型或包装类型也同样支持。
领域类型 | Cypher 类型 | 直接映射到原生类型 |
---|---|---|
|
Boolean |
✔ |
|
布尔型列表 |
✔ |
|
Integer |
✔ |
|
整型列表 |
✔ |
|
Float |
✔ |
|
浮点型列表 |
✔ |
|
String |
✔ |
|
字符串列表 |
✔ |
|
ByteArray |
✔ |
|
长度为 1 的 ByteArray |
|
|
长度为 1 的 String |
|
|
长度为 1 的字符串列表 |
|
|
格式化为 ISO 8601 日期( |
|
|
String |
|
|
字符串列表 |
|
|
Integer |
|
|
整型列表 |
|
|
格式化为 BCP 47 语言标签的字符串 |
|
|
Integer |
|
|
整型列表 |
|
|
String |
|
|
String |
|
|
Date |
✔ |
|
Time |
✔ |
|
LocalTime |
✔ |
|
DateTime |
✔ |
|
LocalDateTime |
✔ |
|
DateTime |
|
|
DateTime |
|
|
String |
|
|
String |
|
|
Duration |
|
|
Duration |
|
|
Duration |
✔ |
|
Point |
✔ |
|
CRS 4326 的 Point |
|
|
CRS 4979 的 Point |
|
|
CRS 7203 的 Point |
|
|
CRS 9157 的 Point |
|
|
CRS 4326 的 Point,其中 x/y 对应于 lat/long |
|
Enum 实例 |
String(枚举的名称值) |
|
Enum[] 实例 |
字符串列表(枚举的名称值) |
|
|
String |
|
|
String |
|
|
String |
自定义类型转换
针对给定类型的属性
如果您希望在实体中使用自己的类型或将其作为 @Query
注解方法的参数,您可以定义并提供一个自定义转换器实现。首先,您必须实现一个 GenericConverter
并注册您的转换器应该处理的类型。对于实体属性类型转换器,您需要负责将您的类型与 Neo4j Java Driver Value
进行相互转换。如果您的转换器仅用于存储库中的自定义查询方法,则只需提供到 Value
类型的单向转换即可。
public class MyCustomTypeConverter implements GenericConverter {
@Override
public Set<ConvertiblePair> getConvertibleTypes() {
Set<ConvertiblePair> convertiblePairs = new HashSet<>();
convertiblePairs.add(new ConvertiblePair(MyCustomType.class, Value.class));
convertiblePairs.add(new ConvertiblePair(Value.class, MyCustomType.class));
return convertiblePairs;
}
@Override
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (MyCustomType.class.isAssignableFrom(sourceType.getType())) {
// convert to Neo4j Driver Value
return convertToNeo4jValue(source);
} else {
// convert to MyCustomType
return convertToMyCustomType(source);
}
}
}
要让 SDN 了解您的转换器,必须将其注册到 Neo4jConversions
中。为此,您需要创建一个类型为 org.springframework.data.neo4j.core.convert.Neo4jConversions
的 @Bean
。否则,Neo4jConversions
将在后台仅使用内部默认转换器创建。
@Bean
public Neo4jConversions neo4jConversions() {
Set<GenericConverter> additionalConverters = Collections.singleton(new MyCustomTypeConverter());
return new Neo4jConversions(additionalConverters);
}
如果您的应用程序需要多个转换器,您可以在 Neo4jConversions
构造函数中添加任意数量的转换器。
仅针对特定属性
如果您只需要针对某些特定属性进行转换,我们提供了 @ConvertWith
注解。这是一个可以应用于实体属性 (@Node
) 和关系属性 (@RelationshipProperties
) 的注解。它通过 converter
属性定义一个 Neo4jPersistentPropertyConverter
,并通过可选的 Neo4jPersistentPropertyConverterFactory
来构建它。通过实现 Neo4jPersistentPropertyConverter
,可以处理给定类型的所有特定转换。此外,@ConvertWith
还提供了 converterRef
,用于引用应用上下文中实现 Neo4jPersistentPropertyConverter
的任何 Spring bean。引用 bean 会优先于构建新的转换器。
我们提供 @DateLong
和 @DateString
作为元注解,用于与不使用原生类型的 Neo4j-OGM 方案向后兼容。这些是基于上述概念构建的元注解。
复合属性
使用 @CompositeProperty
注解,类型为 Map<String, Object>
或 Map<? extends Enum, Object>
的属性可以作为复合属性存储。map 中的所有条目将作为属性添加到包含该属性的节点或关系中。可以带配置的前缀,或使用属性名称作为前缀。虽然我们开箱即用只为 map 提供了此功能,但您可以实现 Neo4jPersistentPropertyToMapConverter
并将其配置为在 @CompositeProperty
上使用的转换器。Neo4jPersistentPropertyToMapConverter
需要知道如何将给定类型分解成 map,以及如何从 map 重新组合。