【问题标题】:Why mybatis insert java.util.Date value to Mysql datetime column then fetch it they are not equal?为什么 mybatis 将 java.util.Date 值插入 Mysql 日期时间列然后获取它们它们不相等?
【发布时间】:2016-08-02 14:15:35
【问题描述】:

Mybatis 将 java.util.Date 插入到 mysql 的 datetime 列中,然后获取它发现它们不匹配

表格

CREATE TABLE `t` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`create_time` datetime DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8

代码

@Insert("insert into t(create_time) values(#{0})")
int insertT(Date date);
@Select("select create_time from t order by id desc limit 1")
Date getLatestCreateTime();

单元测试

    Date date1 = new Date();
    mapper.insertT(date1);

    Date date2 = mapper.getLatestCreateTime();

    Assert.assertEquals(date1, date2);

断言失败

java.lang.AssertionError: 
Expected :Tue Aug 02 22:10:35 CST 2016
Actual   :Tue Aug 02 22:10:36 CST 2016

为什么会这样?

【问题讨论】:

    标签: datetime mybatis mysql-connector


    【解决方案1】:

    因为当TimeUtil中的mysql-connector将Timstamp转换为Date时,它会执行下面的代码

        Timestamp ts = new Timestamp(tsAsMillis1 + (long)offsetDiff);
        ts.setNanos(secondsPart); 
    

    secondsPart 为 0。

    @Test
    public void test_date_compare_date_from_timestamp() {
        Date date1 = new Date();
    
        Timestamp ts = new Timestamp(date1.getTime());
        System.out.println(ts);  // 2016-08-08 22:37:37.078
        Date date2 = new Date(ts.getTime());
        Assert.assertEquals(date1, date2);
        ts.setNanos(0);
        System.out.println(ts); // 2016-08-08 22:37:37.0
        Date date3 = new Date(ts.getTime());
        Assert.assertNotEquals(date1, date3);
    }
    

    而秒数大于原来的秒数,是因为

    insert into t select 1,'2016-08-08 22:42:44.676';
    select * from t;
    +----+---------------------+
    | id | create_time         |
    +----+---------------------+
    |  1 | 2016-08-08 22:42:45 |
    +----+---------------------+
    

    【讨论】:

      【解决方案2】:

      所以,我使用的是这个 mysql 表:-(忽略对象/类名。)

      CREATE TABLE `user_access` (
      `user_id` INT NOT NULL,
      `access_datetime` DATETIME NOT NULL,
      FOREIGN KEY (user_id)  REFERENCES users (user_id) ON DELETE CASCADE
      );
      

      控制器对 mybatis 映射器进行此调用。

      import java.sql.Timestamp;
      import java.util.Date;
      
      cardsMapper.updateUserAccess(user.getEmail(), new Timestamp(new Date().getTime()));
      

      而且mapper接口有傻瓜式的代码:-

      import java.sql.Timestamp;
      @Insert("INSERT INTO user_access VALUES ( (select user_id from users where email = #{email}) , #{dateValue} )")
      void updateUserAccess(String email, Timestamp dateValue);
      

      当代码运行时,该表将日期和时间都存储在 access_datetime 列中。

      希望这对某人有所帮助。 谢谢

      【讨论】:

        猜你喜欢
        • 2022-06-12
        • 1970-01-01
        • 1970-01-01
        • 2021-12-26
        • 2013-08-18
        • 2018-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多