Java --- 用年历更新数据库

标签 java database calendar

使用 Java 加载带有年历的数据库表的最佳方法是什么?

365 天,每天一行。

我可以考虑编写一个循环并每天更新/插入等等,有没有更简单的方法来做到这一点?通过 API 或公开可用的日历?

提前感谢您。

最佳答案

I can think of writing a loop and updating/inserting every day and so on,

是的,这就是要走的路。这里没有魔术或 Elixir 。

基本上,您的选择是:

  • 您可以用 Java 进行硬编码,通过 JDBC 在数据库中创建行。
  • 编写一个文本文件供数据库直接导入,如COPY命令 Postgres .
  • 编写 SQL 脚本来定义表,并为每年(左右)插入行,由 database schema migration 执行工具如FlywayLiquibase .

就我个人而言,我会选择最后一个。使用迁移工具,您可以轻松查看运行的内容和时间。在事先测试脚本后,您可以轻松地将新的 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 )
 ; 

Via an API or publicly available calendar?

您可能会找到这样的资源。但根据我的经验,大多数企业都有自己的日历,即使与最接近的竞争对手相比,这些日历也可能有所不同。某些司法管辖区的某些行业(例如美国的银行和信用合作社)可能存在一些异常(exception)情况,它们都共享特定的官方计划假期日历。但如果您所在的行业不是这样的行业,我建议您咬紧牙关,创建自己的日历定义工具,而不是依赖别人的日历。

For 365 days one row per day.

我想日期可能是natural key对于 table 。将其定义为主键还会设置 UNIQUE 约束,这可以防止您意外地重新加载数据。通常我会找到surrogate keys最好,但我想在这里日期的自然键会很好用。

如果您提到的“费率”是小数,请务必使用 Java 中的 BigDecimal 类型。并在数据库中使用适当的类型。例如,在 Postgres 中,using NUMERIC or DECIMAL正在讨论herehere .

听起来每个国家(或每个司法管辖区或市场)的 boolean 值都会跟踪您的假期。当然,如果您经常添加和删除此类假期安排,则应在子表中完成此操作,而不是作为日历表上的列。

因此表定义可能如下所示:

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

无需存储年份或月份,因为这些可以从 DATE 列值中推断出来。添加年、月等列将违反 database normalization

关于Java --- 用年历更新数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59901757/

相关文章:

javascript - 在日期选择器上隐藏日历

java - JMS 中的客户端确认

database - Liquibase Maven 和命令行工作方式不同

java - 使用@Conditional时如何强制Spring首先运行BeanFactoryPostProcessor

php - 如何使用数据库实时创建 Laravel 图表包

c# - 如果我添加随机盐,如何检查密码是否正确?

java - 将事件添加到此日历

java - 比较两个包含日期的字符串以检查其中一个是在另一个之前还是之后

java - 将属性值名称存储为字符串常量 - 性能和内存使用情况?

java - 匹配 Java 正则表达式中可选组包围的内容