Mapstruct: автоматическое увеличение переменной объекта в списке объектов
У меня есть несколько POJO, как это:
@Data
public class A {
List<B> bList;
}
@Data
public class B {
int id;
int x;
}
@Data
public class C {
List<D> dList;
}
@Data
public class D {
int x;
}
Теперь я хочу отобразить класс C на класс A, используя MapStruct, чтобы значение id в bList в классе A автоматически увеличивалось. Я использую Mapstruct 1.1.0.Final.
Для картирования List<D>
в List<B>
Я могу определить маппер для class B
а также class D
и POJO будут автоматически отображаться, но я не смог найти способ сопоставления POJO с автоматическим приращением в поле.
Мой POJO очень большой. Есть ли способ в Map Struct для автоинкрементных переменных в списке?
1 ответ
У вас есть 2 варианта сделать это с 1.1.0.Final и еще один вариант с 1.2.0.Beta2.
Первый вариант при картировании D
в B
Ты можешь использовать @AfterMapping
между D
а также B
и использовать ThreadLocal
там.
public class AutoIncrementorThreadLocal {
@AfterMapping
public /*static*/ void autoIncrementId(D source, @MappingTarget B target) {
//here you use the ThreadLocal and do something like getAndIncrement
}
}
В вашем картографе вы должны будете сказать, что вы используете AutoIncrementorThreadLocal
, Также метод может быть статическим, MapStruct также может вызывать статические методы.
Второй вариант при картировании C
в A
public class AutoIncrementorBulk {
@AfterMapping
public /*static*/ void autoIncrementId(C source, @MappingTarget A target) {
//here you iterate the list and increment the ids
}
}
В вашем картографе вы должны будете сказать, что вы используете AutoIncrementorBulk
, Также метод может быть статическим, MapStruct также может вызывать статические методы.
Третий вариант с 1.2.0.Beta2
Вы можете использовать новый @Context
и имеют @AfterMapping
в теме.
public class AutoIncrementorContext {
private int counter = 0;
@AfterMapping
public void autoIncrementId(D source, @MappingTarget B target) {
//here you use your counter, because you are only using this instance during one mapping
}
}
Ваш картограф должен выглядеть так:
@Mapper
public interface MyMapper {
C map(A source, @Context AutoIncrementorContext context);
D map(B source, @Context AutoIncrementorContext context);
}
Когда вы собираетесь позвонить своему мапперу, вам нужно будет позвонить так:
myMapper.map(a, new AutoIncrementorContext());
Первый и третий подходы похожи с той лишь разницей, что вам не нужно использовать ThreadLocal
(s) с третьим подходом.