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 会将值减少到秒。

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) 查询的各个部分对实际数据的作用。

即以上导致:-