转换
基于约定的映射
Neo4j 转换器在未提供额外映射元数据时,有一些默认的对象映射规则。这些规则如下:
-
简短的 Java 类名按以下方式映射到主标签:类
com.bigbank.SavingsAccount
映射到savingsAccount
主标签。 -
转换器使用任何已注册的 Spring Converter 来覆盖对象属性到节点字段和值的默认映射。
-
对象的字段用于在图中进行字段的转换。公共的
JavaBean
属性不会被使用。 -
如果你有一个非零参数构造函数,并且其构造函数参数名称与节点的顶级属性名称匹配,那么将使用该构造函数。否则,将使用零参数构造函数。如果有多个非零参数构造函数,则会抛出异常。
我们支持广泛的转换功能,开箱即用。您可以在官方驱动程序手册中找到支持的 Cypher 类型列表:类型映射。
原始类型的包装类型同样得到支持。
域类型 | Cypher 类型 | 直接映射到原生类型 |
---|---|---|
java.lang.Boolean | Boolean | ✔ |
boolean[] | 布尔列表 | ✔ |
java.lang.Long | Integer | ✔ |
long[] | 整数列表 | ✔ |
java.lang.Double | Float | ✔ |
double[] | 浮点数列表 | ✔ |
java.lang.String | String | ✔ |
java.lang.String[] | 字符串列表 | ✔ |
byte[] | ByteArray | ✔ |
java.lang.Byte | 长度为 1 的 ByteArray | |
java.lang.Character | 长度为 1 的字符串 | |
char[] | 长度为 1 的字符串列表 | |
java.util.Date | 格式化为 ISO 8601 日期的字符串 (yyyy-MM-dd’T’HH:mm:ss.SSSZ )。注意 Z :SDN 会将所有 java.util.Date 实例存储为 UTC 。如果需要时区,请使用支持时区的类型(如 ZoneDateTime )或将时区存储为单独属性。 | |
java.lang.Float | String | |
float[] | 字符串列表 | |
java.lang.Integer | Integer | |
int[] | 整数列表 | |
java.util.Locale | 格式化为 BCP 47 语言标签的字符串 | |
java.lang.Short | Integer | |
short[] | 整数列表 | |
java.math.BigDecimal | String | |
java.math.BigInteger | String | |
java.time.LocalDate | Date | ✔ |
java.time.OffsetTime | Time | ✔ |
java.time.LocalTime | LocalTime | ✔ |
java.time.ZonedDateTime | DateTime | ✔ |
java.time.LocalDateTime | LocalDateTime | ✔ |
java.time.OffsetDateTime | DateTime | |
java.time.Instant | DateTime | |
java.util.TimeZone | String | |
java.time.ZoneId | String | |
java.time.Period | Duration | |
java.time.Duration | Duration | |
org.neo4j.driver.types.IsoDuration | Duration | ✔ |
org.neo4j.driver.types.Point | Point | ✔ |
org.springframework.data.neo4j.types.GeographicPoint2d | CRS 为 4326 的 Point | |
org.springframework.data.neo4j.types.GeographicPoint3d | CRS 为 4979 的 Point | |
org.springframework.data.neo4j.types.CartesianPoint2d | CRS 为 7203 的 Point | |
org.springframework.data.neo4j.types.CartesianPoint3d | CRS 为 9157 的 Point | |
org.springframework.data.geo.Point | CRS 为 4326 且 x/y 对应纬度/经度的 Point | |
Enum 的实例 | 字符串(枚举的名称值) | |
Enum[] 的实例 | 字符串列表(枚举的名称值) | |
java.net.URL | String | |
java.net.URI | String | |
java.util.UUID | String |
自定义转换
针对给定类型的属性
如果您更倾向于在实体中使用自己的类型或作为 @Query
注解方法的参数,您可以定义并提供一个自定义的转换器实现。首先,您需要实现一个 GenericConverter
,并注册您的转换器应处理的类型。对于实体属性类型转换器,您需要处理将您的类型转换为 Neo4j Java Driver 的 Value
类型以及从 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 中重新组合。