首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Spring Boot Sqlite查询日期

Spring Boot Sqlite查询日期
EN

Stack Overflow用户
提问于 2022-06-06 22:29:05
回答 1查看 256关注 0票数 0

我有一个Raspberry温度记录器使用Sqlite数据库,这是与我的嵌入式C++文明网络应用程序工作很好。

我想我会有一些乐趣,试图得到一些与Spring有关的东西。我可以让一些查询工作,但我几乎没有任何尝试与查询日期。

我使用org.xerial sqlit-JDBC3.36.0.3和com.enigmabridge Hibernate4-sqlite0.1.2来设置sqlite数据源。

在我的Pi上,返回数据并显示最后一天温度图的主要查询是:

代码语言:javascript
复制
SELECT timestamp, temp, id FROM temps WHERE timestamp > datetime('now', 'localtime', '-1 days');

但是这种类型的查询似乎不适用于JPA,因为查询的天数在单引号字符串文本中,因此任何参数都按原样传递。如果我直接指定查询中的天数,它将返回数据,但我希望将其作为param传递。

因此,我尝试在Spring中查询两次约会,如下所示:

代码语言:javascript
复制
LocalDate end = LocalDate.now();
LocalDate start = end.minusDays(2);

return temperatureRepository.findTemperaturesBetweenDates(start, end);

在存储库中使用此方法:

代码语言:javascript
复制
@Query("SELECT op FROM Temperature op WHERE timestamp between :startDate AND :endDate")
List<Temperature> findTemperaturesBetweenDates(@Param(value="startDate") LocalDate startDate, @Param(value="endDate") LocalDate endDate);

此查询不返回结果。同样,在没有参数的情况下,在查询中直接在单引号中指定日期是有效的,并返回数据。我也尝试过nativeQuery,但结果是一样的。

将Hibernate上的日志记录级别更改为跟踪,我可以看到正在使用的参数,它似乎正在将日期转换为划时代的时间。

/*从温度op中选择op,其中时间戳介于:startDate和:endDate */选择temperatur0_.timestamp作为timestam1__,temperatur0_.id作为id2__,temperatur0_.temp作为temp3__从temps temperatur0_选择时间戳在哪里?然后呢?Hibernate: /*从温度op中选择op,其中时间戳介于:startDate和:endDate */选择temperatur0_.timestamp作为timestam1__,temperatur0_.id作为id2__,temperatur0_.temp作为temp3__从temps temperatur0_选择时间戳在哪里?和? 2022-06-06 23:18:45.393调试9328 - nio-8080-exec-4 o.s.j.d.DriverManagerDataSource :创建到JDBC的新jdbc DriverManager连接:sqlite:src/main/resources/sqlTemplog.db 2022-06-06 23:18:45.394跟踪9328 -nio- nio-8080-exec-4 o.h.r.j.i.ResourceRegistryStandardImpl :注册语句/*从温度op中选择op,其中时间戳在:startDate和:endDate _/ SELECT temperatur0_.timestamp作为timestam1__,temperatur0_.id为id2__,temperatur0_.temp为temp3__,来自temps temperatur0_的时间戳在哪里?然后呢?parameters=null 2022-06-06 23:18:45.394跟踪9328 - nio-8080-exec-4 o.h.e.jdbc.internal.JdbcCoordinatorImpl :注册最后一次查询语句/从温度op中选择op,其中时间戳在:startDate和:endDate / select temperatur0_.timestamp作为timestam1__,temperatur0_.id作为id2__,temperatur0_.temp作为temp3__来自临时temp3__ temperatur0_,其中时间戳在哪里?和?_

2022-06-04 2022-06-06 23:18:45.394跟踪9328 - nio-8080-exec-4 o.h.type.descriptor.sql.BasicBinder :绑定参数1 as DATE - _parameters=null 2022-06-06 23:18:45.394跟踪9328 -- nio-8080-exec-4 o.h.type.descriptor.sql.BasicBinder :绑定参数2作为日期- 2022-06-06 2022-06-06 23:18:45.394痕量9328 -- nio-8080-exec-4 org.hibernate.loader.Loader_

o.h.r.j.i.ResourceRegistryStandardImpl :注册结果集org.sqlite.jdbc4.JDBC4ResultSet@23105e31 2022-06-06 23:18:45.394跟踪9328 -- nio-8080-exec-4 org.hibernate.loader.Loader :处理结果集2022-06 23:18:45.394org.hibernate.loader.Loader :完成处理结果集(0行) 2022-06-06 23:18:45.394跟踪9328 -nio-8080- org.hibernate.loader.Loader :水合总对象:0 2022-06-06 23:18:45.395跟踪9328 --nio-8080- o.h.r.j.i.ResourceRegistryStandardImpl :o.h.r.j.i.ResourceRegistryStandardImpl:从温度op释放语句[/从温度op中选择op,时间戳在:startDate和:endDate /选择temperatur0_.timestamp作为timestam1__,temperatur0_.id为id2__,temperatur0_.temp为temp3__,来自temps temperatur0_的时间戳在哪里?然后呢?

parameters=[16542972000001654470000000__]] 2022-06-06 23:18:45.395跟踪9328 - nio-8080-exec-4 o.h.r.j.i.ResourceRegistryStandardImpl :关闭结果集org.sqlite.jdbc4.JDBC4ResultSet@23105e31 2022-06-06 23:18:45.395跟踪9328 -- nio-8080-exec-4 o.h.r.j.i.ResourceRegistryStandardImpl :关闭准备语句[/从温度op中选择op,时间戳为:startDate和:endDate */选择temperatur0_.timestamp作为timestam1__,temperatur0_.id为id2__,temperatur0_.temp为temp3__,来自temps temperatur0_的时间戳在哪里?然后呢?

parameters=16542972000001654470000000]

我设法让它正常工作的唯一方法是在查询中使用unixepoch,并在Sqlite中转换参数:

代码语言:javascript
复制
@Query(value =("select timestamp, id, temp from temps where timestamp between DATETIME(ROUND(:startDate / 1000), 'unixepoch') AND DATETIME(ROUND(:endDate / 1000), 'unixepoch')"), nativeQuery = true)
List<Temperature> findTemperaturesTest(@Param(value="startDate") LocalDate startDate, @Param(value="endDate") LocalDate endDate);

有什么想法,如何使日期查询正确地使用Spring和Sqlite?谢谢

编辑:

好的,所以刚刚设法使-X days部分正常工作,但是我确实有其他的查询,它们将+/- days和date组合在一起,但是仍然无法正确地将日期传递给查询。

代码语言:javascript
复制
@Query("SELECT op FROM Temperature op WHERE id between 1 and 4 AND timestamp > datetime('now', 'localtime', '-' || :days || ' days')")
List<Temperature> findTemperaturesMinusDays(@Param(value="days") int days);
EN

回答 1

Stack Overflow用户

发布于 2022-06-07 23:04:25

是的,所以这一切似乎都归结于Sqlite存储日期的方式。我的数据库将时间戳字段存储为字符串,如"2022-06-07 23:44:19",大多数数据库将日期存储为unix time。

没问题,我只是告诉它在查询数据库时将一个LocalDateTime转换成一个字符串。嗯,也许没那么容易。我尝试了“转换器”,“类型”,还有一些我忘记了的问题。这些都不管用。

我的第一次半成功尝试是将类中的数据类型更改为字符串,并在getter中进行转换。但这意味着@Query params也必须作为字符串传递。不是很好。

因此,我的解决方案是一个自定义存储库,它将一个LocalDateTime转换为一个字符串,并在查询中将这些参数设置为参数。

代码语言:javascript
复制
public class TemperatureRepositoryImpl implements TemperatureRepositoryCustom {
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List<Temperature> findTemperaturesBetweenDates(LocalDateTime startDate, LocalDateTime endDate) {
        Query query = entityManager.createNativeQuery("SELECT timestamp, temp, id FROM temps WHERE timestamp BETWEEN :startDate AND :endDate");

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String startDateString = startDate.format(formatter);
        String endDateString = endDate.format(formatter);

        query.setParameter("startDate", startDateString);
        query.setParameter("endDate", endDateString);

        return query.getResultList();
    }
}

编辑

差点就和那个扯上关系了。有两个问题--没有使用接口存储库,只有实现,日期不包括时间。最后,让它与TypedQuery一起工作:

代码语言:javascript
复制
    public List<Temperature> findTemperaturesBetweenDates(LocalDateTime startDate, LocalDateTime endDate) {
        TypedQuery<Temperature> query = entityManager.createQuery("SELECT op FROM Temperature op WHERE timestamp BETWEEN date(:startDate) AND date(:endDate)", Temperature.class);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String startDateString = startDate.format(formatter);
        String endDateString = endDate.format(formatter);

        query.setParameter("startDate", startDateString);
        query.setParameter("endDate", endDateString);

        return query.getResultList();
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72524067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档