Итерация по хранилищу для доступа к определенной информации - PullRequest
0 голосов
/ 12 января 2019

В моем приложении 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 голосов
/ 12 января 2019

Репозиторий

лучший способ перебрать список элементов в хранилище и получить доступ к определенным столбцам

Неа. Мы не можем помочь вам в этом вопросе, поскольку вы не показали или не объяснили свой код хранилища.

Я могу показать вам правильный JDBC 4.2 код для извлечения значения только для даты из столбца базы данных типа, подобного стандарту SQL DATE типа.

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

Или кто-то может легко помочь мне исправить код, который у меня есть?

Да, я могу помочь.

  • Вы используете неправильный синтаксис.
  • Вы игнорируете критическую проблему часового пояса.

Используйте метод isEqual, а не ==

Оператор == в тестах Java также:

  • Если две ссылки указывают на один и тот же объект, на одно и то же место в памяти.
    (Вообще говоря, это очень редко требуется в большинстве приложений. Поэтому, как правило, не используют == с объектами .)
  • Если два примитива (int, boolean и т. Д.) Имеют эквивалентные значения.

Таким образом, эффект резко отличается между этими двумя. Один сравнивает значения данных, которые вас интересуют (в примитивах). Другой сравнивает место в памяти (в основном число) пары ссылок ( указатели ) без учета данных , которые вам нужны (в объектах).

При сравнении значения двух объектов вызовите метод. Для LocalDate это будет isEqual. Вы также можете временно сравнить с isBefore & isAfter.

Так твой код:

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 ) ) { … }

Часовой пояс

Часовой пояс имеет решающее значение при определении даты. В любой момент времени дата меняется по всему земному шару в зависимости от зоны. Например, через несколько минут после полуночи в Париж Франция - это новый день, хотя все еще "вчера" в Монреаль Квебек .

Если часовой пояс не указан, JVM неявно применяет свой текущий часовой пояс по умолчанию. Это значение по умолчанию может измениться в любой момент во время выполнения (!), Поэтому ваши результаты могут отличаться. Лучше явно указать желаемый / ожидаемый часовой пояс в качестве аргумента.

Укажите собственное имя часового пояса в формате Continent/Region, например America/Montreal, Africa/Casablanca или Pacific/Auckland. Никогда не используйте 2-4 буквенные сокращения, такие как EST или IST, так как они не истинные часовые пояса, не стандартизированы и даже не уникальны (!).

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 и более поздние версии. Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .

Чтобы узнать больше, см. Руководство по Oracle . И поиск переполнения стека для многих примеров и объяснений. Спецификация JSR 310 .

Вы можете обмениваться java.time объектами напрямую с вашей базой данных. Используйте драйвер JDBC , совместимый с JDBC 4.2 или более поздней версии. Нет необходимости в строках, нет необходимости в java.sql.* классах.

Где получить классы java.time?

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти несколько полезных классов, таких как Interval, YearWeek, YearQuarter и more .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...