Java操作数据库出现的时间差

问题复现

  • 使用参数占位符的形式执行SQL时,若传入的类型为时间类型则可能产生因时区导致的时间差,从而造成数据异常。

  • 代码如下:

    public static void main(String[] args) throws Exception {
        Class.forName("com.mysql.cj.jdbc.Driver");
        Properties prop = new Properties();
        prop.load(Resources.getResourceAsStream("jdbc.properties"));
        Connection conn = DriverManager.getConnection(prop.getProperty("url"),
                                                      prop.getProperty("username"), prop.getProperty("password"));
        PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM date_test WHERE created <= ?");
        pstmt.setObject(1, new Date()); // 此处传入的值会被MySQL驱动根据类型进行相应处理
        System.out.println(pstmt); // 打印出执行的SQL
        pstmt.close();
        conn.close();
    }
    

问题原因

  • 在调用setObject等方法时,驱动会根据传入的数据类型做出相应的处理。

  • 传入日期类型时则会走到 ClientPreparedQueryBindings.java源文件的setTimestamp()方法里。

  • 在方法里会有如下一行代码:

    this.tsdf = TimeUtil.getSimpleDateFormat(this.tsdf, "''yyyy-MM-dd HH:mm:ss", this.session.getServerSession().getServerTimeZone());
    
  • getServerTimeZone()方法则去获取数据库的默认时区,优先获取数据库连接信息上指定的,其次再去获取数据库服务器设置的时区,然后根据时区转换传入的时间,时间差也因此产生。

解决方案

方式一:增加数据库连接信息参数

  • 在连接信息的url值增加参数:serverTimezone=Asia/Shanghai
  • 参数键值对之间使用&符号连接。
  • 时区值也可以写为GMT%2B8,均表示中国的时区,具体根据实际情况设置时区。

方式二:改变数据库时区设置

  • 进入MySQL命令行界面后进行如下操作

    # 查看当前服务器的时区
    show variables like '%time_zone%';
    # 设置服务器时区为正八时区
    set time_zone = '+8:00';
    # 查询当前时间来验证修改是否生效
    select now();
    

方式三:使用字符串类型作为时间参数

  • 在使用参数占位符操作数据库时,传入日期类型的地方使用字符串的形式传入。
  • 注意传入的时间格式要与数据库的格式保持一致否则也会产生异常。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值