如何按日期搜索房间数据库?
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());
}
}
}
运行 以上结果为:-
- 由于精度因素,第一个查询未提取任何内容。
- 以下来自第二个查询
:-
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
我在房间数据库 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());
}
}
}
运行 以上结果为:-
- 由于精度因素,第一个查询未提取任何内容。
- 以下来自第二个查询
:-
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