Android Kotlin Room 查询 select 过去 7 天的记录
Android Kotlin Room query to select record from last seven days
我正在编写一份报告,该报告将从 Room 数据库中获取过去 7 天的数据。
这是我简化的应用程序结构。
Entity Class:
@Entity(tableName = "cleaning")
data class Cleaning(
@PrimaryKey(autoGenerate = true)
val id: Long,
val task: String,
val timestamp: Date
)
类型转换器:
class 日期类型转换器 {
@TypeConverter
fun fromTimeStampToDate(timestamp: Long?): Date? {
return timestamp?.let {
Date(it)
}
}
@TypeConverter
fun fromDateToTimeStamp(date: Date?): Long? {
return date?.time?.toLong()
}
数据访问对象Class提取:
@Query("SELECT * from cleaning WHERE (timestamp=Calendar.getInstance().time - 7) ORDER BY id DESC")
fun readSevenDaysData(): LiveData<List<CleaningRecord>>
问题是 (timestamp=Calendar.getInstance().time - 7)。当我使用 Calendar.getInstance().time
存储日期时,我不知道如何给出过去 7 天提取数据的范围
非常感谢任何正确方向的指导。
我相信下面会做你想要的:-
@Query("SELECT * from cleaning WHERE CAST((timestamp / 1000) AS INTEGER) BETWEEN strftime('%s','now','-7 days') AND strftime('%s','now') ORDER BY id DESC;")
即 时间戳 存储到毫秒,因此除以 1000 会将值减少到秒。
strftime('%s' ....
returns 秒数
'now'
returns 当前日期时间
'-7 days'
相应地修改值
- 有关更全面的信息,请参阅 https://sqlite.org/lang_datefunc.html。
BETWEEN
等同于 >= AND <=
CAST
是为了确保对等(整数值)进行比较。
SQLite 不理解表达式 (timestamp=Calendar.getInstance().time - 7)
的含义,即使它理解它也只会得到与小于 7 天的时间完全匹配的数据,精确到毫秒。
已使用您的代码加上或被以下内容覆盖进行了测试:-
@Dao
interface Extract {
@Insert
fun insert(cleaning: Cleaning)
@Query("SELECT * from cleaning WHERE CAST((timestamp / 1000) AS INTEGER) BETWEEN strftime('%s','now','-7 days') AND strftime('%s','now') ORDER BY id DESC;")
fun readSevenDaysData(): List<Cleaning>
}
显然 SQL 已更改,
此外,为了简洁和方便,没有使用 LiveData,
由于未提供 CleaningRecord 对象,因此仅返回了 Cleaning 对象。
@Database(entities = [Cleaning::class], version = 1, exportSchema = false)
@TypeConverters( 值 = [DateTypeConverter::class])
摘要 class TheDatabase: RoomDatabase() {
抽象乐趣 getExtractDao(): Extract
companion object {
private var instance: TheDatabase? = null
fun getInstance(context: Context): TheDatabase {
if (instance == null) {
instance = Room.databaseBuilder(context,TheDatabase::class.java,"the_database.db")
.allowMainThreadQueries()
.build()
}
return instance as TheDatabase
}
}
}
带注释的@Database class,以及 getInstance 函数,再次指出,为简洁起见,使用了 allowMainThreadQueries。
最后 Activity 添加一些数据并使用相应的查询提取数据:-
class MainActivity : AppCompatActivity() {
lateinit var db: TheDatabase
lateinit var dao: Extract
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
db = TheDatabase.getInstance(this)
dao = db.getExtractDao()
dao.insert(Cleaning(100,"TASK001",Calendar.getInstance().time))
dao.insert(Cleaning(200,"TASK002",Calendar.getInstance().time))
for (c: Cleaning in dao.readSevenDaysData()) {
Log.d("DBINFO","Cleaning Task = ${c.task} ID = ${c.id} ${c.timestamp.time}")
}
}
}
导致 :-
D/DBINFO: Cleaning Task = TASK002 ID = 200 1647400757156
D/DBINFO: Cleaning Task = TASK001 ID = 100 1647400757125
AppInspection 显示:-
另外使用App Inspection查询
SELECT *, timestamp /1000 AS timetosecond, strftime('%s','now','-7 days') AS fromtime, strftime('%s','now') AS totime from cleaning WHERE CAST((timestamp / 1000) AS INTEGER) BETWEEN strftime('%s','now','-7 days') AND strftime('%s','now') ORDER BY id DESC
运行 进一步展示了 a) App Inspection 的用途以及 b) 查询的各个部分对实际数据的作用。
即以上导致:-
我正在编写一份报告,该报告将从 Room 数据库中获取过去 7 天的数据。 这是我简化的应用程序结构。
Entity Class:
@Entity(tableName = "cleaning")
data class Cleaning(
@PrimaryKey(autoGenerate = true)
val id: Long,
val task: String,
val timestamp: Date
)
类型转换器: class 日期类型转换器 {
@TypeConverter
fun fromTimeStampToDate(timestamp: Long?): Date? {
return timestamp?.let {
Date(it)
}
}
@TypeConverter
fun fromDateToTimeStamp(date: Date?): Long? {
return date?.time?.toLong()
}
数据访问对象Class提取:
@Query("SELECT * from cleaning WHERE (timestamp=Calendar.getInstance().time - 7) ORDER BY id DESC")
fun readSevenDaysData(): LiveData<List<CleaningRecord>>
问题是 (timestamp=Calendar.getInstance().time - 7)。当我使用 Calendar.getInstance().time
存储日期时,我不知道如何给出过去 7 天提取数据的范围非常感谢任何正确方向的指导。
我相信下面会做你想要的:-
@Query("SELECT * from cleaning WHERE CAST((timestamp / 1000) AS INTEGER) BETWEEN strftime('%s','now','-7 days') AND strftime('%s','now') ORDER BY id DESC;")
即 时间戳 存储到毫秒,因此除以 1000 会将值减少到秒。
strftime('%s' ....
returns 秒数'now'
returns 当前日期时间'-7 days'
相应地修改值- 有关更全面的信息,请参阅 https://sqlite.org/lang_datefunc.html。
BETWEEN
等同于 >= AND <=CAST
是为了确保对等(整数值)进行比较。
SQLite 不理解表达式 (timestamp=Calendar.getInstance().time - 7)
的含义,即使它理解它也只会得到与小于 7 天的时间完全匹配的数据,精确到毫秒。
已使用您的代码加上或被以下内容覆盖进行了测试:-
@Dao
interface Extract {
@Insert
fun insert(cleaning: Cleaning)
@Query("SELECT * from cleaning WHERE CAST((timestamp / 1000) AS INTEGER) BETWEEN strftime('%s','now','-7 days') AND strftime('%s','now') ORDER BY id DESC;")
fun readSevenDaysData(): List<Cleaning>
}
显然 SQL 已更改,
此外,为了简洁和方便,没有使用 LiveData,
由于未提供 CleaningRecord 对象,因此仅返回了 Cleaning 对象。
@Database(entities = [Cleaning::class], version = 1, exportSchema = false) @TypeConverters( 值 = [DateTypeConverter::class]) 摘要 class TheDatabase: RoomDatabase() { 抽象乐趣 getExtractDao(): Extract
companion object { private var instance: TheDatabase? = null fun getInstance(context: Context): TheDatabase { if (instance == null) { instance = Room.databaseBuilder(context,TheDatabase::class.java,"the_database.db") .allowMainThreadQueries() .build() } return instance as TheDatabase } }
}
带注释的@Database class,以及 getInstance 函数,再次指出,为简洁起见,使用了 allowMainThreadQueries。
最后 Activity 添加一些数据并使用相应的查询提取数据:-
class MainActivity : AppCompatActivity() {
lateinit var db: TheDatabase
lateinit var dao: Extract
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
db = TheDatabase.getInstance(this)
dao = db.getExtractDao()
dao.insert(Cleaning(100,"TASK001",Calendar.getInstance().time))
dao.insert(Cleaning(200,"TASK002",Calendar.getInstance().time))
for (c: Cleaning in dao.readSevenDaysData()) {
Log.d("DBINFO","Cleaning Task = ${c.task} ID = ${c.id} ${c.timestamp.time}")
}
}
}
导致 :-
D/DBINFO: Cleaning Task = TASK002 ID = 200 1647400757156
D/DBINFO: Cleaning Task = TASK001 ID = 100 1647400757125
AppInspection 显示:-
另外使用App Inspection查询
SELECT *, timestamp /1000 AS timetosecond, strftime('%s','now','-7 days') AS fromtime, strftime('%s','now') AS totime from cleaning WHERE CAST((timestamp / 1000) AS INTEGER) BETWEEN strftime('%s','now','-7 days') AND strftime('%s','now') ORDER BY id DESC
运行 进一步展示了 a) App Inspection 的用途以及 b) 查询的各个部分对实际数据的作用。
即以上导致:-