Enum Mapping
Jimmer handles enums in two ways:
-
Map to string: A choice with better understandability and traceability, also the default option.
-
Map to integer: A choice with better performance-first.
Jimmer provides two annotations for enums:
-
org.babyfish.jimmer.sql.EnumType
: Decorate enum types, optionalSpecify mapping method, map to string or ordinal position to integer
-
org.babyfish.jimmer.sql.EnumItem
: Decorate enum items, optionalOverride the mapped string value or integer value for some enum item
Map to String
- Java
- Kotlin
@EnumType(EnumType.Strategy.NAME)
public enum Gender {
MALE,
FEMALE
}
@EnumType(EnumType.Strategy.NAME)
enum class Gender {
MALE,
FEMALE
}
Here, the parameter of @EnumType
is specified as "NAME", indicating mapping to string. By default, the mapped string values of the two enum items are the same as their names, i.e. "MALE" and "FEMALE".
If you expect the mapped strings to be different from the enum item names, you can decorate the enum items with @EnumItem
.
- Java
- Kotlin
@EnumType(EnumType.Strategy.NAME)
public enum Gender {
@EnumItem(name = "M")
MALE,
@EnumItem(name = "F")
FEMALE
}
@EnumType(EnumType.Strategy.NAME)
enum class Gender {
@EnumItem(name = "M")
MALE,
@EnumItem(name = "F")
FEMALE
}
Map to Integer
- Java
- Kotlin
@EnumType(EnumType.Strategy.ORDINAL)
public enum Gender {
MALE,
FEMALE
}
@EnumType(EnumType.Strategy.ORDINAL)
enum class Gender {
MALE,
FEMALE
}
Here, the parameter of @EnumType
is specified as "ORDINAL", indicating mapping to integer. By default, the mapped integer values of the two enum items are the same as their ordinal
, i.e. 0 and 1.
If you expect the mapped integers to be different from the enum items' ordinal
, you can decorate the enum items with @EnumItem
.
- Java
- Kotlin
@EnumType(EnumType.Strategy.ORDINAL)
public enum Gender {
@EnumItem(ordinal = 100)
MALE,
@EnumItem(ordinal = 200)
FEMALE
}
@EnumType(EnumType.Strategy.ORDINAL)
enum class Gender {
@EnumItem(ordinal = 100)
MALE,
@EnumItem(ordinal = 200)
FEMALE
}
Do Not Explicitly Use @EnumType
You can also avoid specifying the @EnumType annotation for enum types, that is, not explicitly indicate whether an enum type should be mapped to string or integer.
In this case, Jimmer will refer to the default global configuration.
The default value of this global configuration is "NAME". If you need "ORDINAL", please override the global configuration.
Next, we show how to override the global configuration:
-
When using SpringBoot
Add configuration item
jimmer.default-enum-strategy
inapplication.yml
orapplication.properties
and set its value to "ORDINAL" -
When not using SpringBoot
- Java
- Kotlin
JSqlClient sqlClient = JSqlClient
.newBuilder()
.setDefaultEnumStrategy(EnumType.Strategy.ORDINAL)
...Omit other configurations...
.build();val sqlClient = newKSqlClient {
setDefaultEnumStrategy(EnumType.Strategy.ORDINAL)
...Omit other configurations...
}
Work with TypeScript Client and Jackson
The serialization of a type to JSON and its storage in the database are two independent matters. The content described above focuses on how Jimmer handles enum mapping in the database, which is unrelated to JSON.
By default, Jackson converts enums to its name, so when generating the TypeScript Client, Jimmer maps the enum according to its name.
- Java
- Kotlin
enum Gender {
MAN,
WOMAN
}
enum class Gender {
MAN,
WOMAN
}
The generated TypeScript code is as follows:
export const GenderEnum_CONSTANTS = [
'MAN',
'WOMAN'
] as const;
export type GenderEnum = typeof GenderEnum_CONSTANTS[number];
//usage
export type PersonDto = {
gender: GenderEnum;
}
If you want to customize the JSON serialization, you need to use the @JsonValue annotation from Jackson.
- Java
- Kotlin
enum Gender {
MAN,
WOMAN;
@JsonValue
public String getValue() {
return name().toLowerCase();
}
}
enum class Gender {
MAN,
WOMAN;
@JsonValue
fun getValue(): String {
return name().toLowerCase();
}
}
When detects the presence of annotations like @JsonValue, Jimmer not knowing how the enum will be converted during JSON serialization, so jimmer will translates the enum type to a string. The generated TypeScript code in this case is as follows:
export type PersonDto = {
gender: string;
}