SpringBoot のようなフレームワークで非常に多くのことができるのは素晴らしいことです。
必要なのは JPA エンティティ クラスと単純なリポジトリ インターフェイスだけであり、SpringData は一般的な CRUD データベース操作に必要なものをすべて提供します。
単純な REST コントローラー クラスを作成し、REST API を実行していますよね?
おい、でも DTO を書くのを忘れた!しかし、アプリがなくても機能するのに、実際にはなぜそれが必要なのでしょうか?
確かに一般的な理由がいくつかあります:
しかし、他にも奇妙なことが起こる可能性があります。私の経験に基づいた奇妙な例を 1 つ紹介します。
この GitHub リポジトリには、DTO なしで動作する単純なアプリケーションが含まれています。ユーザー エンティティがあり、各ユーザーは複数のトランザクションを持つことができます。リポジトリと RestController の間に Service Bean もあり、発生する可能性のあるデータベース アクセス例外をキャッチします。
本番環境に対応したアプリケーションを作成したいので、Hibernate に DDL を生成させたくありません。代わりに、テーブルを作成する schema.sql があります (後で Flyway または Liquibase に切り替える可能性があります)。この簡単な例では、テーブルが空にならないように data.sql も用意しています。
アプリケーションを実行し、http://localhost:8080/users で API エンドポイントを呼び出すと、ユーザーとそのトランザクションを含む予想される JSON が取得されます。
次に、Transaction クラスの // とマークされた 2 行のコードに注目してみましょう。
@JsonIgnore //!!
最初の特徴は、Transaction クラスで @JsonIgnore アノテーションを User 参照に追加する必要があるということです。このアノテーションがないと、JSON シリアル化は無限再帰によりクラッシュします。
次に、誰かがトランザクション エンティティに別のフィールド (説明) を追加するという間違いを犯し、SQL ステートメントの調整を忘れた (または、スキーマ変更が適用されていない環境に対してアプリケーションを実行した) と想像してみましょう。
プライベート文字列の説明;//!!
もちろん、今度は API 呼び出しは失敗します。しかし、エラー処理を見てください。 UserService 内の catch 句が期待どおりに機能しません。代わりに、ログに奇妙なスタック トレースが表示されます。
GlobalExceptionHandler : 予期しないエラー org.springframework.http.converter.HttpMessageNotWritableException: JSON を書き込めませんでした:
私はかつてこの状況を見たことがあり (明らかに、この例よりもはるかに大規模なアプリケーションでした)、SQL 例外がサービスをエスケープした理由と HttpMessageNotWritableException が発生した理由を理解するのにかなりの時間がかかりました。見えますか?
何が起こるかというと、UserService クラスは (UserRepository 経由で) USERS データベース テーブルのみをクエリします。デフォルトの Hibernate 遅延ロードのため、トランザクション エンティティは結果の一部ではありません。 Jackson デシリアライザーが User インスタンスから JSON を作成しようとする場合にのみ、Hibernate に Transaction エンティティをフェッチさせる getTransactions メソッドを呼び出します。
これが、JSON と SQL を組み合わせた奇妙なスタックトレースが得られる理由です。この例外は、処理方法がわからない GlobalExceptionHandler によってキャッチされます。これが、ログ メッセージが「予期しないエラー」となる理由です。
この小さな演習で、アプリケーションの異なるレイヤーを混在させることがいかに危険であるかをより深く理解していただければ幸いです。アプリケーションがまだ小さいうちに、アプリケーションの「晴れた日」のシナリオだけを見ると、一部の開発者は手遅れになるまで間違った行為を続ける可能性があります。
DTO とアプリケーションの他の層の間でフィールドをマッピングする定型コードを記述する必要はありません。 MapStruct が代わりにそれを実行します。
以上がDTO をスキップすると何が起こるかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。