使用 ObjectBox 查询本地时间

Query Local Time with ObjectBox

我有两个问题,

  1. 如何用ObjectBox保存一个LocalTime rage,例如:
class LocalTimeRage {
   LocalTime opens;
   LocalTime closes;
}

和 2. 如何使用 ObjectBox 查询本地时间范围,例如,查询在 openscloses 内匹配的对象 LocalTime 值,例如,查询在 [= 之间打开17=]07:00 AM 并关闭 8:00 PM(本地时间),这样 ObjectBox 将 return 具有匹配的打开和关闭时间的对象范围。

这是基于 ObjectBox v2.8.1。

ObjectBox 支持的列表比较有限built-in types. The list does not include any of the modern java.time classes, but we can use the ObjectBox @Convert annotation

我认为最好完全避免 old and problematic Date class,所以这个例子将 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 对纳秒的支持。)