添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
阳光的香槟  ·  Objective C ...·  6 月前    · 
发财的蛋挞  ·  Shell ...·  1 年前    · 

MySQL的DateTime字段默认情况下是允许为NULL的。当使用MyBatis Plus的 updateById 方法更新数据时,如果DateTime字段为null,会被忽略掉,导致更新失败。为了解决这个问题,可以考虑以下两种方法:

  1. 使用特定的日期值代替null:
    可以选择在DateTime字段为null时,使用一个特定的日期值来代替,比如使用MySQL中的"0000-00-00 00:00:00"或者一个具体的无效日期,来表示该字段的空值。在业务逻辑中,当读取到该特定日期值时,可以将其解释为null。
  2. 使用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;
    // getters and setters

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);

可以兼容三种场景

  1. null 代表不更新
  2. “” 代表更新为null
  3. “2023-06-28 16:27:21” 代表更新具体的值

最后在项目中并没有使用这种方式

  1. 因为相比于直接使用Date类型,这种方式还需要再次进行包装,且前端传时间字段的接口并没有太多。

关联文章 mybatisplus生成工具自定义类型转换

CSDN-Ada助手: 恭喜您写得第18篇博客!标题“chatgpt 功能列表”看起来很有趣。您对chatgpt的功能进行了详细的介绍,这对那些想要了解它的人来说肯定非常有帮助。我很欣赏您的持续创作精神,而且您的文章内容一直都很有深度。 在下一步的创作中,或许您可以考虑加入一些个人的使用心得或是案例分析,这样读者能更好地理解chatgpt在实际应用中的价值。当然,这只是一个谦虚的建议,因为我知道您已经做得很出色了。期待您未来更多精彩的创作! elasticsearch 踩坑 CSDN-Ada助手: “恭喜你写了第19篇博客!看到你在探索elasticsearch的过程中踩坑,真的很有勇气和毅力。希望你能继续分享你的经验和教训,也希望你可以尝试在下一篇博客中加入一些具体的案例分析,这样可以让读者更加深入地了解你的学习过程。加油!”