成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

MapStruct教程-三種方式處理繼承關系

開發 前端
MapStruct是一個效率工具,可以在處理Java Bean映射時,幫助我們盡量減少樣板代碼,只需要定義接口,它會自動生成映射邏輯。本文中,我們一起看下如何通過MapStruct處理集成關系。

你好,我是看山。

MapStruct是一個效率工具,可以在處理Java Bean映射時,幫助我們盡量減少樣板代碼,只需要定義接口,它會自動生成映射邏輯。本文中,我們一起看下如何通過MapStruct處理集成關系。

我們將討論三種方法:

  1. 通過實例檢查;
  2. 使用訪問者模式;
  3. 【推薦】使用@SubclassMapping注解。

一、背景

默認情況下,MapStruct無法為所有從基類或接口繼承的類生成映射器,不支持運行時識別實例和對象層次結構。

(一)基礎定義

先定義POJO類:

public abstract class Vehicle {
    private String color;
    private String speed;
}

public class Car extends Vehicle{
    private Integer tires;
}

public class Bus extends Vehicle {
    private Integer capacity;
}

再定義對應的DTO類:

public class VehicleDTO {
    private String color;
    private String speed;
}

public class CarDTO extends VehicleDTO{
    private Integer tires;
}

public class BusDTO extends VehicleDTO{
    private Integer capacity;
}

(二)定義映射器

這里我們定義三個映射器:CarMapper、BusMapper、VehicleMapper:

@Mapper
public interface CarMapper {
    CarDTO carToDTO(Car car);
}

@Mapper
public interface BusMapper {
    BusDTO busToDTO(Bus bus);
}

@Mapper(uses = {BusMapper.class, CarMapper.class})
public interface VehicleMapper {
    VehicleDTO vehicleToDTO(Vehicle vehicle);
}

在這里,我們分別定義了所有子類的映射器,并在基類映射器通過uses配置使用它們。

(三)識別問題

我們先看下VehicleMapper的生成類:

public class VehicleMapperImpl implements VehicleMapper {

    @Override
    public VehicleDTO vehicleToDTO(Vehicle vehicle) {
        if ( vehicle == null ) {
            return null;
        }

        VehicleDTO vehicleDTO = new VehicleDTO();

        vehicleDTO.setColor( vehicle.getColor() );
        vehicleDTO.setSpeed( vehicle.getSpeed() );

        return vehicleDTO;
    }
}

可以看到,代碼中是直接使用了VehicleDTO,并沒有用到子類的任何定義。我們可以在入口傳入Car或Bus的實例對象,但是最終得到的只能是VehicleDTO的實例。

二、通過實例檢查實現

我們一起看看如何通過實例檢查實現映射邏輯,因為比較簡單,直接代碼:

@Mapper
public interface VehicleMapperByInstanceChecks {
    CarDTO map(Car car);

    BusDTO map(Bus bus);

    default VehicleDTO mapToVehicleDTO(Vehicle vehicle) {
        if (vehicle instanceof Bus) {
            return map((Bus) vehicle);
        } else if (vehicle instanceof Car) {
            return map((Car) vehicle);
        } else {
            return null;
        }
    }
}

從上面代碼來說,其實完全是靠人工智能實現的,通過我們HardCode,借助instanceof實現類型判斷,轉換為需要的類型實例。

三、通過訪問者模式實現

第二種方式是借助訪問者模式實現,通過Java的多態,可以精準的調用到需要的方法。

(一)應用訪問者模式

首先在抽象類Vehicle中定義抽象方法accept(),以接受任何訪問者對象:

public abstract class Vehicle {
    public abstract VehicleDTO accept(Visitor visitor);
}

public interface Visitor {
    VehicleDTO visit(Car car);

    VehicleDTO visit(Bus bus);
}

現在,我們需要為每個Vehicle子類實現accept()方法:

public class Bus extends Vehicle {
    @Override
    VehicleDTO accept(Visitor visitor) {
        return visitor.visit(this);
    }
}

public class Car extends Vehicle {
    @Override
    VehicleDTO accept(Visitor visitor) {
        return visitor.visit(this);
    }
}

最后,我們可以通過實現訪問者接口來實現映射器:

@Mapper
public abstract class VehicleMapperByVisitorPattern implements Visitor {
    public VehicleDTO mapToVehicleDTO(Vehicle vehicle) {
        return vehicle.accept(this);
    }

    @Override
    public VehicleDTO visit(Car car) {
        return map(car);
    }

    @Override
    public VehicleDTO visit(Bus bus) {
        return map(bus);
    }

    abstract CarDTO map(Car car);

    abstract BusDTO map(Bus bus);
}

從性能來說,訪問者模式方法比實例檢查方法更優化,借助Java的多態實現,快速定位轉換方法。從代碼量來說,實例檢查會由于訪問者模式,因為寫的少。

其實這里會引出一個問題,設計模式是好是壞?

四、使用@SubclassMapping實現

MapStruct提供了@SubclassMapping注解,允許我們配置的映射器,可以處理有繼承關系的類實例轉換。

@SubclassMapping注解中有source和target兩個配置,source定義要映射的源子類,target定義要映射到的目標子類:

(一)定義

我們使用@SubclassMapping注解指定繼承對應關系:

@Mapper(uses = {BusMapper.class, CarMapper.class})
public interface VehicleMapperBySubclassMapping {
    @SubclassMapping(source = Car.class, target = CarDTO.class)
    @SubclassMapping(source = Bus.class, target = BusDTO.class)
    VehicleDTO mapToVehicleDTO(Vehicle vehicle);
}

生成的映射代碼為:

public class VehicleMapperBySubclassMappingImpl implements VehicleMapperBySubclassMapping {

    private final BusMapper busMapper = Mappers.getMapper( BusMapper.class );
    private final CarMapper carMapper = Mappers.getMapper( CarMapper.class );

    @Override
    public VehicleDTO mapToVehicleDTO(Vehicle vehicle) {
        if ( vehicle == null ) {
            return null;
        }

        if (vehicle instanceof Car) {
            return carMapper.carToDTO( (Car) vehicle );
        }
        else if (vehicle instanceof Bus) {
            return busMapper.busToDTO( (Bus) vehicle );
        }
        else {
            VehicleDTO vehicleDTO = new VehicleDTO();

            vehicleDTO.setColor( vehicle.getColor() );
            vehicleDTO.setSpeed( vehicle.getSpeed() );

            return vehicleDTO;
        }
    }
}

可以看到,MapStruct自動實現了實例檢查,通過instanceof判斷類型。

責任編輯:武曉燕 來源: 看山的小屋
相關推薦

2009-09-25 14:12:16

Hibernate繼承

2020-11-01 17:10:46

異步事件開發前端

2025-01-24 00:00:00

MapStruct子類型Mapper

2012-07-17 09:16:16

SpringSSH

2024-07-08 09:03:31

2025-01-13 00:00:00

MapStruct枚舉映射

2010-03-12 17:52:35

Python輸入方式

2010-06-13 16:04:14

MySQL三種安裝方式

2011-04-08 11:13:50

CISCO IOS令牌桶雙桶

2021-11-05 21:33:28

Redis數據高并發

2014-07-30 17:10:38

LVS集群負載均衡

2009-07-03 18:32:18

JSP頁面跳轉

2019-11-20 18:52:24

物聯網智能照明智能恒溫器

2014-12-31 17:42:47

LBSAndroid地圖

2021-06-24 08:52:19

單點登錄代碼前端

2025-01-16 00:00:00

MapStruct映射

2013-06-17 17:08:47

Windows PhoWP開發共享數據方式

2010-02-03 15:46:15

C++函數傳遞

2010-03-01 15:21:57

WCF死鎖

2011-06-03 11:53:06

Spring接口
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲免费人成在线视频观看 | 精品日本久久久久久久久久 | 欧美一区二区三区在线看 | 精品国产乱码久久久久久88av | 日韩三 | 亚洲国产中文在线 | 欧美片网站免费 | 国产欧美一区二区三区久久 | 久热爱 | 欧美成ee人免费视频 | 偷拍第一页 | 在线观看日本高清二区 | 亚洲一区 中文字幕 | 国产jizz女人多喷水99 | 亚洲欧美在线观看 | 久久91精品国产一区二区 | 国产高清视频在线观看 | 日韩av在线中文字幕 | 性精品| 成人国产精品一级毛片视频毛片 | 精品国产久 | av一区在线观看 | 久久一区二区精品 | 欧美一区二区大片 | 欧美成人自拍视频 | 国产精品一区二区不卡 | 精品在线观看一区二区 | 久草久 | 日韩在线一区二区 | 精品一二区| 福利网址| 欧美日韩视频 | 黄网址在线观看 | 久久久精品天堂 | 久久无毛 | 国内精品视频在线 | 亚洲不卡在线观看 | 四虎在线观看 | 国产 日韩 欧美 在线 | 亚洲久视频| 欧美性乱|