如何按日期搜索房间数据库?

How to search by date Room Database?

我在房间数据库 Android Studio 中有一个数据库,我需要在其中找到与通过 http 查询找到的日期相匹配的记录

我看到的问题是因为我在尝试使用“LIKE”或“=”进行查询时使用数据转换器 (ZoneDateTimeConverter) returns 空对象...我怎么能进行查询?

查询 1:

@Query("select * from Operation where date =:arg0")
Operation getOperationConsult(String arg0);

查询 2:

@Query("select * from Operation where date LIKE :arg0")
Operation getOperationConsult(String arg0);

运营实体日期:

    @ColumnInfo(name = "date")
ZonedDateTime date;

转换器:

public class ZonedDateTimeTypeConverter {

@TypeConverter
public static ZonedDateTime toZonedDateTime(Long value) {
    return value == null ? null : ZonedDateTime.ofInstant(Instant.ofEpochMilli(value), ZoneOffset.UTC);
}

@TypeConverter
public static Long toString(ZonedDateTime value) {
    return value == null ? null : value.toInstant().toEpochMilli();
}

}

简而言之,您需要进行同类比较,并且数据的存储时间长至毫秒。

所以你可以:-

@Query("SELECT * FROM operation WHERE date=:arg0")
List<Operation> getOperationConsult(long arg0);

可以使用您为 Room 提供的 TypeConverter 将 ZonedDateTime 转换为 long 来确定 long 的位置(稍后会详细介绍)。

但是,您处理的是毫秒,因此由于精度高,上述查询可能根本没有用。

或许可以考虑以下几点:-

@Query("SELECT * FROM operation WHERE date / (1000 * 60 * 60 * 24)= (:arg0 / (1000 * 60 * 60 * 24))")
List<Operation> getOperationsConsultPerDate(long arg0);

这会去掉时间(毫秒、秒、分钟和小时),只留下日期(对于参数的两边),这样会检索与传递的 long 具有相同日期的所有操作。

要确定时间长短,可以使用 ZDT 然后使用 toString TypeConverter 来实现。

考虑以下工作示例,它使用您的操作实体(至少是日期列)和上述 dao 的(运行 在主线程上,为了简洁和方便):-

public class MainActivity extends AppCompatActivity {

    private final static String TAG = "DBINFO";

    TheDatabase db;
    AllDao dao;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        db = TheDatabase.getInstance(this);
        dao = db.getAllDao();

        /* Add some data */
        for (int i=0;i<48;i++) {
            ZonedDateTime zdt = ZonedDateTime.now().minusHours(i).plusHours(24);
            dao.insert(new Operation(zdt));
        }

        /* extract Operations based upon the current time */
        logOperations(dao.getOperationConsult(ZonedDateTimeTypeConverter.toString(ZonedDateTime.now())));
        logOperations(dao.getOperationsConsultPerDate(ZonedDateTimeTypeConverter.toString(ZonedDateTime.now())));
    }

    void logOperations(List<Operation> operationList) {
        for(Operation o: operationList) {
            Log.d(TAG,"Operation ID is " + o.id + " date is " + o.date.toString());
        }
    }
}

运行 以上结果为:-

  1. 由于精度因素,第一个查询未提取任何内容。
  2. 以下来自第二个查询

:-

2021-12-15 10:49:16.451 D/DBINFOEXAMPLE2: Operation ID is 25 date is 2021-12-14T23:49:16.398Z
2021-12-15 10:49:16.451 D/DBINFOEXAMPLE2: Operation ID is 26 date is 2021-12-14T22:49:16.400Z
2021-12-15 10:49:16.452 D/DBINFOEXAMPLE2: Operation ID is 27 date is 2021-12-14T21:49:16.401Z
2021-12-15 10:49:16.452 D/DBINFOEXAMPLE2: Operation ID is 28 date is 2021-12-14T20:49:16.403Z
2021-12-15 10:49:16.452 D/DBINFOEXAMPLE2: Operation ID is 29 date is 2021-12-14T19:49:16.404Z
2021-12-15 10:49:16.452 D/DBINFOEXAMPLE2: Operation ID is 30 date is 2021-12-14T18:49:16.407Z
2021-12-15 10:49:16.452 D/DBINFOEXAMPLE2: Operation ID is 31 date is 2021-12-14T17:49:16.408Z
2021-12-15 10:49:16.453 D/DBINFOEXAMPLE2: Operation ID is 32 date is 2021-12-14T16:49:16.410Z
2021-12-15 10:49:16.453 D/DBINFOEXAMPLE2: Operation ID is 33 date is 2021-12-14T15:49:16.412Z
2021-12-15 10:49:16.453 D/DBINFOEXAMPLE2: Operation ID is 34 date is 2021-12-14T14:49:16.414Z
2021-12-15 10:49:16.453 D/DBINFOEXAMPLE2: Operation ID is 35 date is 2021-12-14T13:49:16.416Z
2021-12-15 10:49:16.453 D/DBINFOEXAMPLE2: Operation ID is 36 date is 2021-12-14T12:49:16.417Z
2021-12-15 10:49:16.454 D/DBINFOEXAMPLE2: Operation ID is 37 date is 2021-12-14T11:49:16.420Z
2021-12-15 10:49:16.454 D/DBINFOEXAMPLE2: Operation ID is 38 date is 2021-12-14T10:49:16.422Z
2021-12-15 10:49:16.454 D/DBINFOEXAMPLE2: Operation ID is 39 date is 2021-12-14T09:49:16.424Z
2021-12-15 10:49:16.454 D/DBINFOEXAMPLE2: Operation ID is 40 date is 2021-12-14T08:49:16.426Z
2021-12-15 10:49:16.454 D/DBINFOEXAMPLE2: Operation ID is 41 date is 2021-12-14T07:49:16.427Z
2021-12-15 10:49:16.454 D/DBINFOEXAMPLE2: Operation ID is 42 date is 2021-12-14T06:49:16.430Z
2021-12-15 10:49:16.454 D/DBINFOEXAMPLE2: Operation ID is 43 date is 2021-12-14T05:49:16.432Z
2021-12-15 10:49:16.455 D/DBINFOEXAMPLE2: Operation ID is 44 date is 2021-12-14T04:49:16.434Z
2021-12-15 10:49:16.455 D/DBINFOEXAMPLE2: Operation ID is 45 date is 2021-12-14T03:49:16.435Z
2021-12-15 10:49:16.455 D/DBINFOEXAMPLE2: Operation ID is 46 date is 2021-12-14T02:49:16.436Z
2021-12-15 10:49:16.455 D/DBINFOEXAMPLE2: Operation ID is 47 date is 2021-12-14T01:49:16.438Z
2021-12-15 10:49:16.455 D/DBINFOEXAMPLE2: Operation ID is 48 date is 2021-12-14T00:49:16.439Z

额外

由于存储的日期(如果除以1000)是SQLite date and time functions识别的格式(格式12),那么您可以使用SQlite日期函数。

  • 请注意,就数据库而言,将数据存储为 long 是最有效的格式,最多占用 8 个字节,而不是存储与 string/text 相同信息的两倍以上格式。

例如,日期时间函数 returns 格式为 yyyy-mm-dd hh:mm:ss 的日期时间,因此为了演示请考虑以下查询:-

@Query("SELECT datetime(date / 1000,'unixepoch') FROM operation WHERE date(date / 1000,'unixepoch') = date('now')")
List<String> getDatesFromOperations();

这将 return 每个选定操作的日期和时间,例如2021-12-1500:20:18。选择的操作是那些日期是查询为invoked/used(即'now')的日期的操作。该查询没有 return 房间对象,但是因为只有一个输出列,所以 Room 可以处理常见类型的列表,在本例中为 String。

  • unixepoch 表示该值是格式 12 的 unix 格式,而不是 Julian 日数。

所以使用 :-

    for (String s: dao.getDatesFromOperations()) {
        Log.d(TAG+"EXAMPLE3","DateTime is " + s);
    }

会导致:-

D/DBINFOEXAMPLE3: DateTime is 2021-12-15 00:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 01:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 02:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 03:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 04:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 05:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 06:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 07:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 08:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 09:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 10:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 11:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 12:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 13:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 14:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 15:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 16:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 17:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 18:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 19:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 20:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 21:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 22:20:18
D/DBINFOEXAMPLE3: DateTime is 2021-12-15 23:20:18