为映射项生成 ID
Generate ID for mapped item
在我们的项目中,习惯上所有映射都使用mapstruct。在这种独特的情况下,我不是在创建实体,而是在创建 DTO。但是这个 DTO 需要我生成一个 UUID,我宁愿不使用表达式选项。
@Mapping(target = "trackId", expression = "java(UUID.randomUUID().toString())")
FileUploadRequest inventoryToFileUpload(Inventory inventory);
我宁愿把编译器当成生活中的朋友。另外,如果生成策略不是 30 个字符宽度的一行,你会怎么做?
我的首选方法如下:
@Mapping(target = "trackId", qualifiedByName = "generateUUID"),
FileUploadRequest inventoryToFileUpload(Inventory inventory);
@Named("generateUUID")
default String generateUuid() {
return UUID.randomUUID().toString();
}
很遗憾,上面的方法不起作用。还得给个出处,废话。或者也许有一种方法可以指定我不依赖任何参数?
这是有效的代码:
// Ommiting other mappings for clarity
@Mapping(target = "trackId", source = "id", qualifiedByName = "generateUUID")
FileUploadRequest inventoryToFileUpload(Inventory inventory);
@Named("generateUUID")
default String generateUuid(final String nonsense) {
return UUID.randomUUID().toString();
}
这会生成以下代码行
fileUploadRequest.setTrackId(this.generateUuid(inventory.getId()));
但是...参数是多余的,很容易看出。我知道这 ACTUALLY 无关紧要。但这似乎是一个疏忽,或者我不明白如何声明我没有这方面的来源,我只是想让映射器调用我的方法。
再次强调,expression
不是有效答案,请勿提出。除非你能做到 expression = "java(generateUuid())"
?
MapStruct 是关于不同对象之间的映射。这就是为什么你不能使用空方法(没有 expression
)。
我的建议是确实使用 Mapping#expression
。但是,为了简化它,您可以使用类似的东西:
public class MappingUtils {
public static String GENERATE_UUID_EXPRESSION = "java(" + MappingUtils.class.getCanonicalName() + ".generateUuid())"
public static String generateUuid() {
return UUID.randomUUID().toString();
}
}
然后在您的映射器中您可以执行以下操作:
@Mapper
public interface MyMapper {
@Mapping(target = "trackId", expression = MappingUtils. GENERATE_UUID_EXPRESSION)
FileUploadRequest inventoryToFileUpload(Inventory inventory);
}
这样做,您在一个地方就有了表达式,并且您有一个执行生成的方法。
生成的代码将使用 MappingUtils
的完整限定名。如果您想避免这种情况,您需要将 MappingUtils
添加到 Mapper#imports
,然后在表达式中使用 MappingUtils.class.getName()
。
在我们的项目中,习惯上所有映射都使用mapstruct。在这种独特的情况下,我不是在创建实体,而是在创建 DTO。但是这个 DTO 需要我生成一个 UUID,我宁愿不使用表达式选项。
@Mapping(target = "trackId", expression = "java(UUID.randomUUID().toString())")
FileUploadRequest inventoryToFileUpload(Inventory inventory);
我宁愿把编译器当成生活中的朋友。另外,如果生成策略不是 30 个字符宽度的一行,你会怎么做?
我的首选方法如下:
@Mapping(target = "trackId", qualifiedByName = "generateUUID"),
FileUploadRequest inventoryToFileUpload(Inventory inventory);
@Named("generateUUID")
default String generateUuid() {
return UUID.randomUUID().toString();
}
很遗憾,上面的方法不起作用。还得给个出处,废话。或者也许有一种方法可以指定我不依赖任何参数?
这是有效的代码:
// Ommiting other mappings for clarity
@Mapping(target = "trackId", source = "id", qualifiedByName = "generateUUID")
FileUploadRequest inventoryToFileUpload(Inventory inventory);
@Named("generateUUID")
default String generateUuid(final String nonsense) {
return UUID.randomUUID().toString();
}
这会生成以下代码行
fileUploadRequest.setTrackId(this.generateUuid(inventory.getId()));
但是...参数是多余的,很容易看出。我知道这 ACTUALLY 无关紧要。但这似乎是一个疏忽,或者我不明白如何声明我没有这方面的来源,我只是想让映射器调用我的方法。
再次强调,expression
不是有效答案,请勿提出。除非你能做到 expression = "java(generateUuid())"
?
MapStruct 是关于不同对象之间的映射。这就是为什么你不能使用空方法(没有 expression
)。
我的建议是确实使用 Mapping#expression
。但是,为了简化它,您可以使用类似的东西:
public class MappingUtils {
public static String GENERATE_UUID_EXPRESSION = "java(" + MappingUtils.class.getCanonicalName() + ".generateUuid())"
public static String generateUuid() {
return UUID.randomUUID().toString();
}
}
然后在您的映射器中您可以执行以下操作:
@Mapper
public interface MyMapper {
@Mapping(target = "trackId", expression = MappingUtils. GENERATE_UUID_EXPRESSION)
FileUploadRequest inventoryToFileUpload(Inventory inventory);
}
这样做,您在一个地方就有了表达式,并且您有一个执行生成的方法。
生成的代码将使用 MappingUtils
的完整限定名。如果您想避免这种情况,您需要将 MappingUtils
添加到 Mapper#imports
,然后在表达式中使用 MappingUtils.class.getName()
。