解决mybatis查询日期时间数据得到long类型数据的问题,页面上时间格式显示为时间戳的问题

转载出处:[https://blog.youkuaiyun.com/qq_29216083/article/details/77678981]
使用mybatis查询数据时,如果数据库存储的是timestamp、datetime、date、time等时间类型,而Java bean也使用的是date类型,mybatis会自动将date类型转换为unix long时间eg:1503912320000,而不是时间格式。
解决方式有两种:
1.将Java bean 中的类型改为String类型。
2.在java bean 中date类型的get方法上加上注解@JsonFormat
jackson中有一个@JsonFormat注解,将它配置到Date类型的get方法上后,jackson就会按照配置的格式转换日期类型

    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    public Date getEnddate() {
        return enddate;
    }

这样获取到的值就是正常的日期格式了。

或者是使用fastjson返回,
使用SerializerFeature特性格式化日期。
JSON.toJSONString(data, SerializerFeature.WriteDateUseDateFormat);
也能返回正常的日期格式。

<think>好的,我现在要解决问题是,实体类中的Date类型字段在使用MyBatis查询时,返回的结果是时间戳格式,而不是预期的日期格式。我需要找出原因,并给出解决方案。 首先,我需要回忆一下MyBatis如何处理数据库中的日期类型和Java实体类之间的映射。通常,数据库中的日期时间类型(如DATEDATETIME、TIMESTAMP)会被JDBC驱动转换为Java的java.util.Date或java.sql.Date、Time、Timestamp等类型。如果实体类中使用的是java.util.Date,而数据库中的字段是DATETIME或TIMESTAMP,MyBatis应该能正确映射,但显示时间戳可能是因为Date对象的toString()方法默认输出格式的问题。 接下来,用户提到返回的是时间戳格式,这可能是指从数据查询得到的日期字段在Java中被转换为长整型时间戳,或者在使用时被格式化为时间戳字符串。需要区分这两种情况。 情况一:数据库中的字段是时间戳类型(如BIGINT存储的毫秒数),而实体类中使用Date类型。这时,MyBatis无法自动转换,需要手动处理类型转换。 情况二:数据库中的字段是日期时间类型(如DATETIME),但查询结果在Java中显示时间戳格式,这可能是因为Date对象在输出时(如日志、JSON序列化)使用了默认的toString()方法,导致显示为类似"Wed Dec 20 10:55:03 CST 2023"的格式,或者转换为时间戳数值。 需要确认具体是哪一种情况。假设用户的情况是数据库字段存储的是日期时间类型,但返回Date对象在转换成字符串时显示时间戳格式。这时候的问题可能出在数据的序列化过程,比如在转换成JSON响应时,没有正确格式化日期字段。 解决方案可能包括: 1. 在MyBatis的ResultMap中指定字段的类型处理器(TypeHandler),或者使用注解指定jdbcType和javaType。 2. 在实体类的Date字段上使用注解,如@JsonFormat(如果使用Jackson进行JSON序列化)来指定日期格式。 3. 配置全局的日期序列化格式,例如在Spring Boot中配置Jackson的日期格式。 另外,需要检查数据库驱动是否正确处理日期类型。例如,MySQL的JDBC驱动在连接参数中可以通过指定useLegacyDatetimeCode=false和serverTimezone来正确处理时区问题,避免日期转换错误。 可能的步骤: 1. 确认数据库字段类型是否为日期时间类型,如DATETIME或TIMESTAMP,而不是存储时间戳的数值类型。 2. 检查实体类中的字段是否为java.util.Date或java.sql.Timestamp,如果数据库字段是TIMESTAMP,MyBatis默认会映射为Timestamp,而DATE会映射为java.sql.Date。但java.util.Date可以接收这些类型。 3. 如果数据库存储的是时间戳数值,则需要自定义TypeHandler来转换数值为Date对象。 例如,如果数据库中的字段是BIGINT类型存储时间戳,那么在MyBatis查询结果映射时,可以使用自定义的TypeHandler将Long转换为Date。 4. 如果问题出现在JSON序列化中,例如使用Spring MVC返回JSON响应,Date对象会被Jackson库序列化为时间戳。此时需要在字段上添加@JsonFormat注解,指定日期格式。 例如: @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date createDate; 5. 另外,可以在application.properties中配置全局的日期格式: spring.jackson.date-format=yyyy-MM-dd HH:mm:ss spring.jackson.time-zone=GMT+8 这样所有Date类型的字段都会按此格式序列化。 总结可能的原因和解决方法: - 数据库字段类型正确,但MyBatis处理无误,问题出在后续的序列化格式,需配置日期格式化。 - 数据库字段实际存储的是时间戳数值,需要自定义TypeHandler进行转换。 需要用户进一步确认数据库字段的类型以及问题出现的场景(如直接输出对象还是JSON响应)。根据常见情况,可能更倾向于JSON序列化的问题,因此建议检查并配置日期格式的序列化方式。</think>### 问题原因分析: 当实体类中的`java.util.Date`字段从MyBatis查询结果中映射时,若返回时间戳格式(如`1630320000000`或`Wed Dec 20 10:55:03 CST 2023`),通常由以下原因导致: 1. **数据库字段类型不匹配**:数据库存储的是数值型时间戳(如`BIGINT`),而非日期类型(如`DATETIME`)。 2. **序列化格式问题**:MyBatis正确映射为`Date`对象,但后续序列化(如JSON转换)未指定格式,导致显示时间戳。 --- ### 解决方案: #### 情况1:数据库字段是数值型时间戳(如`BIGINT`) 若数据库字段直接存储时间戳数值(如`1630320000000`),需通过**自定义TypeHandler**将数值转为`Date`。 **步骤:** 1. **创建TypeHandler类**: ```java @MappedTypes(Date.class) @MappedJdbcTypes(JdbcType.BIGINT) public class TimestampToDateTypeHandler extends BaseTypeHandler<Date> { @Override public void setNonNullParameter(PreparedStatement ps, int i, Date parameter, JdbcType jdbcType) throws SQLException { ps.setLong(i, parameter.getTime()); } @Override public Date getNullableResult(ResultSet rs, String columnName) throws SQLException { long timestamp = rs.getLong(columnName); return rs.wasNull() ? null : new Date(timestamp); } @Override public Date getNullableResult(ResultSet rs, int columnIndex) throws SQLException { long timestamp = rs.getLong(columnIndex); return rs.wasNull() ? null : new Date(timestamp); } @Override public Date getNullableResult(SQLSession session, Object parameter) throws SQLException { // 根据实际情况实现(如CallableStatement) return null; } } ``` 2. **在MyBatis配置中注册TypeHandler**: ```xml <!-- mybatis-config.xml --> <typeHandlers> <typeHandler handler="com.example.TimestampToDateTypeHandler"/> </typeHandlers> ``` 3. **在Mapper XML中指定字段类型处理器**: ```xml <resultMap id="userResultMap" type="User"> <result column="create_time" property="createTime" typeHandler="com.example.TimestampToDateTypeHandler"/> </resultMap> ``` --- #### 情况2:数据库字段是日期类型(如`DATETIME`),但序列化为时间戳MyBatis正确返回`Date`对象,但JSON序列化显示时间戳,需**指定日期格式**。 **方法1:使用`@JsonFormat`注解(推荐)** ```java public class User { @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date createTime; } ``` **方法2:全局配置Jackson序列化格式(Spring Boot)** ```properties # application.properties spring.jackson.date-format=yyyy-MM-dd HH:mm:ss spring.jackson.time-zone=GMT+8 ``` --- #### 补充检查点: 1. **确认数据库字段类型**: - 使用`DESC table_name;`检查字段是否为`DATE`/`DATETIME`/`TIMESTAMP`。 2. **验证JDBC连接参数**(如MySQL): ```properties spring.datasource.url=jdbc:mysql://localhost:3306/db?useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai ``` - 避免因时区或旧版驱动导致日期解析错误。 --- ### 总结: - **数据库存数值时间戳** → 自定义TypeHandler。 - **数据库存日期类型** → 配置序列化格式(`@JsonFormat`或全局配置)。 - 确保JDBC驱动正确处理时区。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值