我观看了 youtube video 并在我的项目中实现了数据库
数据库.kt:
@Database(entities = [Result::class], version = DATABASE_VERSION, exportSchema = false)
abstract class ResultDatabase : RoomDatabase() {
abstract fun resultDao(): ResultDao
companion object {
@Volatile
private var INSTANCE: ResultDatabase? = null
fun getDatabase(context: Context): ResultDatabase {
val tempInstance = INSTANCE
if (tempInstance != null) {
return tempInstance
}
synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
ResultDatabase::class.java,
TABLE_NAME
).build()
INSTANCE = instance
return instance
}
}
}
}
ResultClass.kt:
@Entity(tableName = TABLE_NAME)
data class Result(private val id: Int,
private val cheatingEnabled: Boolean,
private val cheatingSuccessful: Boolean,
private val min: Long,
private val max: Long,
private val result: Long,
private val time: LocalDateTime
)
ResultDao.kt:
@Dao
interface ResultDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
fun addResult(result: Result)
@Query(value = "SELECT * FROM random_data ORDER BY id ASC")
fun getAllResults(): LiveData<List<Result>>
}
Repo.kt
class ResultsRepository(private val resultDao: ResultDao) {
val resultHistory: LiveData<List<Result>> = resultDao.getAllResults()
fun addResult(result: Result) {
resultDao.addResult(result)
}
}
向数据库插入数据的函数:
private fun insertDataToDatabase(min: Long,
max: Long,
result: Long,
cheatingEnabled: Boolean,
cheatingSuccessful: Boolean
) {
val time = LocalDateTime.now()
val resultEntity = Result(0, cheatingEnabled, cheatingSuccessful, min, max, result, time)
viewModelScope.launch {
repository.addResult(resultEntity)
}
}
错误:
C:\Users\Maxim\AndroidStudioProjects\AdvancedNumberGenerator\app\build\tmp\kapt3\stubs\debug\com\example\advancednumbergenerator\database\Result.java:14: error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
private final java.time.LocalDateTime time = null;
^C:\Users\Maxim\AndroidStudioProjects\AdvancedNumberGenerator\app\build\tmp\kapt3\stubs\debug\com\example\advancednumbergenerator\database\Result.java:8: error: Cannot find getter for field.
private final int id = 0;
^C:\Users\Maxim\AndroidStudioProjects\AdvancedNumberGenerator\app\build\tmp\kapt3\stubs\debug\com\example\advancednumbergenerator\database\Result.java:9: error: Cannot find getter for field.
private final boolean cheatingEnabled = false;
^C:\Users\Maxim\AndroidStudioProjects\AdvancedNumberGenerator\app\build\tmp\kapt3\stubs\debug\com\example\advancednumbergenerator\database\Result.java:10: error: Cannot find getter for field.
private final boolean cheatingSuccessful = false;
^C:\Users\Maxim\AndroidStudioProjects\AdvancedNumberGenerator\app\build\tmp\kapt3\stubs\debug\com\example\advancednumbergenerator\database\Result.java:11: error: Cannot find getter for field.
private final long min = 0L;
^C:\Users\Maxim\AndroidStudioProjects\AdvancedNumberGenerator\app\build\tmp\kapt3\stubs\debug\com\example\advancednumbergenerator\database\Result.java:12: error: Cannot find getter for field.
private final long max = 0L;
^C:\Users\Maxim\AndroidStudioProjects\AdvancedNumberGenerator\app\build\tmp\kapt3\stubs\debug\com\example\advancednumbergenerator\database\Result.java:13: error: Cannot find getter for field.
private final long result = 0L;
^C:\Users\Maxim\AndroidStudioProjects\AdvancedNumberGenerator\app\build\tmp\kapt3\stubs\debug\com\example\advancednumbergenerator\database\Result.java:14: error: Cannot find getter for field.
private final java.time.LocalDateTime time = null;
^C:\Users\Maxim\AndroidStudioProjects\AdvancedNumberGenerator\app\build\tmp\kapt3\stubs\debug\com\example\advancednumbergenerator\database\Result.java:7: error: An entity must have at least 1 field annotated with @PrimaryKey
公共最终类结果{ ^C:\Users\Maxim\AndroidStudioProjects\AdvancedNumberGenerator\app\build\tmp\kapt3\stubs\debug\com\example\advancednumbergenerator\database\Result.java:14:错误:无法弄清楚如何从光标。 私有最终 java.time.LocalDateTime time = null; ^
我该如何解决这个错误?可以使用 LocalDateTime 数据类型和 Long 而不是 int 连接吗?但我什至没有开始插入,我在构建时出错。我看到了类似的问题,有人建议使用 json 对象,但是来自 youtube 的人的项目没有 json 且没有任何错误。
答案 0 :(得分:1)
是否可以使用 LocalDateTime 数据类型和 Long 而不是 int 来连接?
是的。
<块引用>但我什至没有开始插入,我在构建时出错
Room 使用注释处理器 — 即您添加到 kapt
的 dependencies
语句。该注释处理器不知道如何处理 LocalDateTime
。而且,它不能与 private
Kotlin 属性一起使用。
我该如何解决这个错误?
首先从 private
上的这些属性中删除 Result
关键字。这应该将 LocalDateTime
的错误减少到 2。
然后,您需要教 Room 如何使用 LocalDateTime
。
为此,您需要一个带有一对 @TypeConverter
函数的类,这些函数可以在 LocalDateTime
和...之间进行转换。在 this sample 中,我有 Instant
和 Long
之间的类型转换器:
import androidx.room.TypeConverter
import java.time.Instant
class TypeTransmogrifier {
@TypeConverter
fun fromInstant(date: Instant?): Long? = date?.toEpochMilli()
@TypeConverter
fun toInstant(millisSinceEpoch: Long?): Instant? = millisSinceEpoch?.let {
Instant.ofEpochMilli(it)
}
}
然后,您需要将 @TypeConverters
注释(注意尾随的 s
)添加到某些内容以使用 @TypeConverter
注释注册您的类。一个简单的地方是在你的 @RoomDatabase
课上,就像我在 this sample 中所做的那样:
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
private const val DB_NAME = "stuff.db"
@Database(entities = [ToDoEntity::class], version = 1)
@TypeConverters(TypeTransmogrifier::class)
abstract class ToDoDatabase : RoomDatabase() {
abstract fun todoStore(): ToDoEntity.Store
companion object {
fun newInstance(context: Context) =
Room.databaseBuilder(context, ToDoDatabase::class.java, DB_NAME).build()
}
}
考虑到这两点,在 my sample project 中,我的任何实体都可以使用 Instant
。您会为 LocalDateTime
做同样的事情(或者,也许将您的实体从使用 LocalDateTime
切换到使用 Instant
)。
您可以在 the documentation 中阅读更多相关信息。