【问题标题】:Springboot data-jpa findByDate()Springboot data-jpa findByDate()
【发布时间】:2019-10-10 23:27:13
【问题描述】:

我正在尝试从 mysql 数据库中检索今天的记录。

我尝试使用 springboot data-jpa 和 jpa-repository 中的 findByDate(Date date, Pageable pageable) 方法,它总是返回空结果。

这是创建的实体代码:

@Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id_synop")
    private Long id;

    @Column(name="contenu")
    private String contenu;

    @Column(name="date", columnDefinition="TIMESTAMP(0)")
    @Temporal(TemporalType.TIMESTAMP)
    private Date date;

    @ManyToOne(cascade= {CascadeType.DETACH,CascadeType.MERGE,CascadeType.PERSIST,CascadeType.REFRESH},
            fetch=FetchType.LAZY)
    @JoinColumn(name="id_station")
    @JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
    private Station station;

这是使用 Mysql WorkBench 创建的 Mysql 表:

CREATE TABLE `synop` (
  `id_synop` bigint(20) NOT NULL AUTO_INCREMENT,
  `id_station` bigint(20) NOT NULL,
  `contenu` varchar(255) NOT NULL,
  `date` timestamp NOT NULL,
  PRIMARY KEY (`id_synop`),
  UNIQUE KEY `idmsgsynop_UNIQUE` (`id_synop`),
  KEY `fk_synope_station_idx` (`id_station`),
  CONSTRAINT `fk_synope_station` FOREIGN KEY (`id_station`) REFERENCES `station` (`id_station`)
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8;

jpa 仓库代码:

import java.util.Date;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;

public interface SynopRepository extends JpaRepository<Synop, Long> {
    public Page<Synop> findByStationId(Long stationId, Pageable pageable);

    public Page<Synop> findByDate(Date date, Pageable pageable);
}

和控制器代码:

@GetMapping("/synops-today")
    public Page<Synop> findToday(@RequestParam(defaultValue="1") int page,Pageable pageable) {
        return synopRepository.findByDate(new Date(),PageRequest.of(page-1, 10, Sort.by("date").ascending()));
    }

我希望通过使用 findByDate(...) 方法来获取今天的记录,但它似乎不起作用。从 MysqlWorkbench 查看数据时,我还注意到一个小问题:日期似乎提前 2 小时(例如:现在是 11:57,但在 mysql Workbench 软件中它显示 9:57,当我查询服务器时间时,它显示了正确的时间...) 我实际上并不关心我只想检索今天的记录的小时/分钟/秒。

【问题讨论】:

  • 你在使用mysql方言吗? spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
  • 尝试在您的 cntrlr 中将日期从 java.util.date 更改为 sql.date...
  • 尝试#findByDateBetween(Date start, Date end, Pageable pageable),start 是今天的日期加上 00:00:00,end 是今天的日期加上 24:00:00。 “日期似乎提前了 2 小时”,可能是时区问题。

标签: java hibernate spring-boot spring-data-jpa


【解决方案1】:

我为我的问题找到了一个可行的解决方案,显然当使用 TIMESTAMP 数据类型时,JPA-Data“findByDate()”方法不能开箱即用。我实际上只需要通过比较时间戳的日期部分来查找记录,所以我使用了这样的查询注释:

@Query("from Synop s where DATE(s.date) = :date")
public Page<Synop> findByDate(@Param("date") Date date, Pageable pageable);

这是 sql DATE() 函数在此处提供帮助,因为在将时间戳的日期部分与我为搜索提供的日期进行比较时,它只考虑时间戳的日期部分。 有了这个,我可以搜索比较日期的数据,同时保持时间戳类型(显示小时、分钟、秒..) 感谢您的帮助。

【讨论】:

    【解决方案2】:

    试试这个解决方案是否对你有帮助 -> date-only-comparison-without-time-using-jpa-named-query

    基本上,尝试使用@Temporal(TemporalType.DATE) 而不是@Temporal(TemporalType.TIMESTAMP)

    如果没有,那么您可以编写使用 sql 函数仅匹配日期部分而不匹配时间的自定义查询 -> comparing-dates-in-mysql-ignoring-time-portion

    【讨论】:

    • 您的解决方案有效,但我需要时间戳数据类型,以便显示创建时间。如果我将其更改为 DATE,它将为我的所有记录提供 00:00:00 小时。
    • 我提供的第二个解决方案的链接是使用“日期”功能。您可以使用它来保留时间详细信息。
    【解决方案3】:

    我认为,您应该在所有地方从java.util.Date 切换到java.sql.Date。 两者之间有转换的方法。

    虽然我更喜欢逻辑而不是 findByDate。之间的逻辑会更准确。

    java.sql.DateJavaDoc,

    一个毫秒值的瘦包装器,允许 JDBC 识别 这是一个 SQL DATE 值。一个毫秒值代表数字 自 1970 年 1 月 1 日 00:00:00.000 以来经过的毫秒数 格林威治标准时间。

    为符合 SQL DATE 的定义,毫秒值 由 java.sql.Date 实例包装必须通过设置“规范化” 小时、分钟、秒和毫秒到零 实例关联的特定时区。

    java.util.DateJavaDoc - 这个 JavaDoc 很长但相关的部分,

    Date 类表示特定的时间瞬间,以毫秒为单位 精度。

    【讨论】:

      猜你喜欢
      • 2016-12-08
      • 2017-06-01
      • 2020-12-14
      • 2022-01-24
      • 2020-11-15
      • 1970-01-01
      • 1970-01-01
      • 2019-02-26
      • 1970-01-01
      相关资源
      最近更新 更多