0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

MapStructを用いてのModelとDTOのマッピングについて

Last updated at Posted at 2023-08-12

1.目的

 SpringBootのAPIにおいて、DBから取得した内容をModelに設定した後に、レスポンスに返す前にDTOへ設定する際の方法について残します。

2.環境

   eclipse(Version: 2022-12 (4.26.0))
   java(ver.17)
   spring boot 3.1.1
   Gradle - Groovy
   mysql(Ver 8.0.33)

3.事前準備

(1) MapStructを紐付ける土台となるファイルを用意します。

※これを用意しないと実際のMappingがうまくいかない。
配置場所はプロジェクト直下や問わない。

ConfigMapper.java

package com.talent.setting;

import org.mapstruct.MapperConfig;
import org.mapstruct.NullValueMappingStrategy;
import org.mapstruct.ReportingPolicy;
/**
 * MapStruct設定用
 */
@MapperConfig(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE,
        nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL)
public interface ConfigMapper {
}

(2) DBの結果や値の設定が格納されているModelを準備します。

※以下は、
前回記事「MyBatisGeneratorを用いて、Model・Mapperの作成」で作成したものと同様。
https://qiita.com/yu-F/items/a612dc9b0ee4008c8b31)

TOnAirKanri.java

package com.model;

import java.util.Objects;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.annotation.Generated;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

/**
 * オンエア管理テーブル情報(全列)
 */

@Schema(name = "tOnAirKanri", description = "オンエア管理テーブル情報(全列)")
@JsonTypeName("tOnAirKanri")
@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2023-06-12T21:30:49.581521+09:00[Asia/Tokyo]")
public class TOnAirKanri {

  @JsonProperty("id")
  private String id;

  @JsonProperty("onairDay")
  private String onairDay;

  @JsonProperty("programId")
  private String programId;

  @JsonProperty("talentId")
  private String talentId;

  @JsonProperty("targetNentsuki")
  private Integer targetNentsuki;

  @JsonProperty("targetShu")
  private Integer targetShu;

  @JsonProperty("deleteFlg")
  private Integer deleteFlg;

  @JsonProperty("torokuDay")
  private String torokuDay;

  @JsonProperty("koushinDay")
  private String koushinDay;

  public TOnAirKanri id(String id) {
    this.id = id;
    return this;
  }

  /**
   * ID
   * @return id
  */
  @Size(max = 8) 
  @Schema(name = "id", description = "ID", required = false)
  public String getId() {
    return id;
  }

  public void setId(String id) {
    this.id = id;
  }

  public TOnAirKanri onairDay(String onairDay) {
    this.onairDay = onairDay;
    return this;
  }

  /**
   * オンエア日
   * @return onairDay
  */
  @Valid 
  @Schema(name = "onairDay", description = "オンエア日", required = false)
  public String getonairDay() {
    return onairDay;
  }

  public void setonairDay(String onairDay) {
    this.onairDay = onairDay;
  }

  public TOnAirKanri programId(String programId) {
    this.programId = programId;
    return this;
  }

  /**
   * 番組ID
   * @return programId
  */
  @NotNull @Size(max = 8) 
  @Schema(name = "programId", description = "番組ID", required = true)
  public String getProgramId() {
    return programId;
  }

  public void setProgramId(String programId) {
    this.programId = programId;
  }

  public TOnAirKanri talentId(String talentId) {
    this.talentId = talentId;
    return this;
  }

  /**
   * タレントID
   * @return talentId
  */
  @Size(max = 8) 
  @Schema(name = "talentId", description = "タレントID", required = false)
  public String getTalentId() {
    return talentId;
  }

  public void setTalentId(String talentId) {
    this.talentId = talentId;
  }

  public TOnAirKanri targetNentsuki(Integer targetNentsuki) {
    this.targetNentsuki = targetNentsuki;
    return this;
  }

  /**
   * 対象年月
   * minimum: 1990
   * maximum: 2100
   * @return targetNentsuki
  */
  @Min(1990) @Max(2100) 
  @Schema(name = "targetNentsuki", description = "対象年月", required = false)
  public Integer getTargetNentsuki() {
    return targetNentsuki;
  }

  public void setTargetNentsuki(Integer targetNentsuki) {
    this.targetNentsuki = targetNentsuki;
  }

  public TOnAirKanri targetShu(Integer targetShu) {
    this.targetShu = targetShu;
    return this;
  }

  /**
   * 対象週
   * minimum: 1
   * maximum: 5
   * @return targetShu
  */
  @Min(1) @Max(5) 
  @Schema(name = "targetShu", description = "対象週", required = false)
  public Integer getTargetShu() {
    return targetShu;
  }

  public void setTargetShu(Integer targetShu) {
    this.targetShu = targetShu;
  }

  public TOnAirKanri deleteFlg(Integer deleteFlg) {
    this.deleteFlg = deleteFlg;
    return this;
  }

  /**
   * 論理削除フラグ
   * minimum: 0
   * maximum: 9
   * @return deleteFlg
  */
  @Min(0) @Max(9) 
  @Schema(name = "deleteFlg", description = "論理削除フラグ", required = false)
  public Integer getDeleteFlg() {
    return deleteFlg;
  }

  public void setDeleteFlg(Integer deleteFlg) {
    this.deleteFlg = deleteFlg;
  }

  public TOnAirKanri torokuDay(String torokuDay) {
    this.torokuDay = torokuDay;
    return this;
  }

  /**
   * 登録日
   * @return torokuDay
  */
  
  @Schema(name = "torokuDay", description = "登録日", required = false)
  public String getTorokuDay() {
    return torokuDay;
  }

  public void setTorokuDay(String torokuDay) {
    this.torokuDay = torokuDay;
  }

  public TOnAirKanri koushinDay(String koushinDay) {
    this.koushinDay = koushinDay;
    return this;
  }

  /**
   * 更新日
   * @return koushinDay
  */
  
  @Schema(name = "koushinDay", description = "更新日", required = false)
  public String getKoushinDay() {
    return koushinDay;
  }

  public void setKoushinDay(String koushinDay) {
    this.koushinDay = koushinDay;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    TOnAirKanri tOnAirKanri = (TOnAirKanri) o;
    return Objects.equals(this.id, tOnAirKanri.id) &&
        Objects.equals(this.onairDay, tOnAirKanri.onairDay) &&
        Objects.equals(this.programId, tOnAirKanri.programId) &&
        Objects.equals(this.talentId, tOnAirKanri.talentId) &&
        Objects.equals(this.targetNentsuki, tOnAirKanri.targetNentsuki) &&
        Objects.equals(this.targetShu, tOnAirKanri.targetShu) &&
        Objects.equals(this.deleteFlg, tOnAirKanri.deleteFlg) &&
        Objects.equals(this.torokuDay, tOnAirKanri.torokuDay) &&
        Objects.equals(this.koushinDay, tOnAirKanri.koushinDay);
  }

  @Override
  public int hashCode() {
    return Objects.hash(id, onairDay, programId, talentId, targetNentsuki, targetShu, deleteFlg, torokuDay, koushinDay);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append("class TOnAirKanri {\n");
    sb.append("    id: ").append(toIndentedString(id)).append("\n");
    sb.append("    onairDay: ").append(toIndentedString(onairDay)).append("\n");
    sb.append("    programId: ").append(toIndentedString(programId)).append("\n");
    sb.append("    talentId: ").append(toIndentedString(talentId)).append("\n");
    sb.append("    targetNentsuki: ").append(toIndentedString(targetNentsuki)).append("\n");
    sb.append("    targetShu: ").append(toIndentedString(targetShu)).append("\n");
    sb.append("    deleteFlg: ").append(toIndentedString(deleteFlg)).append("\n");
    sb.append("    torokuDay: ").append(toIndentedString(torokuDay)).append("\n");
    sb.append("    koushinDay: ").append(toIndentedString(koushinDay)).append("\n");
    sb.append("}");
    return sb.toString();
  }

  /**
   * Convert the given object to string with each line indented by 4 spaces
   * (except the first line).
   */
  private String toIndentedString(Object o) {
    if (o == null) {
      return "null";
    }
    return o.toString().replace("\n", "\n    ");
  }
}

(3) (2)の戻りの値を格納したいDTOを用意します。

※(2)の内容とは異なるフィールドで用意。

OnAirKanriInfoDto.java

package com.talent.service.dto;

import java.io.Serializable;

import com.talent.service.dto.entity.Talent;
import com.talent.service.dto.entity.TvProgram;

import lombok.Data;

/**
 * オンエア管理情報DTO
 */
@Data
public class OnAirKanriInfoDto implements Serializable {
    private String id;
    private Talent talent;
    private TvProgram tvProgram;
    private Integer nentsuki;
    private Integer shu;
}

(4) (2)と(3)の内容を紐付け用のメソッド定義を用意。

※今回は、Helperクラスに定義を記載する。

ShukanTalentJohoBffHelper.java

package com.talent.service.helper;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

import com.model.TOnAirKanri;
import com.talent.service.dto.OnAirKanriInfoDto;
import com.talent.setting.ConfigMapper;

@Mapper(config = ConfigMapper.class)
public interface ShukanTalentJohoBffHelper {

    @Mapping(source = "model.talentId", target = "talent.id")
    @Mapping(source = "talentNm", target = "talent.name")
    @Mapping(source = "model.programId", target = "tvProgram.id")
    @Mapping(source = "programNm", target = "tvProgram.name")
    @Mapping(source = "model.onairDay", target = "tvProgram.onairDay")
    OnAirKanriInfoDto toOnairKanriInfoDto(TOnAirKanri model);

}

メソッド定義は、
→「 【対象のDTO】メソッド名(【元となるModel】別名);」

元となるModelのプロパティ名と対象のDTOのプロパティ名が異なる場合は、
@Mapping(source = "【元となるModel.プロパティ名】", target = "【対象のDTO.プロパティ名】")

上記の定義をメソッドの上に用意する。

※DTOの内部のプロパティとModelの内部のプロパティ名が全く同様、ないしは値ごとに設定が無くても問題ない場合は、「@Mapping」は不要となる。(NULLで設定されたりする)

4.まとめ

MapStructはMybatisにおいては使用する機会が多く、一括で値が設定できるため、便利のため、使えるようになると簡潔にかけるようになります。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?