MapStructの使用方法

この記事では紹介します

MapStructは、複数のDO(ビジネスエンティティオブジェクト)オブジェクトをDTO(データ転送オブジェクト)に変換するなど、特定のタイプのオブジェクトを別のタイプにマップできます。
MapStructに加えて、以前はset / get、BeanUtilsも使用しましたが、もちろん他のメソッドもあります。以下でそれらの長所と短所について説明します。まず、MapStructの基本的な使用法を紹介します。

基本的な使用法

StudentとStudentDTOの変換

  1. 学生オブジェクトをstudentdtoオブジェクトに変換します
  2. 学生コレクションをstudentdtoコレクションに変換する

モデルモデル
学生

@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="Student对象", description="")
public class Student extends Model<Student> {
    
    

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "id")
      @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    @ApiModelProperty(value = "学号")
    private String stuId;

    @ApiModelProperty(value = "名字")
    private String name;

    @ApiModelProperty(value = "性别 0 男,1 女")
    private Integer sex;

    @ApiModelProperty(value = "手机号")
    private String phone;

    @ApiModelProperty(value = "个人简介")
    private String info;

    @ApiModelProperty(value = "头像,picture表id")
    private Long picture;

    @ApiModelProperty(value = "班级")
    private String className;

    @ApiModelProperty(value = "专业")
    private String major;

    @ApiModelProperty(value = "所在小组")
    private Long gId;

}

Studentdtoオブジェクト

@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "学生DTO对象", description = "返回某一个学生最基本的信息")
public class StudentDTO {
    
    


    @ApiModelProperty(value = "id")
    private Long id;

    @ApiModelProperty(value = "名字")
    private String name;

    @ApiModelProperty(value = "性别 0 男,1 女")
    private Integer sex;

    @ApiModelProperty(value = "班级")
    private String className;

    @ApiModelProperty(value = "学号")
    private Long stuId;

    @ApiModelProperty(value = "手机号")
    private String phone;
}

マニュアル

1.依存関係を導入する

        <!--Java 实体映射工具 —— mapStruct依赖-->
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${
    
    mapstruct.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>${
    
    mapstruct.version}</version>
        </dependency>

2.オブジェクト変換インターフェースの作成
は、通常、サーバー層で行われます。
ここに画像の説明を挿入します

package com.marchsoft.group.manager.system.service.mapstruct;
/**
 * @Mapper 定义这是一个MapStruct对象属性转换接口,在这个类里面规定转换规则
 *          在项目构建时,会自动生成改接口的实现类,这个实现类将实现对象属性值复制。  注解详解看下方。
 */
@Mapper
public interface StudentMapStruct {
    
    


    /**
     * 获取该类自动生成的实现类的实例
     * 接口中的属性都是 public static final 的 方法都是public abstract的
     */
    StudentMapStruct INSTANCES = Mappers.getMapper(StudentMapStruct.class);

   //转换对象
    StudentDTO toStudentDTO(Student student);
    //转换集合
    List<StudentDTO> toListStudentDTO(List<Student> student);
}

3.最初の使用

 		 //设置每页的容量为5,这里是一个分页查询。
        Integer pageCount=2;
        Page<Student> page = new Page<>(pageCurrent,pageCount);
        Page<Student> studentPage = studentMapper.selectPage(page, null);
		//获取数据库查询的对象
        List<Student> students = studentPage.getRecords();
        //转换成DTO集合
        List<StudentDTO> studentsDTO = StudentMapStruct.INSTANCES.toListStudentDTO(students);
        System.out.println(students);
        System.out.println(studentsDTO);

4.結果

StudentDTO(id=1, name=张三, sex=0, className=4561, stuId=2004, phone=19907865257)

[StudentDTO(id=3, name=花花, sex=1, className=546, stuId=2045614106, phone=1990245212), StudentDTO(id=4, name=花花, sex=1, className=动科181, stuId=2078788107, phone=199885454512)]

ソースコード分析

StudentMapStructインターフェースを作成して実行すると、システムはデフォルトで実装クラスを生成します。最下層は、最も基本的なセット/取得を使用することです
ここに画像の説明を挿入します

高度な使用

MapStructによって提供されるいくつかのプロセッサオプション構成

MapStructは、@ Mapperアノテーションといくつかのプロパティ構成を提供します。

例:2つの一般的に使用されるcomponentModelunmappedTargetPolicy

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface StudentMapStruct {
    
    
}

1.componentModel = "XX" 4つの属性値

  • デフォルト:デフォルトでは、mapstructはコンポーネントタイプを使用せず、自動生成されたインスタンスオブジェクトはMappers.getMapper(Class)を介して取得できます。
  • cdi:生成されたマッパーはアプリケーションスコープのCDI Beanであり、@ Injectを介して取得できます。
  • Spring(頻繁に使用): @ Componentアノテーションは、生成された実装クラスに自動的に追加されます。これは、Springの@Autowiredメソッドを介して挿入できます。
  • jsr330: @ javax.inject.Namedおよび@Singletonアノテーションが、生成された実装クラスに追加されます。これは、 @ Injectアノテーションを介して取得できます。

2. unmappedTargetPolicy = ReportingPolicy.XX3つの属性値

使用していないターゲット・マッピング方法を埋めるためにソース属性値のケースを報告し、デフォルトのポリシーを適用します
ここに画像の説明を挿入します

-IGNOREは無視されます
-WARNビルド時に警告を発生させます
-ERRORマッピングコードの生成に失敗しました

その他のオプション構成
ここに画像の説明を挿入します

Springの依存関係を使用する

componentModel = "spring"を使用します。StudentMapStrctのインスタンスを作成する必要はありません。これは、@ Autowiredを介して直接使用できます。

接口中:

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface StudentMapStruct {
    
    
    StudentDTO toStudentDTO(Student student);
    List<StudentDTO> toListStudentDTO(List<Student> student);
   }

注入:
    @Autowired  
    StudentMapStruct studentMapStruct;

直接使用:
     StudentDTO studentDTO = studentMapStruct.toStudentDTO(student);
     List<StudentDTO> studentsDTO =studentMapStruct.toListStudentDTO(students);

一貫性のない属性名

  • 属性に一貫性がない場合は、@ Mappingを使用できます
@Mapping(source = "name", target = "stuName")

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface StudentMapStruct {
    
    
	@Mapping(source = "name", target = "stuName")
    StudentDTO toStudentDTO(Student student);
    @Mapping(source = "name", target = "stuName")
    List<StudentDTO> toListStudentDTO(List<Student> student);
   }

一貫性のない属性タイプ

タイプに一貫性がない場合、mapstructは自動変換を行うのに役立ちますが、自動変換タイプは制限されています

自動的に変換できるタイプ

  1. 基本的なタイプとそのパッケージ
  2. 梱包タイプの基本タイプと文字列タイプの間
  3. 文字列型と列挙型の間
  4. カスタム定数

エンティティモデル

@Data
public class UserTest {
    
    
   private String gender;
   private  Integer age;
}


@Data
public class UserTestDTO {
    
    
   private  boolean sex;
   private String age;
}

型変換クラス
は、後で使用する必要があるときに自動的に呼び出されるため、Beanコンテナに追加する必要があります。

@Component
public class BooleanStrFormat {
    
    
   public String toStr(Boolean gender) {
    
    
       if (gender) {
    
    
           return "男";
       } else {
    
    
           return "女";
       }
   }
   public Boolean toBoolean(String str) {
    
    
       if (str.equals("Y")) {
    
    
           return true;
       } else {
    
    
           return false;
       }
   }
}

マッピングインターフェイス
uses = {BooleanStrFormat.class})を使用して、自動的に呼び出される変換クラスを導入します

@Component
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE,uses={
    
    BooleanStrFormat.class})
public interface UserStruct {
    
    
    @Mappings({
    
    
            @Mapping(source = "gender",target = "sex"),
    })
    UserTestDTO toUserTestDTO(UserTest userTest);
}


テストクラス

    @Autowired
    UserStruct userStruct;
    @Test
    public void mapStructTest(){
    
    
        UserTest userTest = new UserTest();
        userTest.setGender("Y");
        userTest.setAge(18);
        UserTestDTO userTestDTO = userStruct.toUserTestDTO(userTest);
        System.out.println(userTestDTO);
    }

結果:

UserTestDTO(sex = true、age = 18)

複数のソースがターゲットをマップします

2つの異なるオブジェクトの値を同じオブジェクトに割り当てる場合があります。このとき、@ Mappingアノテーションを使用する必要があります。

@Mapper(componentModel = "spring")
public interface GoodInfoMapper {
    
    
    @Mappings({
    
    
            @Mapping(source = "type.name",target = "typeName"),
            @Mapping(source = "good.id",target = "goodId"),
            @Mapping(source = "good.title",target = "goodName"),
            @Mapping(source = "good.price",target = "goodPrice")
    })
    GoodInfoDTO fromGoodInfoDTO(GoodInfo good, GoodType type);
}

日付変換/固定値

  固定值:constant
    @Mapping(source = "name", constant = "hollis")
  日期转换:dateForma
    @Mapping(source = "person.begin",target="birth" dateFormat="yyyy-MM-dd HH:mm:ss")

パッケージの使用

すべてのオブジェクトのマッピングの基本的な使用を満たすために、構造体クラスをカプセル化できます

詳細な手順:

1.パブリック処理クラスBaseMapperを作成します

public interface BaseMapper<D, E> {
    
    

    /**
     * DTO转Entity
     * @param dto /
     * @return /
     */
    E toEntity(D dto);

    /**
     * Entity转DTO
     * @param entity /
     * @return /
     */
    D toDto(E entity);

    /**
     * DTO集合转Entity集合
     * @param dtoList /
     * @return /
     */
    List <E> toEntity(List<D> dtoList);

    /**
     * Entity集合转DTO集合
     * @param entityList /
     * @return /
     */
    List <D> toDto(List<E> entityList);
}

2.エンティティオブジェクトごとに構造体を作成し、BaseMapperを継承します

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface StudentMapStruct extends BaseMapper<StudentDTO,Student> {
    
    
}

3.使用する

        StudentDTO studentDTO = studentMapStruct.toDto(student);
        
        List<StudentDTO> studentsDTO =studentMapStruct.toDto(students);

4.結果

StudentDTO(id=1, name=张三, sex=0, className=4561, stuId=2004, phone=19907865257)

[StudentDTO(id=3, name=花花, sex=1, className=546, stuId=2045614106, phone=1990245212), StudentDTO(id=4, name=花花, sex=1, className=动科181, stuId=2078788107, phone=199885454512)]

パフォーマンスの比較

ここに画像の説明を挿入します

アノテーションの紹介

ここに画像の説明を挿入します

参照ブログ:

この記事を書いている時点で、私は予備学習段階にあり、学習を助けてくれたこれらの記事に感謝しています。

  1. MapStructの超簡単な研究ノート
  2. それらのBeanUtilsツールを捨ててください、MapStructはとても香りがよいです!
  3. アリババがプロパティの
    コピーにApacheBeanutilsを使用することを禁止しているのはなぜですか?
  4. MapStructの使用を開始する

おすすめ

転載: blog.csdn.net/zhang19903848257/article/details/113739973