Scala Provider
基本概念
在前面的文档中,我们介绍过如何映射枚举,以及如何使用@Serialized
映射JSON。
但是,有的时候,以上两种方法都无法满足我们的要求,这时我们可以使用ScalarProvider
。
可以为SqlClient注册多个ScalarProvider
,每个ScalarProvider
告诉Jimmer如何处理一种自定义数据类型。
ScalarProvider
分为两种:
-
全局级
定义Java/Kotlin类型和数据库类型的映射规则,全局统一。任何实体定义中包含该类型的属性都会被全局
ScalarProvider
统一处理。备注全局级
ScalarProvider
只能处理非集合类型,比如:类、接口、枚举。不能处理类型为:Array
、Collection
、Map
等集合类型。 -
属性级
对某个特定的实体属性,定义Java/Kotlin类型和数据库类型的映射规则。
备注-
属性级
ScalarProvider
可以处理任何非Jimmer内置的类型。包括集合类型,比如:Array
、Collection
,Map
。 -
如果被映射的属性类型是集合类型,该属性需要被
@org.babyfish.jimmer.Scalar
修饰。
-
JSON映射一文阐述了@Serialized
注解,既可以修饰属性返回的类型也可以修饰实体属性,
就是因为更底层的ScalarProvider
有两种。
ScalarProvider
是Jimmer提供的一个SPI接口,其定义如下:
package org.babyfish.jimmer.sql.runtime;
import java.util.function.Consumer;
public abstract class ScalarProvider<T ❶, S ❷> {
protected ScalarProvider(Class<T> scalarType, Class<S> sqlType) { ❸
...省略代码...
}
protected ScalarProvider() { ❹
...省略代码...
}
public abstract T toScalar(S sqlValue); ❺
public abstract S toSql(T scalarValue); ❻
public Collection<ImmutableProp> getHandledProps() { ❼
return null;
}
}
-
❶ 范型参数
T
: Java/Kotlin中数据类型; -
❷ 范型参数
S
: 数据库中数据类型; -
❸ 明确指定
T
和S
所代表类型的构造函数;这个构造函数通常用于定义通用性和可复用性较强的
ScalarProvider
。 -
❹ 无需明确指定
T
和S
所代表类型的构造函数;要求派生类明确指定范型参数
T
和S
,让Jimmer可以自动分析出T
和S
所代表类型。否则,会异常。这个构造函数通常用于定义特定类型所对应的
ScalarProvider
,不要求通用性和可复用性。 -
❺ 方法
toScalar
: 把数据库中读取到的非null数据转换为Java数据; -
❻ 方法
toSql
: 把Java的非null数据转换为数据库可接受的数据; -
❼ 如果要定义属性级
ScalarProvider
,有一种选择 (也有其他选择) 是在派生类中覆盖方法getHandledProps
;
全局级ScalarProvider
例如当前数据库不支持UUID类型,可以如此处理:
定义ScalarProvider
- Java
- Kotlin
public class UUIDScalarProvider extends AbstractScalarProvider<UUID, String> {
@Override
public UUID toScalar(String sqlValue) {
return UUID.fromString(sqlValue);
}
@Override
public String toSql(UUID scalarValue) {
return scalarValue.toString();
}
}
class UUIDScalarProvider : ScalarProvider<UUID, String> {
override fun toScalar(sqlValue: String): UUID =
UUID.fromString(sqlValue)
override fun toSql(scalarValue: UUID): String =
scalarValue.toString()
}
注册Scalar Provider
有两种方法可以让Jimmer注册ScalarProvider
:
-
使用Spring Boot Starter
让
ScalarProvider
的各派生类被Spring托管即可。有两种选择。-
修改上面的
UUIDScalarProvider
类,用spring的@Component
修饰- Java
- Kotlin
UUIDScalarProvider.java@Component
public class UUIDScalarProvider extends AbstractScalarProvider<UUID, String> {
...省略代码...
}UUIDScalarProvider.kt@Component
class UUIDScalarProvider : ScalarProvider<UUID, String> {
...省略代码...
} -
用Spring的
@Bean
方法,向Spring注册UUIDScalaProvider对象- Java
- Kotlin
@Bean
public UUIDScalarProvider uuidScalarProvider() {
return new UUIDScalarProvider();
}@Bean
fun uuidScalarProvider(): UUIDScalarProvider =
UnitTestIdGenerator()
-