效率提升-再次實踐pojo的映射簡化(mapStruct)

背景

之前寫了一個mapStruct的Hello World,本wiki將再用一個實際項目中的例子來進行優化。

實現過程

創建一個spring boot項目

在這裏插入圖片描述
這裏創建了一個MyApplicationRunner,方便我們調試bean

複製之前項目中的代碼

我們先看一下兩個需要轉換的類。
ClassTaskPO.java

import lombok.Data;
import lombok.NoArgsConstructor;

import java.sql.Timestamp;


/**
 * <p>Description: 班級任務持久化對象類</p>
 *
 * @author wang
 * @date 2018/10/22
 **/
@Data
@NoArgsConstructor
public class ClassTaskPO {
    private Long id;
    private Integer oldTaskId;
    private Long templateId;
    private String publisherId;
    private String publisherName;
    private String relation;
    private String classId;
    private String className;
    private String schoolId;
    private String userId;
    private Integer roleType;
    private Integer type;
    private String tags;
    private String title;
    private String image;
    private Integer imageWidth;
    private Integer imageHeight;
    private String coverImage;
    private Integer coverImageWidth;
    private Integer coverImageHeight;
    private String introduction;
    private String content;
    private String remarkContent;
    private Integer origin;
    private Integer totalCount;
    private Integer totalDay;
    private Timestamp startTime;
    private Timestamp endTime;
    private String submitEndTime;
    private Integer state;
    private String students;
    private Integer contentType;
    private Integer visibility;
    private Integer isDelete;
    private Integer isRemark;
    private Long remindTime;
    private Timestamp createTime;
    private Timestamp updateTime;

	// 直接在構造函數中寫的轉換,缺點是:即使屬性名稱相同,也得一個一個去寫屬性匹配(不留神丟一個,就尷尬了)
    public ClassTaskPO(ClassTaskWriteDTO classTaskWriteDTO) {
        templateId = classTaskWriteDTO.getTaskTemplateId();
        publisherId = classTaskWriteDTO.getPublisherId();
        // default配置
        publisherName = classTaskWriteDTO.getPublisherName() == null ? "" : classTaskWriteDTO.getPublisherName();
        relation = classTaskWriteDTO.getRelation();
        classId = classTaskWriteDTO.getClassId();
        className = classTaskWriteDTO.getClassName();
        userId = classTaskWriteDTO.getUserId();
        roleType = classTaskWriteDTO.getRoleType();
        schoolId = classTaskWriteDTO.getSchoolId();
        type = classTaskWriteDTO.getType();
        tags = classTaskWriteDTO.getTags();
        title = classTaskWriteDTO.getTitle();
        introduction = classTaskWriteDTO.getIntroduction();
        content = classTaskWriteDTO.getContent();
        remarkContent = classTaskWriteDTO.getRemarkContent();
        origin = classTaskWriteDTO.getOrigin();
        totalCount = classTaskWriteDTO.getTotalCount();
        totalDay = classTaskWriteDTO.getTotalDay();
        // 時間戳轉換
        startTime = new Timestamp(classTaskWriteDTO.getStartTime());
        endTime = new Timestamp(classTaskWriteDTO.getEndTime());
        // 時間戳轉換
        submitEndTime = classTaskWriteDTO.getSubmitEndTime();
        contentType = classTaskWriteDTO.getContentType();
        visibility = classTaskWriteDTO.getVisibility();
        // 時間戳轉換
        startTime = new Timestamp(classTaskWriteDTO.getStartTime());
        state = classTaskWriteDTO.getState();
    }

    public ClassTaskPO(ClassTaskUpdateDTO classTaskUpdateDTO) {
        id = classTaskUpdateDTO.getTaskId();
        schoolId = classTaskUpdateDTO.getSchoolId();
        tags = classTaskUpdateDTO.getTags();
        title = classTaskUpdateDTO.getTitle();
        introduction = classTaskUpdateDTO.getIntroduction();
        content = classTaskUpdateDTO.getContent();
        submitEndTime = classTaskUpdateDTO.getSubmitEndTime();
        totalCount = classTaskUpdateDTO.getTaskTotalCount();
        totalDay = classTaskUpdateDTO.getTaskTotalDay();
        if (null != classTaskUpdateDTO.getStartTime()) {
            startTime = new Timestamp(classTaskUpdateDTO.getStartTime());
        }
        if (null != classTaskUpdateDTO.getEndTime()) {
            endTime = new Timestamp(classTaskUpdateDTO.getEndTime());
        }
    }

    public ClassTaskPO(ClassTaskDetail classTaskDetail, ClassTaskUpdateDTO classTaskUpdateDTO) {
        templateId = classTaskDetail.getTaskTemplateId();
        publisherId = classTaskDetail.getPublisherId();
        publisherName = classTaskDetail.getPublisherName() == null ? "" : classTaskDetail.getPublisherName();
        relation = classTaskDetail.getRelation();
        classId = classTaskDetail.getClassId();
        className = classTaskDetail.getClassName();
        userId = classTaskDetail.getUserId();
        roleType = classTaskDetail.getRoleType();
        schoolId = classTaskDetail.getSchoolId();
        type = classTaskDetail.getType();
        remarkContent = classTaskDetail.getRemarkContent();
        origin = classTaskDetail.getOrigin();
        contentType = classTaskDetail.getContentType();
        visibility = classTaskDetail.getVisibility();
        startTime = new Timestamp(classTaskDetail.getStartTime());
        state = classTaskDetail.getState();

        tags = classTaskUpdateDTO.getTags();
        title = classTaskUpdateDTO.getTitle();
        introduction = classTaskUpdateDTO.getIntroduction();
        content = classTaskUpdateDTO.getContent();
        startTime = new Timestamp(classTaskUpdateDTO.getStartTime());
        endTime = new Timestamp(classTaskUpdateDTO.getEndTime());
        submitEndTime = classTaskUpdateDTO.getSubmitEndTime();
        totalCount = classTaskUpdateDTO.getTaskTotalCount();
        totalDay = classTaskUpdateDTO.getTaskTotalDay();
    }
}

ClassTaskWriteDTO.java

import lombok.Data;

import java.io.Serializable;

/**
 * <p>Description: 班級任務寫入傳輸對象</p>
 *
 * @author wang
 * @date 2018/11/12
 **/
@Data
public class ClassTaskWriteDTO implements Serializable {
    private static final long serialVersionUID = -5720405607273123914L;

    private Long taskTemplateId;
    /**
     * 發佈者id
     */
    private String publisherId;
    /**
     * 發佈者名稱
     */
    private String publisherName;
    /**
     * 關係
     */
    private String relation;
    /**
     * 班級id
     */
    private String classId;
    /**
     * 班級名稱
     */
    private String className;
    /**
     * 學校id
     */
    private String schoolId;
    /**
     * 用戶id
     */
    private String userId;
    /**
     * 用戶類型
     */
    private Integer roleType;
    /**
     * 任務類型
     */
    private Integer type;
    /**
     * 任務標籤
     */
    private String tags;
    /**
     * 標題
     */
    private String title;
    /**
     * 任務介紹
     */
    private String introduction;
    /**
     * 任務內容
     */
    private String content;
    /**
     * 點評
     */
    private String remarkContent;
    /**
     * 任務來源
     */
    private Integer origin;
    /**
     * 連續任務總次數
     */
    private Integer totalCount;
    /**
     * 連續任務總天數
     */
    private Integer totalDay;
    /**
     * 任務參與人數
     */
    private Integer participateCount;
    /**
     * 任務狀態 0:進行中,1:已完成 2:已結束 3未開始
     */
    private Integer state;
    /**
     * 統一內容類型
     */
    private Integer contentType;
    private Integer visibility;
    /**
     * 任務開始時間
     */
    private Long startTime;
    /**
     * 任務結束時間
     */
    private Long endTime;
    /**
     * 打卡截止時間
     */
    private String submitEndTime;
}

可以看到,是使用構造函數實現了轉換過程。下面進行改造,使用mapStruct進行轉換。

使用mapStruct進行修改

添加pom文件依賴

<properties>
    <java.version>1.8</java.version>
    <mapstruct.version>1.3.1.Final</mapstruct.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<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>

添加代碼

MyTransform.java,實現不同類型之間的轉換

import org.springframework.stereotype.Component;

import java.sql.Timestamp;

@Component
public class MyTransform {
    public Timestamp longToTimestamp(Long t) {
        if (t != null) {
            return new Timestamp(t);
        }
        return null;
    }

    public Long timestampToLong(Timestamp timestamp) {
        if (timestamp != null) {
            return timestamp.getTime();
        }
        return null;
    }
}

添加映射類
MyMapper.java

import org.mapstruct.Mapper;

import java.sql.Timestamp;

@Mapper(
		// 在spring中使用,可以被Autowared
        componentModel = "spring",
        // 在生成的impl類中,添加import
        imports = Timestamp.class,
        // 使用轉換類(轉換類需要添加@Commponet)
        uses = {MyTransform.class}
)
public interface MyMapper {
    ClassTaskPO classTaskWriteDTOToClassTaskPO(ClassTaskWriteDTO classTaskWriteDTO);

    ClassTaskWriteDTO classTaskPOToClassTaskWriteDTO(ClassTaskPO classTaskPO);
}

在你ApplicationRunner中進行測試
在這裏插入圖片描述

自定生成的impl代碼

import java.sql.Timestamp;
import javax.annotation.Generated;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-04-04T14:51:17+0800",
    comments = "version: 1.3.1.Final, compiler: javac, environment: Java 1.8.0_111 (Oracle Corporation)"
)
@Component
public class MyMapperImpl implements MyMapper {

    @Autowired
    private MyTransform myTransform;

    @Override
    public ClassTaskPO classTaskWriteDTOToClassTaskPO(ClassTaskWriteDTO classTaskWriteDTO) {
        if ( classTaskWriteDTO == null ) {
            return null;
        }

        ClassTaskPO classTaskPO = new ClassTaskPO();

        classTaskPO.setPublisherId( classTaskWriteDTO.getPublisherId() );
        classTaskPO.setPublisherName( classTaskWriteDTO.getPublisherName() );
        classTaskPO.setRelation( classTaskWriteDTO.getRelation() );
        classTaskPO.setClassId( classTaskWriteDTO.getClassId() );
        classTaskPO.setClassName( classTaskWriteDTO.getClassName() );
        classTaskPO.setSchoolId( classTaskWriteDTO.getSchoolId() );
        classTaskPO.setUserId( classTaskWriteDTO.getUserId() );
        classTaskPO.setRoleType( classTaskWriteDTO.getRoleType() );
        classTaskPO.setType( classTaskWriteDTO.getType() );
        classTaskPO.setTags( classTaskWriteDTO.getTags() );
        classTaskPO.setTitle( classTaskWriteDTO.getTitle() );
        classTaskPO.setIntroduction( classTaskWriteDTO.getIntroduction() );
        classTaskPO.setContent( classTaskWriteDTO.getContent() );
        classTaskPO.setRemarkContent( classTaskWriteDTO.getRemarkContent() );
        classTaskPO.setOrigin( classTaskWriteDTO.getOrigin() );
        classTaskPO.setTotalCount( classTaskWriteDTO.getTotalCount() );
        classTaskPO.setTotalDay( classTaskWriteDTO.getTotalDay() );
        classTaskPO.setStartTime( myTransform.longToTimestamp( classTaskWriteDTO.getStartTime() ) );
        classTaskPO.setEndTime( myTransform.longToTimestamp( classTaskWriteDTO.getEndTime() ) );
        classTaskPO.setSubmitEndTime( classTaskWriteDTO.getSubmitEndTime() );
        classTaskPO.setState( classTaskWriteDTO.getState() );
        classTaskPO.setContentType( classTaskWriteDTO.getContentType() );
        classTaskPO.setVisibility( classTaskWriteDTO.getVisibility() );

        return classTaskPO;
    }

    @Override
    public ClassTaskWriteDTO classTaskPOToClassTaskWriteDTO(ClassTaskPO classTaskPO) {
        if ( classTaskPO == null ) {
            return null;
        }

        ClassTaskWriteDTO classTaskWriteDTO = new ClassTaskWriteDTO();

        classTaskWriteDTO.setPublisherId( classTaskPO.getPublisherId() );
        classTaskWriteDTO.setPublisherName( classTaskPO.getPublisherName() );
        classTaskWriteDTO.setRelation( classTaskPO.getRelation() );
        classTaskWriteDTO.setClassId( classTaskPO.getClassId() );
        classTaskWriteDTO.setClassName( classTaskPO.getClassName() );
        classTaskWriteDTO.setSchoolId( classTaskPO.getSchoolId() );
        classTaskWriteDTO.setUserId( classTaskPO.getUserId() );
        classTaskWriteDTO.setRoleType( classTaskPO.getRoleType() );
        classTaskWriteDTO.setType( classTaskPO.getType() );
        classTaskWriteDTO.setTags( classTaskPO.getTags() );
        classTaskWriteDTO.setTitle( classTaskPO.getTitle() );
        classTaskWriteDTO.setIntroduction( classTaskPO.getIntroduction() );
        classTaskWriteDTO.setContent( classTaskPO.getContent() );
        classTaskWriteDTO.setRemarkContent( classTaskPO.getRemarkContent() );
        classTaskWriteDTO.setOrigin( classTaskPO.getOrigin() );
        classTaskWriteDTO.setTotalCount( classTaskPO.getTotalCount() );
        classTaskWriteDTO.setTotalDay( classTaskPO.getTotalDay() );
        classTaskWriteDTO.setState( classTaskPO.getState() );
        classTaskWriteDTO.setContentType( classTaskPO.getContentType() );
        classTaskWriteDTO.setVisibility( classTaskPO.getVisibility() );
        classTaskWriteDTO.setStartTime( myTransform.timestampToLong( classTaskPO.getStartTime() ) );
        classTaskWriteDTO.setEndTime( myTransform.timestampToLong( classTaskPO.getEndTime() ) );
        classTaskWriteDTO.setSubmitEndTime( classTaskPO.getSubmitEndTime() );

        return classTaskWriteDTO;
    }
}

不用自己去寫每個屬性,只需要寫一下mapper,如果需要的話,寫一個通用的transform即可

評價

  • 不用再去一個個屬性的去寫,以免丟失
  • 可以自己定義屬性變化
  • 可以在spring中使用mapStruct
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章