我的问题是如何存储
List<Enum>
在 RoomDatabase 中,到目前为止我没有找到答案。
枚举:
public enum HelloEnum {
A,
B,
C
}
转换器:
public class EnumConverter {
@TypeConverter
public List<HelloEnum> storedStringToEnum(String value) {
List<String> dbValues = Arrays.asList(value.split("\\s*,\\s*"));
List<HelloEnum> enums = new ArrayList<>();
for (String s: dbValues)
enums.add(HelloEnum.valueOf(s));
return enums;
}
@TypeConverter
public String languagesToStoredString(List<HelloEnum> cl) {
String value = "";
for (HelloEnum lang : cl)
value += lang.name() + ",";
return value;
}
}
在插入和获取您的数据方面,这不会被问到问题。
@Dao
public interface HelloPojoDao {
@Query("SELECT * FROM helloPojo")
List<HelloPojo> fetchAll();
@Insert
void insertPojo(HelloPojo pojo);
}
但是,我要指出,现在按枚举进行过滤变得更加棘手。例如,如果您想编写一个查询来获取包含 enum.A 和 enum.B 的对象,则必须构建一个查询来为它们查询字符串对象。在这种情况下,“SELECT * FROM pojo WHERE enums contains 'A,' and 'B,'。因此,最好为您的枚举分配数字值(作为@Kuffs 答案详细信息),因为解析整数可能会产生比解析字符串。
希望这能解决您的问题。欢迎在评论区提出任何问题,祝您狩猎愉快!
好的,使用 Kotlin 更简单,当使用name
class EnumTypeConverter {
@TypeConverter
fun restoreEnum(enumName: String): EnumType = EnumType.valueOf(enumName)
@TypeConverter
fun saveEnumToString(enumType: EnumType) = enumType.name
}
让我展示使用 kotlin 持久化/检索它的方式。
在操作过程中我们有什么限制?
toString
列表到字符串的默认方法,因为它可能取决于我们确切使用的环境因此,在我看来,正确的实施将如下所示:
Enumerable
所有持久化到数据库的枚举类都应该实现的接口因此,Enumerable 接口:
/** marks the enum with custom int code for each value */
interface Enumerable {
val code: Int
}
枚举示例:
enum class PaymentSystemEntity constructor(
override val code: Int
) : Enumerable {
VISA(1),
MASTERCARD(2),
UNKNOWN(0);
companion object {
fun parseFromCode(code: Int): PaymentSystemEntity = values()
.firstOrNull { it.code == code } ?: UNKNOWN
}
}
序列化扩展:
fun <T> List<T>.asString(): String where T : Enum<T>, T : Enumerable = this
.map { it.code }
.joinToString(separator = ",")
fun <T> String.toEnumList(creator: (code: Int) -> T): List<T> where T : Enum<T>, T : Enumerable = this
.split(',')
.map { it.toInt() }
.map { creator(it) }
枚举的样本类型转换器:
class PaymentSystemTypeConverter {
@TypeConverter
fun paymentSystemsToString(value: List<@JvmSuppressWildcards PaymentSystemEntity>): String =
value.asString()
@TypeConverter
fun stringToPaymentSystems(value: String): List<@JvmSuppressWildcards PaymentSystemEntity> =
value.toEnumList { PaymentSystemEntity.parseFromCode(it) }
}
您可能以相同的方式实现了其他类型的集合
Kotlin 中的 Jack Dalton 版本:
@TypeConverter
fun storedStringListLineType(value: String): List<LineType> {
val dbValues = value.split("\\s*,\\s*".toRegex()).dropLastWhile { it.isEmpty() }
val enums: MutableList<LineType> = ArrayList()
for (s in dbValues)
enums.add(LineType.valueOf(s))
return enums
}
@TypeConverter
fun listLineTypeToStoredString(listLineTypes: List<LineType>): String {
var value = ""
for (lineType in listLineTypes)
value += lineType.name + ","
return value
}