如何在数据库室中保存枚举字段?



我必须将enum枚举中的值写入数据库。编译过程中出错。我做错了什么?

无法弄清楚如何将此字段保存到数据库中。您可以考虑为其添加类型转换器。

@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
}
}
}

您可以对每个枚举进行转换,如下所示:

class Converters {
@TypeConverter
fun toHealth(value: String) = enumValueOf<Health>(value)
@TypeConverter
fun fromHealth(value: Health) = value.name
}

或者,如果您更喜欢将其存储为 SQLinteger,您也可以使用序号:

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 编译器中添加一个注释和一个 Enums 生成器。

最后,用下面注释数据库类、实体类、dao 类、dao 方法、dao 方法参数或实体字段类:

@TypeConverters(Converters::class)

这在 2.3.0-alpha4 版本中不再是问题:"如果没有提供,Room 现在将默认使用枚举到字符串,反之亦然。如果枚举的类型转换器已存在,Room 将优先使用它而不是默认转换器。

"如果枚举已经存在用于读取的单向类型转换器,Room 可能会意外使用可能不需要的内置字符串到枚举转换器。这是一个已知问题,可以通过使其成为双向转换器来解决。

要解决此问题,请使用@TypeConverters注释(而不是您的enum class)注释您的Database类。

例:

@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

枚举类;

enum class Priority {
HIGH,
MEDIUM,
LOW
}

转换器类;

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
}

对于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]);
}
}

从房间版本 2.3.0 开始,您可以保存枚举 看这里 https://developer.android.com/jetpack/androidx/releases/room?hl=ru#version_230_3

最新更新