转换
基于约定的映射
Neo4j 转换器在没有提供其他映射元数据时,有一些用于映射对象的约定。这些约定是:
-
简短的 Java 类名将映射到主标签,方式如下:类 `com.bigbank.SavingsAccount` 映射到 `savingsAccount` 主标签。
-
转换器使用与其注册的任何 Spring 转换器 来覆盖对象属性到节点字段和值的默认映射。
-
对象的字段用于在图中进行转换。不使用公共 `JavaBean` 属性。
-
如果只有一个非零参数构造函数,其构造函数参数名称与节点的顶级属性名称匹配,则使用该构造函数。否则,将使用零参数构造函数。如果有多个非零参数构造函数,则会抛出异常。
我们开箱即用地支持各种转换。在官方驱动程序手册中查找受支持的 Cypher 类型列表:类型映射。
同样支持基本类型或包装类型。
域类型 | Cypher 类型 | 直接映射到原生类型 |
---|---|---|
|
Boolean |
✔ |
|
Boolean 列表 |
✔ |
|
Integer |
✔ |
|
Integer 列表 |
✔ |
|
Float |
✔ |
|
Float 列表 |
✔ |
|
String |
✔ |
|
String 列表 |
✔ |
|
ByteArray |
✔ |
|
长度为 1 的 ByteArray |
|
|
长度为 1 的 String |
|
|
长度为 1 的 String 列表 |
|
|
格式化为 ISO 8601 日期 ( `yyyy-MM-dd'T'HH:mm:ss.SSSZ` ) 的字符串。注意 `Z`:SDN 将以 `UTC` 存储所有 `java.util.Date` 实例。如果您需要时区,请使用支持它的类型(即 `ZoneDateTime`)或将时区存储为单独的属性。 |
|
|
String |
|
|
String 列表 |
|
|
Integer |
|
|
Integer 列表 |
|
|
格式化为 BCP 47 语言标签的字符串 |
|
|
Integer |
|
|
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 且 x/y 对应于经/纬度的 Point |
|
枚举 (`Enum`) 实例 |
String(枚举的名称值) |
|
枚举数组 (`Enum[]`) 实例 |
String 列表(枚举的名称值) |
|
|
String |
|
|
String |
|
|
String |
自定义转换
针对给定类型的属性
如果您更喜欢在实体中或作为 `@Query` 注解方法的参数使用您自己的类型,您可以定义和提供自定义转换器实现。首先,您必须实现一个 `GenericConverter` 并注册您的转换器应该处理的类型。对于实体属性类型转换器,您需要处理将您的类型转换为 **和** 从 Neo4j Java 驱动程序 `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>
类型的属性存储为复合属性。映射中的所有条目都将作为属性添加到包含该属性的节点或关系中。可以使用配置的前缀,或者以属性名称为前缀。虽然我们只为映射提供开箱即用的功能,但您可以使用Neo4jPersistentPropertyToMapConverter
并将其配置为在@CompositeProperty
上使用的转换器。Neo4jPersistentPropertyToMapConverter
需要知道如何将给定类型分解成映射以及如何从映射中重新组合。