JSON映射
Jimmer支持JSON属性。在Java/Kotlin实体类型中,这种属性可以被声明为除了java.lang.Object
和kotlin.Any
外的任何类型,在数据库中,对应列的存储的信息是JSON。
-
JSON属性是简单属性,而非关联属性。
-
按目前实现,Postgres中对应列的类型应为
jsonb
,其他数据库中对应列的类型应为字符串。
Jimmer提供org.babyfish.jimmer.sql.Serialized
,有两种使用JSON映射的方式
-
全局JSON映射
如果属性的类型是自定义类,而非数组、集合或Map。可以用
@Serialized
修饰这个类。这样,任何实体中相同类型的属性都会成为JSON属性。 -
属性级JSON映射
无论属性是什么类型,都可以使用
@Serialized
修饰当前属性。
数组、集合或Map类型的属性必须使用属性级映射;然而,对于自定义的类型而言,使用全局配置映射。
全局JSON映射
首先,定义自 定义类,并用@Serialized
修饰
- Java
- Kotlin
@Serialized
public class UserType {
...省略成员,可包含任意信息...
...只要支持Json序列化/反序列化即可...
}
@Serialized
data class UserType(
...省略参数,可包含任何信息...
...只要支持Json序列化/反序列化即可...
)
然后,就可以使用UserType
类型定义任何实体属性了
- Java
- Kotlin
@Entity
public interface Book {
UserType userData();
...省略其他类型...
}
@Entity
interface Book {
val userData: UserType
...省略其他类型...
}
属性级JSON映射
直接用@Serialized
修饰属性即可
- Java
- Kotlin
@Entity
public interface Book {
@Serialized
List<Map<String, SomeType1>> userData1();
@Serialized
Map<String, List<SomeType2>> userData2();
...省略其他类型...
}
@Entity
interface Book {
@Serialized
val userData1: List<Map<String, SomeType1>>
@Serialized
val userData2: Map<String, List<SomeType2>>
...省略其他类型...
}
ObjectMapper配置
使用底层API
开发人员可以为被@Serialized
修饰的属性配置JSON序列化/反序列化的ObjectMapper。
- Java
- Kotlin
ObjectMapper mapper1 = ...略...;
ObjectMapper mapper2 = ...略...;
ObjectMapper mapper3 = ...略...;
JSqlClient sqlClient = JSqlClient
.newBuilder()
.setDefaultSerializedTypeObjectMapper(mapper1) ❶
.setSerializedTypeObjectMapper(MetaConfig.class, mapper2) ❷
.setSerializedTypePropMapper(TopicProps.TAGS, mapper3) ❸
...省略其他配置...
.build();
val mapper1: ObjectMapper = ...略...
val mapper2: ObjectMapper = ...略...
val mapper3: ObjectMapper = ...略...
val sqlClient = newKSqlClient {
setDefaultSerializedTypeObjectMapper(mapper1) ❶
setSerializedTypeObjectMapper(MetaConfig::class, mapper2) ❷
setSerializedTypePropMapper(Topic::tags, mapper3) ❸
...省略其他配置...
}
-
❶ 将默认的ObjectMapper设置为
mapper1
和
setSerializedTypeObjectMapper(Object.class, mapper1)
等价 -
❷ 任何属性,只要其返回类型为MetaConfig或其派生类型,都采用
mapper2
-
❸ 明确设置
Topic.tags
的ObjectMappermapper3
如果被设置的属性未被
@Serialized
修饰,将会抛出异常
配置优先级:❸ > ❷ > ❶
使用Spring Boot Starter
如果使用Spring Boot Starter,SqlClient是自动创建的,但是用户可以通过Customizer/KCustomizer
来改变SqlClient被创建前的配置
- Java
- Kotlin
@Component
public class SerializationCustomizer implements Customizer {
@Override
public void customize(JSqlClient.Builder builder) {
builder
.setDefaultSerializedTypeObjectMapper(...略...)
.setSerializedTypeObjectMapper(MetaConfig.class, ...略...)
.setSerializedTypePropMapper(TopicProps.TAGS, ...略...);
}
}
@Component
class SerializationCustomizer : KCustomizer {
override fun customize(dsl: KSqlClientDsl) {
dsl
.setDefaultSerializedTypeObjectMapper(...略...)
.setSerializedTypeObjectMapper(MetaConfig::class, ...略...)
.setSerializedTypePropMapper(Topic::tags, ...略...);
}
}