java.sql.Date、java.sql.Time 和 java.sql.Timestamp

大多数数据库支持三种形式的日期时间字段,即 DATE、TIME 和 TIMESTAMP。它们中的每一个在 JDBC 中都有一个对应的类,并且它们中的每一个都扩展了java.util.Date。这三个是:

  • java.sql.Date表示 SQL DATE,存储年、月和日,没有时间组件。java.sql.Date 不考虑时区。
  • java.sql.Time表示 SQL TIME,仅包含有关小时、分钟、秒和毫秒的信息,不包含日期组件。
  • java.sql.Timestamp表示 SQL TIMESTAMP,它包含精确到纳秒精度的日期和时间信息。

让我们检查下表,参考前 5 个数据库(不按顺序)日期时间数据类型:

DatabaseSQL DATESQL TIMESQL TIMESTAMPSource
MySQL / MariaDBDATE
DATETIME
TIMETIMESTAMPLink
Link
PostgreSQLDATETIME
TIME WITH TIME ZONE
TIMESTAMP
TIMESTAMP WITH TIME ZONE
Link
OracleDATETIMESTAMP
TIMESTAMP WITH TIME ZONE
TIMESTAMP WITH LOCAL TIME ZONE
Link
Microsoft SQL ServerDATE
SMALLDATETIME
DATETIME
DATETIME2
DATETIMEOFFSET
TIMELink
IBM Db2DATETIMETIMESTAMPLink

我把来源,我的参考放在最右边的栏中。如我错了请纠正我

使用 JDBC 类

选择哪个类取决于字段的 SQL 类型。PreparedStatement 具有所有三个值的设置器,setDate() 用于 java.sql.Date,setTime() 用于 java.sql.Time 和 setTimestamp() 用于 java.sql.Timestamp。

让我们举个例子,我们在数据库中创建一个测试表。对于本文,我将使用 MySQL。

CREATE TABLE test_datetime (
  dtm_date DATE,
  dtm_time TIME,
  dtm_timestamp TIMESTAMP,
  obj_date DATE,
  obj_time TIME,
  obj_timestamp TIMESTAMP
);
然后我们将当前日期/时间(通过 new java.util.Date() 获取)插入到 SQL 数据库表的日期字段中。
SqlDateTimeInsertExample.java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
 
public class SqlDateTimeInsertExample {
 
    public static void main(String[] args) throws Exception {
        // (1) connect to mysql database
        String url = "jdbc:mysql://localhost/coffeehouse?serverTimezone=Asia/Singapore";
        Class.forName("com.mysql.cj.jdbc.Driver");
 
        try (Connection conn = DriverManager.getConnection(url, "barista", "cappuccino")) {
            // (2) set java.sql.Date, Time, and Timestamp with current Date (and time)
            java.util.Date utilDate = new java.util.Date();
            java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
            java.sql.Time sqlTime = new java.sql.Time(utilDate.getTime());
            java.sql.Timestamp sqlTS = new java.sql.Timestamp(utilDate.getTime());
            // (3) insert java.sql.Date, Time and Timestamp (including objects) to DB
            String sql = "INSERT INTO test_datetime("
                    + "dtm_date, dtm_time, dtm_timestamp,"
                    + "obj_date, obj_time, obj_timestamp) VALUES (?,?,?,?,?,?)";
            try (PreparedStatement pst = conn.prepareStatement(sql)) {
                pst.setDate(1, sqlDate);
                pst.setTime(2, sqlTime);
                pst.setTimestamp(3, sqlTS);
                
                pst.setObject(4, utilDate);
                pst.setObject(5, utilDate);
                pst.setObject(6, utilDate);
                
                // (4) execute update
                pst.executeUpdate();
            }
        }
    }
}

如上例,使用 setObject(int parameterIndex , x Object); 我们可以只给最后三个参数一个 util.Date ,它们可以毫无问题地接受它(这也发生在另一个 JDBC 驱动程序中,而不仅仅是 MySQL)。但是只是懒惰地使用 setObject(...) 会导致一些问题,包括数据(或部分数据)丢失。

注意: URL 后缀 ?serverTimezone=Asia/Singapore 是为了抑制:线程“main”中的异常 java.sql.SQLException:服务器时区值“马来半岛标准时间”无法识别或代表多个时区。如果要使用时区支持,则必须配置服务器或 JDBC 驱动程序(通过 serverTimezone 配置属性)以使用更具体的时区值。

(你能看到上面 MySQL JDBC 错误消息中的错字吗?:p)

连接mysql确认结果:

$ mysql -u barista -p
Enter password: **********
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 5.5.27 MySQL Community Server (GPL)

mysql> connect coffeehouse
Connection id:    10
Current database: coffeehouse

mysql> select * from test_datetime;
+------------+----------+---------------------+------------+----------+---------------------+
| dtm_date   | dtm_time | dtm_timestamp       | obj_date   | obj_time | obj_timestamp       |
+------------+----------+---------------------+------------+----------+---------------------+
| 2019-08-15 | 15:48:19 | 2019-08-15 15:48:19 | 2019-08-15 | 15:48:19 | 2019-08-15 15:48:19 |
+------------+----------+---------------------+------------+----------+---------------------+
1 row in set (0.00 sec)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值