Java --- 用年历更新数据库
Java --- update a database with an annual calendar
使用 Java 加载具有年历的数据库 table 的最佳方法是什么?
365 天每天一行。
我可以想到每天写一个循环和updating/inserting等等,有没有更简单的方法呢?通过 API 或公开可用的日历?
提前致谢。
I can think of writing a loop and updating/inserting every day and so on,
是的,这就是要走的路。这里没有魔术或灵丹妙药。
基本上,您的选择是:
- 您可以在 Java 中对编程进行硬编码,通过 JDBC 在数据库中创建行。
- 编写数据库直接导入的文本文件,如
COPY
command in Postgres.
- 编写 SQL 脚本来定义 table,并为每年(或左右)插入行,由 database schema migration tool such as Flyway or Liquibase.
执行
就我个人而言,我会选择最后一个。使用迁移工具,您可以轻松查看 运行 的内容和时间。在对脚本进行预先测试之后,您可以轻松地将新的 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?
您可能会找到这样的资源。但根据我的经验,大多数企业 运行 都有自己的日历,即使与最接近的竞争对手相比,日历也可能有所不同。某些司法管辖区的某些行业可能会有一些例外,例如美国的银行和信用合作社,它们都共享特定的官方计划假期日历。但如果您不是这样的行业,我建议您硬着头皮创建自己的日历定义工具,而不是依赖别人的日历。
For 365 days one row per day.
我想日期可能是 natural key for the table. Defining it as the primary key will also set a constraint of UNIQUE
, which prevents you from accidentally reloading data. Usually I find surrogate keys 最好的,但我想这里日期的自然键会很好用。
如果您提到的 "rates" 是小数,请务必使用 BigDecimal
输入 Java。并在您的数据库中使用适当的类型。例如,在 Postgres 中,using NUMERIC
or DECIMAL
is discussed here and here.
听起来像每个国家(或每个司法管辖区或市场)的布尔值会跟踪您的假期。当然,如果你经常添加和删除这样的假期安排,这应该在子 table 中完成,而不是作为日历上的列 table.
所以 table 定义可能看起来像这样:
CREATE TABLE calendar_
(
date_ DATE NOT NULL ,
holiday_us_ BOOLEAN NOT NULL ,
rate_ DECIMAL ,
CONSTRAINT pkey_calendar_ PRIMARY KEY ( date_ )
)
;
不需要存储年或月,因为这些可以从 DATE
列值中推导出来。添加年、月等列将违反 database normalization。
使用 Java 加载具有年历的数据库 table 的最佳方法是什么?
365 天每天一行。
我可以想到每天写一个循环和updating/inserting等等,有没有更简单的方法呢?通过 API 或公开可用的日历?
提前致谢。
I can think of writing a loop and updating/inserting every day and so on,
是的,这就是要走的路。这里没有魔术或灵丹妙药。
基本上,您的选择是:
- 您可以在 Java 中对编程进行硬编码,通过 JDBC 在数据库中创建行。
- 编写数据库直接导入的文本文件,如
COPY
command in Postgres. - 编写 SQL 脚本来定义 table,并为每年(或左右)插入行,由 database schema migration tool such as Flyway or Liquibase. 执行
就我个人而言,我会选择最后一个。使用迁移工具,您可以轻松查看 运行 的内容和时间。在对脚本进行预先测试之后,您可以轻松地将新的 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?
您可能会找到这样的资源。但根据我的经验,大多数企业 运行 都有自己的日历,即使与最接近的竞争对手相比,日历也可能有所不同。某些司法管辖区的某些行业可能会有一些例外,例如美国的银行和信用合作社,它们都共享特定的官方计划假期日历。但如果您不是这样的行业,我建议您硬着头皮创建自己的日历定义工具,而不是依赖别人的日历。
For 365 days one row per day.
我想日期可能是 natural key for the table. Defining it as the primary key will also set a constraint of UNIQUE
, which prevents you from accidentally reloading data. Usually I find surrogate keys 最好的,但我想这里日期的自然键会很好用。
如果您提到的 "rates" 是小数,请务必使用 BigDecimal
输入 Java。并在您的数据库中使用适当的类型。例如,在 Postgres 中,using NUMERIC
or DECIMAL
is discussed here and here.
听起来像每个国家(或每个司法管辖区或市场)的布尔值会跟踪您的假期。当然,如果你经常添加和删除这样的假期安排,这应该在子 table 中完成,而不是作为日历上的列 table.
所以 table 定义可能看起来像这样:
CREATE TABLE calendar_
(
date_ DATE NOT NULL ,
holiday_us_ BOOLEAN NOT NULL ,
rate_ DECIMAL ,
CONSTRAINT pkey_calendar_ PRIMARY KEY ( date_ )
)
;
不需要存储年或月,因为这些可以从 DATE
列值中推导出来。添加年、月等列将违反 database normalization。