如何使用lombok @Builder存储不同的值?

时间:2019-06-22 14:22:48

标签: java lombok

我有以下JPA实体

@Data
@Builder
public class Post {
  @Id
  @GeneratedValue
  UUID id;

  @OneToMany
  Set<PostTags> tags;

  String content;
}

@Data
public class PostTag {
  @Id
  @GeneratedValue
  UUID id;

  @OneToOne
  Post post;

  String tag;
}

使用lombok @Builder我希望能够执行以下操作

Post post = Post.builder()
  .tags("hello", "world")
  .content("Hello world")
  .build();

我想我需要一个自定义构建器

public static class PostBuilder {
  private Set<String> myTags = new HashSet<>();
  public PostBuilder tags(String... tags) {
    myTags.addAll(Arrays.asList(tags));
    return this;
  }
}

documentation上出现了我可以使用的ObtainVia注解,但是我不确定如何解决它(文档上没有示例),尤其是因为我只想要{{1 }}是特定于构建器的东西,而不会暴露在主类本身上。

2 个答案:

答案 0 :(得分:0)

ObtainVia仅适用于toBuilder,因此在这种情况下无济于事。

我建议采用以下方法。

首先,在PostTag中添加工厂方法,例如createTag(String)。此方法仅在其创建的实例中设置tag,并保留其他所有null。将其静态导入到您要使用PostBuilder的类中。

接下来,在@Singular上使用tags。然后您可以编写:

Post post = Post.builder()
   .tag(createTag("hello"))
   .tag(createTag("world"))
   .content("Hello world")
   .build();

最后,自定义build()方法,以便它首先创建Post实例(就像未自定义的build()方法一样),然后将此新创建的Post实例设置为在所有post实例中为PostTag。 看一下delombok编码,以确保自定义构建器时使用正确的构建器类和方法标头。

答案 1 :(得分:0)

您可以使用@Accessors来满足您的要求:

发布

@Data
@Accessors(chain = true)
public class Post {
    @Id
    @GeneratedValue
    private UUID id;

    @OneToMany
    private Set<PostTags> tags;

    private String content;

    public Post tags(String... tags) {
        Arrays.stream(tags)
                .map(tag -> PostTags.builder().tag(tag).build())
                .forEach(this.tags::add);
        return this;
    }
}

PostTags

@Data
@Builder
public class PostTags {
    @Id
    @GeneratedValue
    private UUID id;
    @OneToOne
    private Post post;
    private String tag;
}

使用@Accessors(chain = true)时,设置器将返回this引用而不是void,然后您的代码将以这种方式进行操作:

Post post = new Post().setId(id).tags("aaa", "bbb");

如果您希望代码与builder更相似,则将fluent的值添加到注释中:@Accessors(chain = true, fluent = true)

它将从设置器中删除set<Something>,仅使用字段名称,然后您的代码将如下所示:

Post post = new Post().id(id).content("hello").tags("aaa", "bbb");