遍历存储库以访问某些信息

时间:2019-01-11 23:30:39

标签: java sql loops spring-boot repository

在我的Java / Spring应用程序中,我试图遍历SQL数据库表中称为“许可证”的所有项目,如果许可证的有效期距今天还有30天,则发送电子邮件,但是我遇到了遍历的问题。

问题在于访问到期列。我应该怎么做才能访问数据库中每个许可证的到期日期,因为显然我的操作方式不准确。我可能会感到困惑,因为您需要通过存储库从表中获取所有项目,但是对于每个项目,您都使用模型来访问到期日期。

是否有更好的方法来遍历存储库中的项目列表并访问特定的列?还是有人可以轻松地帮助我修复到目前为止的代码?

List<License> licenses=licenseRepository.findAll();
for(Object lic:licenses){

    if (lic.expiration.minusDays(30) == LocalDate.now()) {
        try {
            emailService.sendSimpleMessage(mail, licenseModel);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

存储库

  

一种更好的方式来遍历存储库中的项目列表并访问特定的列

不。在这一点上,我们没有帮助您,因为您没有显示或解释您的存储库代码。

我可以向您展示正确的JDBC 4.2代码,以便从类似于SQL标准DATE类型的数据库列中检索仅日期的值。

LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
  

或者有人可以轻松地帮助我修复到目前为止的代码吗?

是的,我可以提供帮助。

  • 您使用的语法不正确。
  • 您正在忽略时区的关键问题。

使用isEqual方法,而不是==

Java上的==运算符会测试:

  • 如果两个引用都指向同一对象,则指向内存中的同一位置。
    (通常来说,在大多数应用中很少需要这样做。因此,通常不要使用==与对象。)
  • 如果两个原语(intboolean等)具有相等的值。

因此,两者之间的效果有很大不同。一个比较您关心的数据的值(以原语)。另一个比较一对引用(pointers)的内存位置(基本上是一个数字),而与您关心的数据无关(在对象中)

比较两个对象的时,调用一个方法。对于LocalDate,应为isEqual。您还可以与isBeforeisAfter进行暂时比较。

所以您的代码:

if ( lic.expiration.minusDays( 30 ) == LocalDate.now() ) { … }

...应该是...

if ( lic.expiration.minusDays( 30 ).isEqual( LocalDate.now() ) ) { … }

我会用自己的代码来分解。

LocalDate today = LocalDate.now() ;
LocalDate thirtyDaysBeforeExpiration = lic.expiration.minusDays( 30 ) ;
if ( thirtyDaysBeforeExpiration.isEqual( today ) ) { … }

时区

时区对于确定日期至关重要。在任何给定时刻,日期都会在全球范围内变化。例如,Paris France午夜之后的几分钟是新的一天,而Montréal Québec仍然是“昨天”。

如果未指定时区,则JVM隐式应用其当前的默认时区。该默认值可能在运行时(!)期间change at any moment,因此您的结果可能会有所不同。最好将您的期望/期望时区明确指定为参数。

Continent/Region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用2-4个字母的缩写,例如ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "America/Montreal" ) ;  
LocalDate today = LocalDate.now( z ) ;

如果要使用JVM的当前默认时区,请提出要求并作为参数传递。如果省略,代码将变得难以理解,因为我们不确定您是否打算使用默认值,还是像许多程序员一样不知道该问题。

ZoneId z = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

所以我的代码版本实际上是:

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
LocalDate today = LocalDate.now( z ) ;
LocalDate thirtyDaysBeforeExpiration = lic.expiration.minusDays( 30 ) ;
if ( then.isEqual( today ) ) { … }

关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore