如何在数据库机房中保存枚举字段?
How to save enum field in the database room?
我必须将 enum
枚举的值写入数据库。编译过程中发生错误。我做错了什么?
Cannot figure out how to save this field into database. You can consider adding a type converter for it.
@ColumnInfo(name = "state_of_health")
@TypeConverters(HealthConverter::class)
var health: Health
enum class Health(val value: Int){
NONE(-1),
VERY_BAD(0),
...
}
class HealthConverter{
@TypeConverter
fun fromHealth(value: Health): Int{
return value.ordinal
}
@TypeConverter
fun toHealth(value: Int): Health{
return when(value){
-1 -> Health.NONE
0 -> Health.VERY_BAD
...
else -> Health.EXCELLENT
}
}
}
要解决此问题,请使用 @TypeConverters
注释(而不是 enum class
)注释您的 Database
class。
示例:
@Database(entities = arrayOf(User::class), version = 1)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
勾选https://developer.android.com/training/data-storage/room/referencing-data
您可以对每个枚举进行转换,如下所示:
class Converters {
@TypeConverter
fun toHealth(value: String) = enumValueOf<Health>(value)
@TypeConverter
fun fromHealth(value: Health) = value.name
}
或者如果您更喜欢将其存储为 SQL integer
,您也可以使用序数:
class Converters {
@TypeConverter
fun toHealth(value: Int) = enumValues<Health>()[value]
@TypeConverter
fun fromHealth(value: Health) = value.ordinal
}
不幸的是,无法使用泛型 Enum<T>
来完成此操作,因为未绑定的泛型会引发错误 Cannot use unbound generics in Type Converters
。
Android Room 团队可以认真地为他们的 kapt 编译器添加注释和枚举生成器。
最后,注释数据库class、实体class、dao class、dao方法、dao方法参数或实体字段class:
@TypeConverters(Converters::class)
对于 java 开发者
枚举
public enum Health {
NONE(-1),
VERY_BAD(0);
public final int value;
Health(int newValue) {
value = newValue;
}
public int getValue() {
return value;
}
}
类型转换器
public class HealthConverter {
/**
* Convert Health to an integer
*/
@TypeConverter
public static int fromHealthToInt(Health value) {
return value.ordinal();
}
/**
* Convert an integer to Health
*/
@TypeConverter
public static Health fromIntToHealth(int value) {
return (Health.values()[value]);
}
}
枚举class;
enum class Priority {
HIGH,
MEDIUM,
LOW
}
转换器class;
class Converter {
@TypeConverter
fun fromPriority(priority: Priority): String {
return priority.name
}
@TypeConverter
fun toPriority(priority: String): Priority {
return Priority.valueOf(priority)
}
}
用法;
@Database(entities = [MyData::class], version = 1, exportSchema = false)
@TypeConverters(Converter::class)
abstract class MyDatabase : RoomDatabase() {
// todo
}
这在 version 2.3.0-alpha4 中不再是问题:“如果提供 none,Room 现在将默认使用枚举到字符串,反之亦然。如果枚举的类型转换器已经存在,Room 将优先使用它而不是默认的。"
“如果枚举已经存在用于读取的单向类型转换器,Room 可能会意外使用内置的字符串到枚举转换器,这可能是不需要的。这是一个已知问题,可以通过使它是一个双向转换器。"
自 Room 版本 2.3.0 起,您可以在此处保存 Enum Look https://developer.android.com/jetpack/androidx/releases/room?hl=ru#version_230_3
我必须将 enum
枚举的值写入数据库。编译过程中发生错误。我做错了什么?
Cannot figure out how to save this field into database. You can consider adding a type converter for it.
@ColumnInfo(name = "state_of_health")
@TypeConverters(HealthConverter::class)
var health: Health
enum class Health(val value: Int){
NONE(-1),
VERY_BAD(0),
...
}
class HealthConverter{
@TypeConverter
fun fromHealth(value: Health): Int{
return value.ordinal
}
@TypeConverter
fun toHealth(value: Int): Health{
return when(value){
-1 -> Health.NONE
0 -> Health.VERY_BAD
...
else -> Health.EXCELLENT
}
}
}
要解决此问题,请使用 @TypeConverters
注释(而不是 enum class
)注释您的 Database
class。
示例:
@Database(entities = arrayOf(User::class), version = 1)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
勾选https://developer.android.com/training/data-storage/room/referencing-data
您可以对每个枚举进行转换,如下所示:
class Converters {
@TypeConverter
fun toHealth(value: String) = enumValueOf<Health>(value)
@TypeConverter
fun fromHealth(value: Health) = value.name
}
或者如果您更喜欢将其存储为 SQL integer
,您也可以使用序数:
class Converters {
@TypeConverter
fun toHealth(value: Int) = enumValues<Health>()[value]
@TypeConverter
fun fromHealth(value: Health) = value.ordinal
}
不幸的是,无法使用泛型 Enum<T>
来完成此操作,因为未绑定的泛型会引发错误 Cannot use unbound generics in Type Converters
。
Android Room 团队可以认真地为他们的 kapt 编译器添加注释和枚举生成器。
最后,注释数据库class、实体class、dao class、dao方法、dao方法参数或实体字段class:
@TypeConverters(Converters::class)
对于 java 开发者
枚举
public enum Health {
NONE(-1),
VERY_BAD(0);
public final int value;
Health(int newValue) {
value = newValue;
}
public int getValue() {
return value;
}
}
类型转换器
public class HealthConverter {
/**
* Convert Health to an integer
*/
@TypeConverter
public static int fromHealthToInt(Health value) {
return value.ordinal();
}
/**
* Convert an integer to Health
*/
@TypeConverter
public static Health fromIntToHealth(int value) {
return (Health.values()[value]);
}
}
枚举class;
enum class Priority {
HIGH,
MEDIUM,
LOW
}
转换器class;
class Converter {
@TypeConverter
fun fromPriority(priority: Priority): String {
return priority.name
}
@TypeConverter
fun toPriority(priority: String): Priority {
return Priority.valueOf(priority)
}
}
用法;
@Database(entities = [MyData::class], version = 1, exportSchema = false)
@TypeConverters(Converter::class)
abstract class MyDatabase : RoomDatabase() {
// todo
}
这在 version 2.3.0-alpha4 中不再是问题:“如果提供 none,Room 现在将默认使用枚举到字符串,反之亦然。如果枚举的类型转换器已经存在,Room 将优先使用它而不是默认的。"
“如果枚举已经存在用于读取的单向类型转换器,Room 可能会意外使用内置的字符串到枚举转换器,这可能是不需要的。这是一个已知问题,可以通过使它是一个双向转换器。"
自 Room 版本 2.3.0 起,您可以在此处保存 Enum Look https://developer.android.com/jetpack/androidx/releases/room?hl=ru#version_230_3