代码之家  ›  专栏  ›  技术社区  ›  user3832429

MapStruct反向链接映射是否可行?

  •  3
  • user3832429  · 技术社区  · 7 年前

    我是MapStruct的新手,在谷歌上找不到问题的答案。 我有一个ShoppingCart,它有样本(以及其他属性),每个样本都需要一个对我的ShoppingCart的引用。可以用MapStruct进行这样的映射吗? 没有MapStruct,我只需将对ShoppingCart的引用传递给示例。这是手写的:

    protected ShoppingCart map(Cart cart, DataShareOption dataShareOption) {
    //(other stuff)
       for (CartSample cartSample : cart.getCartSamples()) {
           ShoppingCartSample sample = mapCartSample(cartSample, shoppingCart,
           dataShareOption);
           shoppingCart.getSamples().add(sample);
       }
    }
    
    protected ShoppingCartSample mapCartSample(CartSample cartSample,
        ShoppingCart shoppingCart, DataShareOption dataShareOption) {
    
         ShoppingCartSample sample = new ShoppingCartSample();
         sample.setShoppingCart(shoppingCart);
         //(other stuff)
         return sample;
    }
    
    // the classes declarations:
    // business class
    public class ShoppingCart extends ShoppingCartHeader
    {
        private List<ShoppingCartSample> samples = new   ArrayList<ShoppingCartSample>();
    //rest of the class
    
    
    // data base class:
    @Entity
    @Table(name = "cart")
    public class Cart extends BaseEntity
    {
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "cart")
    private Set<CartSample> cartSamples = new HashSet<CartSample>();
       // more stuff here
    
    
    // business class:
      public class ShoppingCartSample
      {
       private ShoppingCart shoppingCart;
      // rest of the class
    
    
    // data base class:
    @Entity
    @Table(name = "cart_sample")
    public class CartSample
    {
       @ManyToOne()
       @JoinColumn(name = "cart_id")
       private Cart cart;
       // more stuff here
    
    3 回复  |  直到 7 年前
        1
  •  3
  •   Tomer Gal    6 年前

    您可以使用 @AfterMapping 注释如下:

    @Mapper
    public interface ShoppingCartMapper{
        ShoppingCart map(Cart cart);
        ShoppingCartSample map(CartSample cartSample);
    
        @AfterMapping
        default void setShoppingCartSampleParent(@MappingTarget ShoppingCart cart){
            for(ShoppingCartSample cartSample : cart.getSamples()){
                cartSample.setShoppingCart(cart);
            }
        }
    }
    
        2
  •  0
  •   Bertrand Cedric    7 年前

    您可以使用 decorator 并使用toher类设置链接,通过mapstruct自动调用

    您的映射器

    @Mapper
    @DecoratedWith(MyMapperDecorator.class)
    public interface MyMapper {
        ShoppingCart map(Cart cart);
        ShoppingCartSample map(CartSample cart);
    }
    

    public abstract class MyMapperDecorator implements MyMapper {
        private final MyMapper delegate;
    
        public ParticulierMapperDecorator(MyMapper delegate) {
            this.delegate = delegate;
        }
    
        public ShoppingCart map(Cart cart){
            ShoppingCart shoppingCart = delegate.map(cart);//map the two objects
            //Set your link
            for(ShoppingCartSample sample: hoppingCart.getSampes()){
                sample.setShoppingCart(shoppingCart)
            }
        }
    }
    
        3
  •  0
  •   Filip    7 年前

    看一看 mapstruct-mapping-with-cycles @Context 映射周期(这是您拥有的)。

    这里的代码也是:

    public class CycleAvoidingMappingContext {
        private Map<Object, Object> knownInstances = new IdentityHashMap<Object, Object>();
        @BeforeMapping
        public <T> T getMappedInstance(Object source, @TargetType Class<T> targetType) {
            return (T) knownInstances.get( source );
        }
        @BeforeMapping
        public void storeMappedInstance(Object source, @MappingTarget Object target) {
            knownInstances.put( source, target );
        }
    }
    

    请记住 source target CycleAvoidingMappingContext Object .

    映射器看起来像:

    @Mapper
    public interface MyMapper {
        ShoppingCart map(Cart cart, @Context CycleAvoidingMappingContext context);
        ShoppingCartSample map(CartSample cart, @Context CycleAvoidingMappingContext context);
    }