Java --- обновить базу данных с годовым календарем - PullRequest
1 голос
/ 24 января 2020

Как лучше всего загрузить таблицу базы данных с годовым календарем, используя Java?

На 365 дней одна строка в день.

Я могу подумать о написании al oop и обновлении / вставке каждый день и так далее, есть ли более простой способ сделать это? Через API или общедоступный календарь?

Заранее благодарю.

1 Ответ

2 голосов
/ 25 января 2020

Я могу подумать о написании всего oop и обновлении / вставке каждый день и т. Д.,

Да, это путь к go. Никаких фокусов c или серебряных пуль здесь нет.

По сути, вы можете выбрать:

  • Вы можете жестко запрограммировать код в Java, создавая строки в базе данных через JDB C.
  • Запись текстового файла для прямого импорта базой данных, например, команда COPY в Postgres.
  • Запись SQL сценарии для определения таблицы и для каждого года (или около того) вставки строк, которые будут выполняться инструментом миграции схемы базы данных , таким как Flyway или Liquibase .

Лично я бы go с последним. С помощью инструмента миграции вы можете легко просмотреть, что было выполнено и когда. И вы можете легко перенести новый сценарий SQL в рабочий режим, который будет запущен в следующем году, после предварительного тестирования сценария.

Я бы написал небольшое консольное приложение для генерации черновика сценария SQL. Затем отредактируйте вручную праздники. Примерно так:

Year year = Year.of( 2021 );  // Input the year for which we want to create a calendar by way of a SQL script.
// Verify the requested year is in the future.
if ( ! Year.now().isBefore( year ) ) { throw new IllegalArgumentException( "Year must be in the future. Message # a0720f38-f4c5-4aca-9214-d9756a91e372." ); }
String filePath = "/Users/basilbourque/calendar_" + year + ".sql";

String newline = "\n";
StringBuilder sql = new StringBuilder();
sql.append( "INSERT INTO calendar_ ( date_ , holiday_us_ ) " ).append( newline );
LocalDate firstOfYear = year.atDay( 1 );
Stream < LocalDate > dates = firstOfYear.datesUntil( firstOfYear.plusYears( 1 ) );  // Generate a stream of `LocalDate` objects, for each date from start to end, using Half-Open approach where the ending is exclusive.
String joined = 
        dates
        .map( localDate -> "( '" + localDate.toString() + "' , FALSE )" )
        .collect( 
            Collectors.joining( ", " + newline , "VALUES " + newline , newline + " ; " )   // Pass delimiter, prefix, suffix.
        )
;
sql.append( joined );

System.out.println( "sql = " + newline + sql );

try
{
    Files.writeString( 
        Paths.get( filePath ) ,
        sql , 
        StandardCharsets.UTF_8 , 
        StandardOpenOption.CREATE_NEW 
    );
}
catch ( IOException e )
{
    e.printStackTrace();
}

При запуске.

INSERT INTO calendar_ ( date_ , holiday_us_ ) 
VALUES 
( '2021-01-01' , FALSE ), 
( '2021-01-02' , FALSE ), 
…
( '2021-12-31' , FALSE )
 ; 

Через API или общедоступный календарь?

Вы можете найти такой ресурс. Но по моему опыту, большинство компаний используют свой собственный календарь, который может отличаться даже от ближайших конкурентов. Могут быть некоторые исключения в некоторых отраслях в некоторых юрисдикциях, таких как банки и кредитные союзы в Соединенных Штатах, которые имеют общий c официальный запланированный календарь праздников. Но если ваша отрасль не такая, я советую кусать маркеры и создавать свои собственные средства определения календаря, а не полагаться на чужой календарь.

В течение 365 дней по одной строке в день.

Полагаю, датой может быть натуральный ключ для таблицы. Определение его в качестве первичного ключа также установит ограничение UNIQUE, которое предотвращает случайную перезагрузку данных. Обычно я считаю суррогатными ключами лучшими, но я предполагаю, что здесь естественный ключ даты будет работать хорошо.

Если ваши "показатели", которые вы упоминаете, являются дробным числом, обязательно используйте BigDecimal введите Java. И используйте соответствующий тип в вашей базе данных. В Postgres, например, с использованием NUMERIC или DECIMAL обсуждается здесь и здесь .

Звучит как логическое значение По каждой стране (или по юрисдикции или рынку) будет отслеживаться ваш отпуск. Конечно, если вы регулярно добавляете и отбрасываете такие расписания праздников, это следует делать в дочерней таблице, а не в столбцах таблицы календаря.

Таким образом, определение таблицы может выглядеть примерно так:

CREATE TABLE calendar_
(
  date_ DATE NOT NULL ,
  holiday_us_ BOOLEAN NOT NULL ,
  rate_ DECIMAL ,
  CONSTRAINT pkey_calendar_ PRIMARY KEY ( date_ )
)
;

Нет необходимости хранить год или месяц, так как они могут быть выведены из значений столбца DATE. Добавление столбцов для года, месяца и так далее будет нарушать нормализацию базы данных .

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