- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我的项目中有以下 bean 结构。
public class Account{
// properties
// setters
// getters
}
public class AccountType1 extends Acccount{
// properties
// setters
// getters
}
public class AccountType3 extends Acccount{
// properties
// setters
// getters
}
public class CustomerProfile {
Customer customer;
List<Account> accounts;
List<Service> services;
}
我的客户和服务结构类似。一个父级和多个实现。我的应用程序是一个中间件应用程序。我不知道我们的应用程序从其他 Web 服务调用中获取什么样的运行时对象(Bean 模型在应用程序中是相同的)。列表可以包含任何实现。它可以是Account、AccountType1 或AccountType2。服务也是如此。父级将有公共(public)字段,每个实现将有特定字段。我们将为每个新客户(即消费者)提供新的流程。 field 要求也不同。因此我们需要有单独的 CustomerProfile 以及相应的 Account 和 Service 映射器。现在对于 client1,他们可能需要通用 Account 或 AccountType1 或 AccountType2 或 AccountTypeN 或全部。因此,代码应该是通用的,就像我在配置中提供 {AccountType1.class, AccounTypeN.class} 的任何类型的类一样,它应该仅从列表中映射这些对象。由于 AccountType1 扩展了 Account,因此它还应该处理父类字段。我目前正在按照以下方式执行此操作。
@Mapper(config = GlobalConfig.class)
public interface CustomerProfileMapper{
@Mappings({
@Mapping( target = "customer", source = "customer"),
@Mapping( target = "accounts", source = "accounts"),
@Mapping( target = "services", source = "services")
})
CustomerProfile mapCustomerProfile(CustomerProfile customerProfile);
@IterableMapping(qualifiedByName = "mapAccount")
List<Account> mapAccounts(List<Account> accounts);
@Named("mapAccount")
default Account mapAccount (Account account){
if(account instanceof AccountType1){
mapAccountType1((AccountType1)account);
}
else if(account instanceof AccountType2){
mapAccountType2((AccountType2)account);
}
else {
mapBaseAccount(account);
}
}
@Mappings{...}
AccountType1 mapAccountType1(AccountType1 account);
@Mappings{...}
AccountType2 mapAccountType2(AccountType2 account);
}
@Mappings{...}
Account mapBaseAccount(Account account);
}
但是此代码将是多余的,因为我必须为不同的 CustomerProfileMappers 的每个流程编写。我希望代码是通用的并且可以用作配置。可重用性是这里关注的问题。如何解决这个问题呢?基本上我想做如下的事情。
@IterableMapping( mappingClasses= {AccountType1.class, AccountType2.class, Account.class})
List<Account> mapAccounts(List<Account> accounts);
@Mappings{...}
AccountType1 mapAccountType1(AccountType1 account);
@Mappings{...}
AccountType2 mapAccountType2(AccountType2 account);
}
@Mappings{...}
Account mapBaseAccount(Account account);
因此,mapStruct 应该生成类似于我当前处理方式的代码。它应该生成映射方法来处理mappingClasses 属性中定义的所有指定类。它还应该在映射器中查找各个类特定的映射方法。如果找到,则调用它们,否则生成映射方法。这是必需的,因为我与客户和服务有类似的事情。我不想在映射器中包含太多手写代码,并且每个流程都有数十个不同的 CustomerProfileMappers。而且随着每个版本的发布,它们都在不断增加。我已经阅读了 MapStruct 的完整技术文档。但我找不到办法做到这一点。或者这可能是一个新的 FR?
最佳答案
您可以尝试将帐户的开关外部化。
@Mapper(config = GlobalConfig.class)
public interface CustomerProfileMapper{
@Mappings({
@Mapping( target = "customer", source = "customer"),
@Mapping( target = "accounts", source = "accounts"),
@Mapping( target = "services", source = "services")
})
CustomerProfile mapCustomerProfile(CustomerProfile customerProfile, @Context MyMappingContext ctx);
@Mappings{...}
AccountType1 mapAccountType1(AccountType1 account);
@Mappings{...}
AccountType2 mapAccountType2(AccountType2 account);
}
@Mappings{...}
Account mapBaseAccount(Account account);
}
public class MyMappingContext {
// or whatever component model you prefer
CustomerProfileMapper mapper = CustomerProfileMapper.INSTANCE;
@AfterMaping
public void mapAccount (CustomerProfile source, @MappingTarget CustomerProfile target){
for ( Account account : source.getAccounts() ){
if(account instanceof AccountType1){
mapper.mapAccountType1((AccountType1)account);
}
else if(account instanceof AccountType2){
mapper.mapAccountType2((AccountType2)account);
}
else {
mapper.mapBaseAccount(account);
}
}
}
}
您甚至可以从该上下文回调映射器。如果您愿意,可以将映射器本身的通用行为表示为通用映射器。因此,在 CommonCustomerProfileMapper 中定义签名,并让 CustomerProfileMapper1 继承该签名并定义映射。
关于 MapStruct 中的一项新功能:就像所说的:我不确定对此类功能有多少共同兴趣,但您始终可以发出功能请求。
关于java - 当泛型类型具有继承结构时,如何在 Mapstruct 中映射集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53050641/
我可以在我们有 String 到 Enum 映射的地方找到答案,但我找不到如何将 Enum 映射到 String。 public class Result { Value enumValue; }
我想使用 MapStruct 映射一个没有源对象的 Target 对象。我试过了,但出现以下错误。 Can't generate mapping method with no input argume
我在单独的文件中有这 3 个类 public class Book { @Id @GeneratedValue private Long id; @NonNull
如何使用 MapStruct 对于以下场景进行 bean 映射。 class Source { private String sourceId; private List courses; //al
是否可以在针对目标 bean 中字符串类型的 bean 属性设置字符串值之前对其进行修剪? 例如,Dozer 通过其映射配置提供了这样的功能, true 另见 Dozer Global C
我收到编译错误: com/mycompany/hibernate5/Main.java:[10,46] cannot find symbol symbol: class Customer_
目前我们在项目中使用 ModelMapper。但是,在该站点中,我看到很多人喜欢 MapStruct。 不确定差异以及我们是否需要真正进行升级。 ModelMapper 和 MapStruct 有什么
我正在使用 map 结构用于在我的 中将 Dto 映射到实体,反之亦然 Spring Boot 应用。 I want to know that, is there a way that i can m
如何在 MapStruct 中完全禁用“构建器”?我根本不想使用它们,因为它们给我带来了各种各样的问题。 我在 META-INF 下创建了服务文件(我更喜欢一种将它分配给映射构建器 = 的方法,但我没
@Mapper @Mapper 将接口或抽象类标记为映射器,并自动生成映射实现类代码。 public @interface Mapper { // 引入其他其他映射器 Class&
我在其他地方看到过这个问题,但不是在相同的上下文中,也没有适合我们用例的答案。 假设我在源对象中有一个列表字段: List mySourceList; 和相应的目标字段: List myTargetL
我在 MapStruct 中使用 spring data jdbc。 POJO 与具有所有“仅限内部”数据(如代理键、审计信息等)的表结构保持一致,而域对象是分层的并且仅包含业务相关数据。我必须在特定
页面信息 public class PageInfoDto implements Serializable { private int currentPageNum; private
在 MapStruct 版本 1.1.0.Final 中,这是可能的.... @Mappings({ @Mapping(target = "transaction.process.detail
我有一个 list List我想映射到另一个列表 List .这些类型如下所示: public class Payment { @XmlElement(name = "Installment"
我要单例Mapper两者兼而有之 create和 update方法。 create 方法生成的代码很好,但是在更新的情况下,我想在目标中设置属性,前提是它们在源中不为空。 我该怎么做 mapStruc
我想使用 mapstruct 在这些对象之间进行映射: MyObj1 -List myObj2List --List myObj3List ---string field1 MyObj4 -List
如何映射以下内容: class Source { String name; List others; } class Other { String otherName; Lis
我想映射以下类 class Schedule { ZoneId timezoneId; List rules; } class AvailabilityRule { long
我是 MapStruct API 的新手,谁能说一下如何进行嵌套映射。 我有两个类,一个是我实际的purchaseOrder 类,它是我的目标类,另一个是EDPurchaseOrder 类,它被称为源
我是一名优秀的程序员,十分优秀!