在JavaDTO类上使用数据注释

在JavaDTO类上使用数据注释,java,spring,spring-boot,dto,lombok,Java,Spring,Spring Boot,Dto,Lombok,我对使用DTO类的数据注释感到困惑。这是我的示例类 @Data public class MyClass { private Long id; private String name; } 我在网上读到,专门在DTO类上使用数据注释将允许使用生成的setter更改字段的值 我应该删除lombok数据注释吗?并手动实现getter和setter 谢谢:)注释来自Lombok项目,该项目旨在通过注释使用反射。此注释确保生成所有setter、getter和具有所有必需参数的构造函数,并重

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

@Data
public class MyClass {
   private Long id;
   private String name;
}
我在网上读到,专门在DTO类上使用数据注释将允许使用生成的setter更改字段的值

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

谢谢:)

注释来自Lombok项目,该项目旨在通过注释使用反射。此注释确保生成所有setter、getter和具有所有必需参数的构造函数,并重写
Object::toString
Object::equals
Object::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
注释,也可以手动编写注释。

注释来自Lombok项目,该项目旨在通过注释使用反射。此注释确保生成所有setter、getter和具有所有必需参数的构造函数,并重写
Object::toString
Object::equals
Object::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
注释,也可以手动编写注释。

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

比如说

@Data
class User{

private String userName;

private String pwd;
}
这个类,将有所有的setter和getter。当您转换到web时,您将看到

{userName: "123", pwd: "xxx"}
这太可怕了。 但是如果你使用DTO

class User{

private String userName;

private String pwd;

public String getUserName(){
    return userName;
}
}
他们只看到

{userName: "123"}

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

比如说

@Data
class User{

private String userName;

private String pwd;
}
这个类,将有所有的setter和getter。当您转换到web时,您将看到

{userName: "123", pwd: "xxx"}
这太可怕了。 但是如果你使用DTO

class User{

private String userName;

private String pwd;

public String getUserName(){
    return userName;
}
}
他们只看到

{userName: "123"}

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

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

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

@数据
公共类MyClass{
@Setter(AccessLevel.NONE)
私人长id;
私有字符串名称;
}

这将为id生成一个getter但不生成setter,为名称生成一个getter和setter。

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

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

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

@数据
公共类MyClass{
@Setter(AccessLevel.NONE)
私人长id;
私有字符串名称;
}

这将为id生成一个getter而不是setter,为名称生成一个getter和setter。

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


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

我会避免@Data For DTO,因为它有太多陷阱。首先,正如您所提到的,它是可变的,这对于DTO来说并不是您真正想要的。尽管它是可变的,我