MySQL的DateTime字段默认情况下是允许为NULL的。当使用MyBatis Plus的
updateById
方法更新数据时,如果DateTime字段为null,会被忽略掉,导致更新失败。为了解决这个问题,可以考虑以下两种方法:
-
使用特定的日期值代替null:
可以选择在DateTime字段为null时,使用一个特定的日期值来代替,比如使用MySQL中的"0000-00-00 00:00:00"或者一个具体的无效日期,来表示该字段的空值。在业务逻辑中,当读取到该特定日期值时,可以将其解释为null。
-
使用Java中的Optional类:(推荐)
可以在Java中使用
Optional
类来处理DateTime字段的空值。将DateTime字段声明为
Optional<LocalDateTime>
类型,即可处理可能为null的情况。在查询时,如果DateTime字段为null,将其包装为
Optional.empty()
;在更新时,如果要设置为空值,可以将其设置为
Optional.empty()
,否则将值包装为
Optional.of(value)
。
以下是第二种方法的示例代码:
User.java:
public class User {
private Long id;
private String username;
private Optional<LocalDateTime> dateTime;
UserMapper.java:
public interface UserMapper extends BaseMapper<User> {
UserService.java:
public class UserService {
private UserMapper userMapper;
public UserService(UserMapper userMapper) {
this.userMapper = userMapper;
public void updateUserDateTime(Long userId, Optional<LocalDateTime> dateTime) {
User user = new User();
user.setId(userId);
user.setDateTime(dateTime);
userMapper.updateById(user);
在这个示例中,DateTime字段被声明为Optional<LocalDateTime>
类型。在updateUserDateTime
方法中,你可以传入Optional.empty()
来表示将DateTime字段设置为null。如果要设置具体的值,可以使用Optional.of(value)
来包装。
使用Optional
类可以更好地表示DateTime字段的空值情况,并与MyBatis Plus的更新方法兼容。当读取和处理数据时,你可以使用Optional
类的方法来判断字段是否为null,并进行相应的处理。
查询数据时数据库为null那么程序中也为null,不会再包装一层
理由:为null时不会更新此字段,减少不必要的数据更新
还需要一些转换器
package com.example.demo.handler;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import java.io.IOException;
import java.util.Optional;
@Configuration
public class JacksonConfiguration {
@Bean
public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.serializerByType(Optional.class, new OptionalSerializer());
builder.deserializerByType(Optional.class, new OptionalDeserializer());
return builder;
public static class OptionalSerializer extends JsonSerializer<Optional<?>> {
@Override
public void serialize(Optional<?> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value.isPresent()) {
gen.writeObject(value.get());
} else {
gen.writeNull();
public static class OptionalDeserializer extends JsonDeserializer<Optional<?>> {
@Override
public Optional<?> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
ObjectMapper mapper = (ObjectMapper) p.getCodec();
JsonNode node = mapper.readTree(p);
if (node.isNull()) {
return null;
if ("".equals(node.textValue())) {
return Optional.empty();
} else {
Object value = mapper.treeToValue(node, Object.class);
return Optional.ofNullable(value);
package com.example.demo.handler;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.springframework.stereotype.Component;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;
import java.util.Optional;
@Component
public class OptionalDateTypeHandler extends BaseTypeHandler<Optional<Date>> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Optional<Date> parameter, JdbcType jdbcType) throws SQLException {
ps.setObject(i, parameter.orElse(null));
@Override
public Optional<Date> getNullableResult(ResultSet rs, String columnName) throws SQLException {
Date date = rs.getTimestamp(columnName);
if (date == null) {
return null;
return Optional.ofNullable(date);
@Override
public Optional<Date> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
Date date = rs.getTimestamp(columnIndex);
if (date == null) {
return null;
return Optional.ofNullable(date);
@Override
public Optional<Date> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
Date date = cs.getTimestamp(columnIndex);
if (date == null) {
return null;
return Optional.ofNullable(date);
可以兼容三种场景
- null 代表不更新
- “” 代表更新为null
- “2023-06-28 16:27:21” 代表更新具体的值
最后在项目中并没有使用这种方式
- 因为相比于直接使用Date类型,这种方式还需要再次进行包装,且前端传时间字段的接口并没有太多。
关联文章 mybatisplus生成工具自定义类型转换
CSDN-Ada助手:
elasticsearch 踩坑
CSDN-Ada助手: