DTOの使用 パーマリンク to " DTOの使用"

はじめに パーマリンク to "はじめに"

デフォルトでは、JHipsterはドメイン・オブジェクト(通常はJPAエンティティ)をRESTエンドポイントで直接使用します。 これには多くの利点がありますが、主な利点は、コードに含まれるレイヤーが少ないため、コードが理解しやすいことです。

ただし、複雑なユースケースでは、RESTエンドポイントによって公開されるデータ転送オブジェクト(またはDTO)の使用を必要とする場合があります。これらのオブジェクトは、ドメインオブジェクトの上に追加のレイヤを追加し、特にRESTレイヤに合わせて調整されます:主な利点は、複数のドメインオブジェクトを集約できることです。

JHipsterでのDTOの動作 パーマリンク to "JHipsterでのDTOの動作"

JHipsterエンティティを生成する場合、サービスレイヤを追加するオプションがあります。DTOオプションは、マッピングを処理するためにサービスレイヤが必要なため、サービスレイヤを選択した場合にのみ使用できます(JPAを使用している場合、これはサービスレイヤがトランザクションであるため、遅延ロードが機能します)。

サービス・レイヤーを選択すると、エンティティのDTOを生成するオプションが表示されます。このオプションを選択すると、次のことが可能になります。

  • DTOが生成され、元となるエンティティにマップされます。
  • 多対1の関係を集約し、クライアント側のフレームワーク(Angularなど)で表示するために使用されるIDとフィールドのみを使用します。その結果、Userエンティティへの多対1の関係は、userIdフィールドとuserLoginフィールドをDTOに追加します。
  • 所有者でない側の1対多の関係と多対多の関係は無視します。これはエンティティの動作と一致します(エンティティはこれらのフィールドに@JsonIgnoreアノテーションを持っています)。
  • 所有者側の多対多関係の場合:他のエンティティからのDTOをSetで集約して使用します。これは、他のエンティティもDTOを使用する場合にのみ機能します。

MapStructを使用したDTOとエンティティのマッピング パーマリンク to "MapStructを使用したDTOとエンティティのマッピング"

DTOはエンティティによく似ているため、DTOを互いに自動的にマッピングするソリューションが必要になることがよくあります。

JHipsterで選択されたソリューションはMapStructです。必要なマッピングを自動的に生成するのは、Javaコンパイラーにプラグインされたアノテーション・プロセッサーです。

非常にクリーンで効率的であり、リフレクションを使用しないことが気に入りました(リフレクションはマッパーのように多様するとパフォーマンスに悪影響を及ぼします)。

MapStruct用にIDEを構成する パーマリンク to "MapStruct用にIDEを構成する"

MapStructはアノテーションプロセッサであるため、IDEがプロジェクトをコンパイルするときに自動的に実行されるよう設定する必要があります。

Mavenを使用している場合は、IDEでIDEのMavenプロファイルをアクティブにする必要があります。Gradleユーザは、IDE固有のものを適用する必要はありません。

プロファイルをアクティブにする手順については、IDEの設定を参照してください。

高度なMapStructの使用法 パーマリンク to "高度なMapStructの使用法"

MapStructマッパーはSpring Beanとして構成され、依存性注入をサポートします。便利なヒントの1つは、マッパーにRepositoryを注入できるため、そのIDを使用してマッパーにて管理対象としたいJPAエンティティをフェッチできることです。

以下にUserエンティティを取得するコードの例を示します。

@Mapper
public abstract class CarMapper {

    @Inject
    private UserRepository userRepository;

    @Mapping(source = "user.id", target = "userId")
    @Mapping(source = "user.login", target = "userLogin")
    public abstract CarDTO carToCarDTO(Car car);

    @Mapping(source = "userId", target = "user")
    public abstract Car carDTOToCar(CarDTO carDTO);

    public User userFromId(Long id) {
        if (id == null) {
            return null;
        }
        return userRepository.findOne(id);
    }
}