我有以下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 }}是特定于构建器的东西,而不会暴露在主类本身上。
答案 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");