HSQLDB:使用 java 插入/获取日期

Posted

技术标签:

【中文标题】HSQLDB:使用 java 插入/获取日期【英文标题】:HSQLDB: Insert/Get Date with java 【发布时间】:2014-03-25 11:28:32 【问题描述】:

我正在使用 HSQLDB 制作一个小程序(使用 JavaFX gui),我目前正在尝试让“保留”部分工作(用户可以添加新的或在有限的时间内搜索现有的时间)。 为此,我已经预先添加了一些日期(我使用的是 database.sql 脚本),例如:

INSERT INTO reservations(begin, end) VALUES ('2013-08-01', '2013-08-31')

我已经编写了一些方法(创建、更新、删除、搜索、findAll),现在我有点卡在“创建”部分。

我想将新的预订插入到数据库中

pstmt = con.prepareStatement("INSERT INTO reservations(begin, end) VALUES (?,?)");

但我在创建可以插入的新日期时遇到问题。

pstmt.setDate(1, (java.sql.Date) beg);

不起作用(我使用 java.util.Date 对象来保存从数据库中导出的日期),它只是中止了我的测试 (jUnit)。

Calendar cal1 = Calendar.getInstance();
cal1.set(2014, 0, 1);
Date beginn = cal1.getTime();

仅以以下形式创建日期:Wed Jan 01 12:23:15 CET 2014

但是(我不知道日期是如何保存在 HSQLDB 中的)我希望日期为“YYYY-MM-DD”。

那么,将日历日期转换为我需要的格式的最佳方法是什么(并将它们强制转换?不幸的是,将字符串转换为日期不起作用)。并且:如果我打算使用 JavaFX 让用户选择开始日期和结束日期,那么我使用 java.util.Date 日期的方法可以吗?

【问题讨论】:

我现在遇到了另一个问题:a.equals(b) 不会返回 "true"........a 是 "Date a = new java.sql.Date( r.getBegin().getTime());"其中 r 是一个新的预留实例........b 是 "b = rs.getDate("begin");" (使用带有“SELECT begin, end FROM reservation”的 Statement & ResultSet rs........它应该返回“true”,因为我首先创建了 r,将其提交到数据库(工作正常)然后使用它与“find(r)”一起使用,但仍然没有,所以日期肯定有问题(已经检查过,“find”方法适用于除日期之外的所有内容)......:/知道什么是错了吗? 是的,我所期望的...a.getTime()=1388603443625 但 b.getTime()=1388530800000 .... ToString() 对两者都返回相同的 (2014-01-01) a 和 b (至少是同一天),所以我猜这是因为 Calendar?有没有办法只将 h、min 和 sec 设置为 0,所以两个日期都相同?到目前为止,我发现的唯一东西包括那些是“set(int year,int month,int date,int hourOfDay,int minute,int second)”但看起来没有办法只设置 h,min秒?! 【参考方案1】:

而不是(java.sql.Date) beg 导致ClassCastException 你应该写:

new java.sql.Date(beg.getTime()); // provided beg is of type java.util.Date as you wrote

如果您在 VALUES 子句中使用字符串,您可能会考虑将 JDBC-escape-syntax 用于日期。而您的声明“仅以以下形式创建日期:Wed Jan 01 12:23:15 CET 2014”根本不重要,因为您只看到方法 toString()of java.util.Date 的输出。它与数据库中的内部状态或存储无关。你的愿望“我希望日期是“YYYY-MM-DD”。”与您的应用程序的表示层相当相关,而不是与您无法控制的 db 的内部存储格式相关,除了选择适当的 db 列类型(此处:ANSI-SQL-DATE)。

在表示层中,您可以使用 SimpleDateFormat 之类的类来获得所需的输出。

编辑(因为 cmets 中的问题):

好的,您真的不必担心java.util.Date-timestamp 的toString()-表示。它的内部状态只是一个 long 表示自 1970-01-01 以来经过的毫秒,不包括闰秒。只需忽略 java.util.Date 的标准输出,它会显示系统区域上下文,而不是内部状态。使用a.before(b) 是完全可以的,与toString()-method 的java.util.Date 的奇怪输出无关。

此外:您无法真正控制数据库工具如何显示日期列值。这就是您使用的工具的秘密。 db 内部的状态可能完全不同,所以每个 db 就像一个黑盒子。

但是当您从 db 读取日期值并将数据呈现给用户时,您必须担心java.util.Date-objects 的表示。为此,我建议使用SimpleDateFormat - 见上文。但是这种适配(转换为可读的人类日期格式)不在 db-tool 中,不在 JDBC 层中,而在用户表示层中,通常在 UI 中。

【讨论】:

不,我在 den DB 中使用 DATE:“CREATE TABLE 保留(resid INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,开始 DATE NOT NULL,结束 DATE NOT NULL)”...... ............. 我将使用 JavaFX 场景构建器来制作布局,我只想让它与日历下拉菜单一起工作(这样用户就可以选择他们喜欢的时间段)想搜索)。您怎么看:使用 java.util.Date 并将其转换为 java.sql.Date 更好还是应该从一开始就使用后者? @Neph 您只在您的 JDBC 层内使用java.sql.Date,它作为您的PreparedStatement 中的参数。在外面你可以使用java.util.Date(虽然我认为它已经坏了,但这是另一个话题)。再说一遍:不要投射,而是换行。 关于外观的事情是:如果我在 java.sql.Date 上使用 logger.info()(应该来自 log4j)它输出“2014-01-01”,java.util。另一方面,日期输出整个内容,包括日期、小时、分钟和秒的名称,因为我必须比较选择的日期和数据库中的日期(使用 java.util.Date 中的 a.before(b) ),我担心它不会起作用,因为它看起来像 java 版本保存了更多的信息。是的,我想在自己的列中以“YYYY-MM-DD”格式输出表格中的所有预订。 所以据我了解:“public ArrayList search(Date a, Date b)”(我在测试类和服务类中创建它的实例)应该是java.sql.dates 并在将 a 和 b 提交给“搜索”方法之前,我应该将它们包装在例如使用 java.sql.Date a=new java.sql.Date(a1) 测试类,其中 a1 为 Date a1 = cal1.getTime();对吗?

以上是关于HSQLDB:使用 java 插入/获取日期的主要内容,如果未能解决你的问题,请参考以下文章

数据库 Hsqldb 无法区分日期和时间戳

HSQLDB:原因:使用 MAX,但不使用 Group By,并获取 java.sql.SQLSyntaxErrorException:表达式不在聚合或 GROUP BY 列中:

java.sql.SQLException:无法从底层数据库获取连接! — HSQLDB

HSQLDB 如果不存在则插入,如果存在则更新

java获取excel日期

获取当前日期和时间