У меня есть два вопроса,
class LocalTimeRage {
LocalTime opens;
LocalTime closes;
}
И 2. Как вы можете запросить с помощью ObjectBox локальный диапазон времени, например, запросить объект, который соответствует значениям opens
и closes
LocalTime, например, запрос для открытия между 07:00 и закрытием 20:00 (в LocalTime) как такой ObjectBox будет возвращать объекты, время открытия и закрытия которых соответствует диапазону.
Это основано на ObjectBox v2.8.1.
ObjectBox поддерживает относительно ограниченный список встроенных типов . В списке нет ни одного из современных java.time
классов, но мы можем использовать аннотацию ObjectBox @Convert.
Я думаю, что лучше полностью избегать старого и проблемного классаDate
, поэтому в этом примере значения LocalDateTime
преобразуются в длинные (однако Date
является одним из их встроенных поддерживаемых типов):
import java.time.LocalTime;
import io.objectbox.annotation.Entity;
import io.objectbox.annotation.Id;
import io.objectbox.annotation.Convert;
import io.objectbox.converter.PropertyConverter;
@Entity
public class LocalTimeRange {
@Id
private long id;
@Convert(converter = LocalTimeConverter.class, dbType = Long.class)
private LocalTime opens;
@Convert(converter = LocalTimeConverter.class, dbType = Long.class)
private LocalTime closes;
public static class LocalTimeConverter implements PropertyConverter<LocalTime, Long> {
@Override
public LocalTime convertToEntityProperty(Long databaseValue) {
if (databaseValue == null) {
return null;
}
return LocalTime.ofSecondOfDay(databaseValue);
}
@Override
public Long convertToDatabaseValue(LocalTime entityProperty) {
if (entityProperty == null) {
return null;
}
long seconds = (entityProperty.getHour() * 60 * 60) +
(entityProperty.getMinute() * 60) +
entityProperty.getSecond();
return seconds;
}
}
public LocalTimeRange(Long id) {
this.id = id;
}
public LocalTimeRange(long id, LocalTime opens, LocalTime closes) {
this.id = id;
this.opens = opens;
this.closes = closes;
}
public LocalTimeRange() {
}
// getters and setters not shown
}
Теперь мы можем создать и сохранить пару тестовых объектов:
BoxStore store = MyObjectBox.builder().name("objectbox-demo-db").build();
Box<LocalTimeRange> box = store.boxFor(LocalTimeRange.class);
// start with no objects:
box.query().build().remove();
// add two objects:
LocalTimeRange ltrOne = new LocalTimeRange(1,
LocalTime.of(9, 30, 0), //9:30:00 (9:30am)
LocalTime.of(10, 15, 0));
box.put(ltrOne);
LocalTimeRange ltrTwo = new LocalTimeRange(2,
LocalTime.of(10, 05, 0),
LocalTime.of(11, 45, 0));
box.put(ltrTwo);
И тогда мы можем запросить хранилище данных:
// this will find both objects:
LocalTime testTime = LocalTime.of(10, 10, 0);
// this will find the 2nd object
//LocalTime testTime = LocalTime.of(10, 20, 0);
// convert the localtime to seconds:
Long seconds = localTimeToSeconds(testTime);
List<LocalTimeRange> localTimeRanges = box.query()
.less(LocalTimeRange_.opens, seconds)
.greater(LocalTimeRange_.closes, seconds)
.build().find();
for (LocalTimeRange ltr : localTimeRanges) {
System.out.println(ltr.toString());
}
store.close();
---
private static long localTimeToSeconds(LocalTime lt) {
return (lt.getHour() * 60 * 60) +
(lt.getMinute() * 60) +
lt.getSecond();
}
Операторы запросов также ограничены в типах, которые они могут обрабатывать:
less(LocalTimeRange_.opens, seconds)
Здесь seconds
— это long
, потому что нет оператора запроса, который принимает тип Java, который мы хотим использовать (LocalTime
).
Возможно, вы захотите уточнить мой пример, чтобы убедиться, что время тестирования, попадающее точно на одно из граничных значений, обрабатывается правильно (например, нет метода запроса «меньше или равно»). Вы можете создавать более сложные запросы с помощью equal()
, and()
, or()
и так далее.
(Этот подход обрабатывает LocalTime
с точностью до секунды. Если вам нужна точность до доли секунды, вам нужно обновить логику, включив в LocalTime
поддержку наносекунд.)
Я не знаю, как использовать конвертер для этого случая (класс Schedule
), учитывая необходимость сопоставления каждого свойства с одним (и только одним) из поддерживаемых встроенных типов. Кроме того, для вашего примера List
в документации предлагается преобразовать список строк в массив JSON, что приведет к созданию одной строки для базы данных. Похоже, на данный момент мы отошли от хранения объектов и вместо этого храним документы. Я предполагаю, что должен быть способ сделать все это с объектами... Может быть, для этого нужен новый вопрос?
Из документов: docs.objectbox.io/queries «содержит» работает только со строкой, поэтому запрос о том, содержит ли свойство «расписания» заданное Schedule
, может не работать полностью, поскольку это не строковый литерал, а пользовательский класс / объект.
Как насчет этого? stackoverflow.com/questions/65439440/…
Как насчет того, когда
LocalTimeRange
является свойством/полем объекта? Например.class Yoga { List<Schedule> schedules; }
class Schedule { String day; LocalTimeRange opens; LocalTimeRange closes; }