• Java应用开发各种奇葩的问题


    1、Lombok

    1.1 创建子类,无法对父类属性进行赋值

    1. @Data 和@Builder 不可以混用
      @Builder 和 @Data 搭配使用,导致生成的构造器是可变的,它允许使用 setter 方法修改构造器的状态。这违反了构造器模式的原则,构造器应该是不可变的,一旦创建就不能被修改。
      **注意:**如果非要使用 @Builder ,那么不要用 @Data ,要用 @Getter。相对来说,反而 @Accessors 的行为更符合这个要求。
    2. @Data 无法对父类属性进行赋值
    • @Data注解可以用来生成类的getter、setter、构造方法和toString方法。然而,默认情况下,它只会考虑当前类中存在的属性(字段),而不会考虑其父类中的属性。如果你希望@Data也考虑父类中的属性,需要使用@Accessors注解和@Data一起使用。
    @Accessors(fluent=true)
    public class Parent {
        private int parentProperty;
    }
    
    @Data
    public class Child extends Parent {
        private int childProperty;
    }
    
    Child child = new Child();
    child.setParentProperty(10);
    child.setChildProperty(20);
    System.out.println(child); // prints Child{parentProperty=10, childProperty=20}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 如果父类用了@Data 此时子类如何给父类属性赋值
      如果父类使用了@Data注解,子类可以通过以下两种方式给父类复制属性: 使用@Accessors(fluent=true)注解:在子类上添加@Accessors(fluent=true)注解,可以使得子类的属性可以通过链式调用的方式进行赋值,这样就可以使用子类给父类复制属性。例如:
    @Data
    public class Parent {
        private String name;
    }
    
    @Data
    @Accessors(fluent=true)
    public class Child extends Parent {
        private String age;
    }
    
    Child child = new Child();
    child.setName("John").setAge("18");
    Parent parent = child.toParent();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 使用@AccessorsPrefix注解:在子类上添加@AccessorsPrefix注解,可以为子类的属性指定前缀,以区分子类和父类的属性。例如:
    @Data
    public class Parent {
        private String name;
    }
    
    @Data
    @Accessors(prefix = "p")
    public class Child extends Parent {
        private String age;
    }
    
    Child child = new Child();
    child.setName("John").setAge("18");
    Parent parent = child.toParent();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    1. @AllArgsConstructor 构造函数 无法初始化父类的属性
      @AllArgsConstructor注解只能用来生成具有指定参数的构造函数,它并不会初始化父类的属性。 如果希望初始化父类的属性,可以在子类的@AllArgsConstructor注解的父类属性上添加@ToString(callSuper = true);
      @EqualsAndHashCode(callSuper = true)
    2. @ToString(callSuper =true) 实现toString 属性覆盖父类
    3. @EqualsAndHashCode(callSuper = true)覆盖父类

    2、MybatisPLus

    2.1 MybatisPLus自动填充公共参数

    在MyBatis Plus中,可以使用@FillInsert和@FillUpdate注解来自动填充公共参数。 @FillInsert:用于填充insert操作的公共参数,默认情况下,会将注解所在的字段自动添加到插入语句中。 @FillUpdate:用于填充update操作的公共参数,默认情况下,会将注解所在的字段自动添加到更新语句中。 示例代码如下:

    public class BaseEntity implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        /**
         * 搜索值
         */
        @JsonIgnore
        @TableField(exist = false)
        private String searchValue;
    
        /**
         * 创建者
         */
        @TableField(fill = FieldFill.INSERT)
        private String createBy;
    
        /**
         * 创建时间
         */
        @TableField(fill = FieldFill.INSERT)
        private Date createTime;
    
        /**
         * 更新者
         */
        @TableField(fill = FieldFill.INSERT_UPDATE)
        private String updateBy;
    
        /**
         * 更新时间
         */
        @TableField(fill = FieldFill.INSERT_UPDATE)
        private Date updateTime;
    
        /**
         * 请求参数
         */
        @JsonInclude(JsonInclude.Include.NON_EMPTY)
        @TableField(exist = false)
        private Map<String, Object> params = new HashMap<>();
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 添加配置
    import cn.hutool.core.util.ObjectUtil;
    import cn.hutool.http.HttpStatus;
    import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
    import com.ruoyi.common.core.domain.BaseEntity;
    import com.ruoyi.common.core.domain.model.LoginUser;
    import com.ruoyi.common.exception.ServiceException;
    import com.ruoyi.common.helper.LoginHelper;
    import com.ruoyi.common.utils.StringUtils;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.ibatis.reflection.MetaObject;
    
    import java.util.Date;
    
    /**
     * MP注入处理器
     *
     * @Author: water
     * @Date: 2023/11/15 8:51
     * @Version: 1.0.0
     */
    @Slf4j
    public class CreateAndUpdateMetaObjectHandler implements MetaObjectHandler {
    
        @Override
        public void insertFill(MetaObject metaObject) {
            try {
                if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseEntity) {
                    BaseEntity baseEntity = (BaseEntity) metaObject.getOriginalObject();
                    Date createTime = ObjectUtil.isNotNull(baseEntity.getCreateTime())
                            ? baseEntity.getCreateTime() : new Date();
                    Date updateTime = ObjectUtil.isNotNull(baseEntity.getUpdateTime())
                            ? baseEntity.getUpdateTime() : new Date();
                    // 解析了有数据填充的问题
                    baseEntity.setCreateTime(createTime);
                    baseEntity.setUpdateTime(updateTime);
                    String username = StringUtils.isNotBlank(baseEntity.getCreateBy())
                            ? baseEntity.getCreateBy() : getLoginUsername();
                    // 当前已登录 且 创建人为空 则填充
                    baseEntity.setCreateBy(username);
                    // 当前已登录 且 更新人为空 则填充
                    baseEntity.setUpdateBy(username);
                }
            } catch (Exception e) {
                throw new ServiceException("自动注入异常 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);
            }
        }
    
        @Override
        public void updateFill(MetaObject metaObject) {
            try {
                if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseEntity) {
                    BaseEntity baseEntity = (BaseEntity) metaObject.getOriginalObject();
                    Date current = new Date();
                    // 更新时间填充(不管为不为空)
                    baseEntity.setUpdateTime(current);
                    String username = getLoginUsername();
                    // 当前已登录 更新人填充(不管为不为空)
                    if (StringUtils.isNotBlank(username)) {
                        baseEntity.setUpdateBy(username);
                    }
                }
            } catch (Exception e) {
                throw new ServiceException("自动注入异常 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);
            }
        }
    
        /**
         * 获取登录用户名
         */
        private String getLoginUsername() {
            LoginUser loginUser;
            try {
                loginUser = LoginHelper.getLoginUser();
            } catch (Exception e) {
                log.warn("自动注入警告 => 用户未登录");
                return null;
            }
            return ObjectUtil.isNotNull(loginUser) ? loginUser.getUsername() : null;
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82

    3、参考

  • 相关阅读:
    学习黑马AJAX
    树莓派无需显示屏的VNC Viewer方式的远程连接
    如何在uniapp中实现二维码生成功能
    【python基础】random模块常用方法讲解
    uniapp 组件 和 API
    学习c#的第二天
    RK3399 Android7.1修改adb shell下$前的提示名称
    图片里的文字如何提取?试试这几种提取方法
    Python位运算符
    计算机视觉(CV)技术的优势和挑战
  • 原文地址:https://blog.csdn.net/sanduo112/article/details/134415055