【问题标题】:Using Data annotation on Java DTO class在 Java DTO 类上使用数据注释
【发布时间】:2018-08-13 10:23:19
【问题描述】:

我在对 DTO 类使用数据注释时感到困惑。这是我的示例类。

@Data
public class MyClass {
   private Long id;
   private String name;
}

我在网上看到,专门在 DTO 类上使用 Data annotation 将允许通过使用生成的 setter 来更改字段的值。

我应该删除 lombok Data 注释吗?并手动实现 getter 和 setter。

谢谢:)

【问题讨论】:

  • 你在说哪个@Data?是龙目岛的吗?
  • setter 应该更新字段的内容。您必须决定是否希望该类的实例是不可变的。 如何 setter 进入你的班级并不重要,唯一的问题是:应该有 setter 吗?这是一个只有才能决定如何去做的要求。

标签: java spring spring-boot dto lombok


【解决方案1】:

注解@Data 来自Project Lombok,该项目主要通过注解使用反射。此注解确保生成所有 setter、getter、具有所有必需参数的构造函数并覆盖 Object::toStringObject::equalsObject::hashCode 方法。

简单地说,这个注解“完成”了一个简单的 POJO 对象,并在不需要使用 IDE 的情况下生成所有样板。

他们将注释命名为@Data,因为他们支持将理解对象仅作为数据容器的想法。


据我所知,这一代只发生在缺少的 getter/setter 上(为了简洁起见,让我们谈谈它们)。如您所知,生成的 getter/setter 是纯形式:

public int getId() { return this.id; }

public void setId(int id) { this.id = id; }

您可以使用更详细的 setter/getter 执行验证或任何类似的方法来覆盖生成的。您既可以使用@Data 注释,也可以手动编写。

【讨论】:

  • 谢谢@Nikolas。我应该删除它并实现 getter 和 setter 吗?这样它将防止使用生成的设置器更改字段的值。
  • 它们不会被改变。生成的 setter 只是补全缺失的。
【解决方案2】:

我会避免 @Data 用于 DTO,因为它有太多陷阱。首先,正如您所提到的,它是可变的,您并不真正想要 DTO。尽管它是可变的,但它实现了 equals() 和 hashCode() 只是自找麻烦。

您可以将@Value 用于不可变的 DTO。对于传入的 DTO,您可能需要将 lombok.anyConstructor.addConstructorProperties 添加到您的 lombok.config,这将允许像 jackson 这样的库在没有默认构造函数的情况下反序列化到您的 POJO。

【讨论】:

    【解决方案3】:

    DTO是用来传递数据信息的,有些信息实际上是我们不希望用户能够更改或者访问的,比如用户密码,我们不想在用户可以看到的时候传递给前端加密的密码,或者我们不希望用户在更改信息的同时修改密码,而在这个序列化过程中起作用的是setter和getter,以及为所有字段自动生成getter和setter的数据注释。

    例如

    @Data
    class User{
    
    private String userName;
    
    private String pwd;
    }
    

    这个类,将有所有的 setter 和 getter。当您转入网络时,您会看到

    {userName: "123", pwd: "xxx"}
    

    这太可怕了。 但是如果你使用 DTO

    class User{
    
    private String userName;
    
    private String pwd;
    
    public String getUserName(){
        return userName;
    }
    }
    

    他们只看到

    {userName: "123"}
    

    【讨论】:

      【解决方案4】:

      默认情况下,@Data lombok 注解将为类中的所有字段生成 setter 和 getter。

      如果您想要一个不可变的数据传输对象,请将其注释为 @Value

      如果您希望在 MyClass 类型中混合一些不可变值和一些可变值,例如,您可能希望 id 字段不可变而其余字段可变,则可以在该字段上使用 @Setter 注释你想要是不可变的,指定AccessLevelNONE。例如:

      @Data
      public class MyClass {
         @Setter(AccessLevel.NONE)
         private Long id;
         private String name;
      }
      

      这将为 id 生成一个 getter 但不生成 setter,并为 name 生成一个 getter 和 setter。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-18
        相关资源
        最近更新 更多