MyBatis 3.4+ 原生支持 Java 8 日期时间类型,无需额外插件,但需确保 JDBC 驱动兼容(如 MySQL 8.0.23+)、数据库字段类型匹配(LocalDateTime↔DATETIME、LocalDate↔DATE),并注意时区配置与驱动参数。

MyBatis 3.4+ 原生支持 Java 8 的新日期时间类型(如 LocalDateTime、LocalDate、LocalTime、ZonedDateTime 等),无需额外引入插件,但需注意 JDBC 驱动兼容性、数据库字段类型匹配以及配置细节。
确保使用兼容的 JDBC 驱动和数据库版本
旧版驱动(如 MySQL Connector/J 5.1.x)对 java.time 类型支持不完整,容易抛出 SQLException: Cannot convert class java.time.LocalDateTime。建议:
- MySQL:升级到 Connector/J 8.0.23+,连接 URL 中添加
useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true(根据实际时区调整) - PostgreSQL:使用 42.2.0+ 驱动,原生支持
timestamp→LocalDateTime - HikariCP 等连接池默认启用 `autoCommit=false` 不影响日期映射,但需确认驱动已正确加载
数据库字段类型与 Java 类型对应关系
映射失败常因类型不匹配。关键对应如下:
-
LocalDateTime↔DATETIME(MySQL)、timestamp without time zone(PostgreSQL) -
LocalDate↔DATE -
LocalTime↔TIME -
OffsetDateTime/ZonedDateTime需数据库支持带时区类型(如 PostgreSQL 的timestamp with time zone),MySQL 建议存为 UTCDATETIME+ 应用层处理时区
Mapper XML 或注解中无需特殊写法
只要驱动和类型匹配,MyBatis 会自动委托 JDBC 驱动完成转换。例如:
立即学习“Java免费学习笔记(深入)”;
<select id="selectUser" resultType="User">
SELECT id, name, create_time AS createTime FROM user WHERE id = #{id}
</select>
对应 Java 实体:
public class User {
private Long id;
private String name;
private LocalDateTime createTime; // 自动映射成功
}
若仍报错,可显式指定 JDBC 类型(非必需,仅调试用):
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
自定义 TypeHandler(仅需特殊逻辑时)
比如统一将数据库中的秒级时间戳(BIGINT)转为 LocalDateTime:
public class TimestampToLdtTypeHandler extends BaseTypeHandler<LocalDateTime> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, LocalDateTime parameter, JdbcType jdbcType) {
long epochSecond = parameter.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
ps.setLong(i, epochSecond);
}
@Override
public LocalDateTime getNullableResult(ResultSet rs, String columnName) {
long timestamp = rs.getLong(columnName);
return LocalDateTime.ofInstant(Instant.ofEpochSecond(timestamp), ZoneId.systemDefault());
}
// ... 其他重写方法
}
注册方式(在 MyBatis 配置中):
<typeHandlers>
<typeHandler handler="com.example.TimestampToLdtTypeHandler"
javaType="java.time.LocalDateTime"
jdbcType="BIGINT"/>
</typeHandlers>
不复杂但容易忽略驱动和字段类型的协同匹配。保持驱动新版、字段语义一致、避免过度自定义,基本就能稳定使用新日期类型。


















