简单使用笔记
MyDatabase
@Database(
entities = [xxxEntity::class],
version = 1
)
abstract class MyDatabase : RoomDatabase() {
// Dao
abstract fun getXxxDao(): xxxDao
companion object {
@Volatile
private var INSTANCE: MyDatabase? = null
/**
* 获取Database单例
*/
fun getInstance(): MyDatabase =
INSTANCE ?: synchronized(this) {
INSTANCE ?: buildDatabase().also {
INSTANCE = it
}
}
/**
* 创建Database
*/
private fun buildDatabase() =
Room.databaseBuilder(
getApplication(),
MyDatabase::class.java,
"xxx.db"
)
.allowMainThreadQueries() // 允许在主线程访问数据库
.fallbackToDestructiveMigration() // 删除数据库重新创建
.build()
/**
* 关闭数据库
*/
fun closeDB() {
INSTANCE?.apply {
if (this.isOpen) {
this.close()
INSTANCE = null
}
}
}
}
}
指定schemas
生成的文件路径, 这个json中可以看到各张表如何生成的.
defaultConfig {
javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/build/schemas".toString()]
}
}
}
xxxDao
@Dao
interface xxxDao {
// 查找全部
@Query("select * from XXX")
fun findAll(): List<User>
// 根据集合条件查找
@Query("SELECT * FROM XXX WHERE `current_date` IN (:array)")
fun findByArray(array:List<String>): List<User>?
// 根据日期查找
@Query("SELECT * FROM XXX WHERE `current_date` = :date")
fun finByDate(date: String): User?
// 插入对象, 如果表中某条数据主键和这个对象主键一样就直接覆盖,如果不存在重复的就直接插入.
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insert(user: User)
// 按照主键更新数据
@Update
fun update(user: User)
// 按照主键删除数据
@Delete
fun delete(user: User)
}
xxxEntity
// 父类,可以方便使用多态
open class Info(
open val date: String,
open var time: Long,
open var calorie: Double,
)
@Entity(tableName = "XXX")
data class XXX(
@PrimaryKey @ColumnInfo(name = "current_date") override val date: String,
@ColumnInfo(name = "time") override var time: Long,
@ColumnInfo(name = "calorie") override var calorie: Double,
) : Info(date, time, calorie)
问题总结
- 需要一张表对应一个
DAO
吗,小项目不需要这么干, 怎么方便怎么来. DAO
写SQL语句时, 涉及到Entity
中表名,字段名,这种都会高亮提示,并且用鼠标点击还能跳转到对应Entity
内,如果无法跳转,可能就有潜在的错误.
当时表字段我使用了current_date
来命名,结果用该字段作为条件查询时死活查不出来,最后发现在SQL中点击current_date无法跳转, 遂在SQL中重写此字段,IDE提示要在current_date
加上单引号,
改好后再查就没问题了, 这个问题浪费了很长时间, 按道理说编译时候应该提示错误的, 但没有提示, 查询就是无法查出.最后搜了下current_date是SQL中的一个方法名称, 可能名称冲突了吧.- APP中另外一个Module使用了另一个版本的Romm版本, 两个版本在编译时候提示一个工具编译的代码和另一个工具编译的代码没法匹配, 后来将Romm版本降级后,又出现了编译错误, 最后将Romm的版本整体提升后才解决.