mysql数据库时间字段相差8个小时解决办法

当遇到MySQL数据库时间字段与本地时间相差8小时的问题时,可以利用MyBatis的类型转换器功能来解决。通过创建自定义的DateHandler,并指定泛型为Date,然后在MyBatis配置中注册该类型处理器。在操作数据库的insert、update、delete语句中,为日期参数指定typeHandler,而select查询语句则无需修改。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据库->mysql

持久层框架->mybatis


解决思路:使用mybatis提供的类型转换器功能


创建DateHandler,指定泛型为Date

package cn.nsu.edu.web.four.handler.mybatis;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.sql.*;
import java.util.Calendar;
import java.util.Date;

/**
 * @author 墨盒
 * @version 1.0
 * @Date 2017/10/23
 * @Time 18:19
 * @Descorption
 */
public class DateHandler extends BaseTypeHandler<Date> {
    Log log = LogFactory.getLog(getClass());

    @Override
    public void setParameter(PreparedStatement ps, int i, Date parameter, JdbcType jdbcType) throws SQLException {
//        super.setParameter(ps, i, parameter, jdbcType);
        Timestamp timestamp = new Timestamp(parameter.getTime());
        log.info("插入的时间   "+new Date(parameter.getTime())+ "    "+timestamp);
        //指定Calendar即可解决时差
        ps.setTimestamp(i,timestamp, Calendar.getInstance());

    }

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {
        preparedStatement.setString(i, date.toString());
    }

    @Override
    public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
        return resultSet.getTimestamp(s, Calendar.getInstance());

    }

    @Override
    public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
//        log.info("getNullableResult(ResultSet resultSet, int i)  " + resultSet.getDate(i).toString());
        return resultSet.getTimestamp(i, Calendar.getInstance());
    }

    @Override
    public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        return callableStatement.getTime(i, Calendar.getInstance());
    }
}


配置mybatis typeHandler

<typeAliases>
		<!--时间handler-->
		<typeAlias type="cn.nsu.edu.web.four.handler.mybatis.DateHandler" alias="dateHandler"/>
	</typeAliases>

	<!-- <typeAliases>
		单个别名定义 type:pojo的路径 alias:别名的名称
		<typeAlias type="cn.itcast.mybatis.po.User" alias="user"/>
		批量别名定义 name:指定包名,将包下边的所有pojo定义别名 ,别名为类名(首字母大写或小写都行)
		 <package name="com.nsu.bean" /> 
	</typeAliases> -->

	<typeHandlers>
    <!--此处只需要指定javaType即可,jdbcType不指定,只要mybatis sql传入javaType类型即可调用该类            
 <typeHandler handler="cn.nsu.edu.web.four.handler.mybatis.DateHandler" javaType="java.util.Date" />
	</typeHandlers>

使用方法——select语句不需要任何修改,insert、update、delete语句,传参时最好指定typeHandler


### MySQL 显示时间与当前时间相差 8 小时的解决方案 当遇到 MySQL 中显示的时间与实际时间相差 8 小时时,通常是因为时区配置不当引起的。以下是几种常见的解决方法: #### 方法一:调整 MySQL 配置文件中的时区设置 可以通过修改 MySQL 的配置文件 `my.cnf` 或 `my.ini` 来指定服务器的默认时区。在 `[mysqld]` 节点下添加如下参数: ```ini default-time-zone='+08:00' ``` 保存并重启 MySQL 服务即可生效[^1]。 #### 方法二:通过 JDBC 连接字符串设置时区 如果是在 Java 应用程序中连接 MySQL 数据库,可以在 JDBC URL 参数中显式声明时区为 UTC+8。例如: ```java jdbc:mysql://localhost:3306/database_name?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false ``` 此方式可以确保应用程序和数据库之间的时区一致性[^3]。 #### 方法三:更新 Docker 容器内的时区文件 对于运行在 Docker 上的 MySQL 实例,可能由于容器内部未正确同步宿主机的时区而导致时间偏差。可通过以下命令将宿主机上的时区文件复制到容器内,并覆盖 `/etc/localtime` 文件: ```bash docker cp /usr/share/zoneinfo/Asia/Shanghai mysql_container:/usr/share/zoneinfo/Asia/Shanghai docker exec -it mysql_container bash -c 'cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone' ``` 完成操作后需重新启动容器以应用更改[^5]。 #### 方法四:避免使用 NOW() 函数直接获取时间 虽然 SQL 查询语句中经常使用 `NOW()` 获取当前时间戳,但如果存在跨区域部署或者不同组件间有独立设定各自时区的情况,则可能导致最终结果不符合预期。因此建议改由业务逻辑层传入精确的时间值而不是依赖于数据库端计算得出的结果[^2]。 #### 方法五:针对 Flink CDC 场景下的特殊处理 考虑到某些框架如 Apache Flink 使用 Debezium 插件捕获变更事件流时,默认会将以 DATETIME 类型存储的数据转换成基于协调世界时 (UTC) 表达形式再向外推送;然而这样做的后果便是原本按照本地标准记录下来的时刻被错误解释成了另一个偏移量所对应的新数值——即出现了所谓的“少八小时现象”。对此类状况目前尚无官方支持直接修正源头行为的办法,但我们可以尝试手动调整目标字段内容来弥补差异,比如利用 TIMESTAMPDIFF 函数动态加回丢失的部分作为临时应对措施之一[^4]: ```sql SELECT *, DATE_ADD(event_time, INTERVAL 8 HOUR) AS adjusted_event_time FROM your_table; ``` 综上所述,具体采取哪种策略取决于项目环境以及个人偏好等因素综合考量之后决定最为合适的做法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值