[SpringBoot&JPA]ドメイン分析設計
8378 ワード
[1]需要分析
👩🏻💻 要求
[2]ドメインモデルとテーブルの設計
会員は多様な商品を注文することができ、一度に注文すると多様な商品を選択することができる.→ N:M
(多対多関係はリレーショナル・データベースだけでなく、エンティティでもあまり使用されません.したがって、上図に示すように、エンティティ(受注商品)を追加することで多対多関係を解決します.)
継承構造
エンティティ分析
カテゴリと商品の多対多
表解析
(CATEGORY ITEMは中間表)
アルバム、図書、映画のジャンルを一つのテーブルにまとめる.次いで、DTYPE
列を用いてタイプを区別する.
📌 実際のコードでは、DBで小文字+スタイルを使用
(これは、既存の例では会社によって異なります.)
関連関係マッピング解析
会員と注文
:一対多、多対一の関係なので、関連関係が必要な主人は、外来鍵のある注文を関連関係の主人とするのが望ましい.
(したがって、Order.member
をORDERS.MEMBER_ID
外部キーにマッピングする)
商品と注文を注文する
:多対一の双方向関係.外来キーは受注商品にあるので、関連関係のオーナーです.
(したがって、OrderItem.order
をORDER_ITEM.ORDER_ID
外部キーにマッピングする)
商品と商品を注文する
:多対一の一方向関係.
(OrderItem.item
をORDER_ITEM.ITEM_ID
外部キーにマッピング)
注文と出荷
:一対一の双方向関係.
(Order.delivery
をORDERS.DELIVERY_ID
外部キーにマッピング)
カテゴリと商品
:@ManyToMany
を使用したマッピング
しかし、これは単なる例であり、実際の操作では使用できません.
📌 外部キーが置かれている場所は関連関係の主人です
関連関係のオーナーは、外部キーが誰が管理しているのかという問題だけで、ビジネスで優位に立っているわけではありません.
例えば自動車と車輪があり、一対多の関係では常に一対多の外来鍵があるので、車輪を関連関係の持ち主にすればよい.もちろん、自動車を関連関係の所有者とすることはできないが、自動車が所有者となると、自動車が管理しない車輪表の外部キー値を更新し、管理やメンテナンスが困難になり、追加の個別更新照会の性能問題が発生する可能性がある.
[3]開発エンティティクラス1
実験をできるだけ簡単に設計するために、@Getter
および@Setter
を開いて実行したが、実際の動作では、@Getter
は開いており、@Setter
は必要でない限り閉じている.
理論的には必要な方法のみを提供するのが理想的であるが、実際の作業ではクエリーを必要とするエンティティが多すぎて、@Getter
が開き、@Setter
が閉じられる.@Getter
は、呼び出しによってデータを変更することはありませんが、@Setter
にうっかり触れると危険です.
[4]開発エンティティクラス2
📌shift + option + command + L
:位置合わせ
✔️ Address.Javaでは、値タイプは変更不可に設計されています.@Setter
は開かれず、ジェネレータですべての値を初期化し、変更不可能なクラスにします.JPA仕様のエンティティまたはimbeddyタイプ(@Embedded
)はjavaデフォルトジェネレータをpublicまたはprotectedに設定する必要があります.
公共の安全よりも保護するように設定します.
(JPAにこのような制限があるのは、JPAインプリメンテーションライブラリがオブジェクトの作成時にレプリケーションなどの技術を使用することをサポートしなければならないためです.)
[5]エンティティを設計する際の注意事項
1.エンティティはなるべくSetterを使用しない
(例ではsetterを開いて操作を簡略化します)
Setterがすべて開いている場合は、変更点が多すぎてメンテナンスが困難です.
後で再構築でSetterを削除
2.すべての関連関係を遅延ロードに設定
インスタントロード(EAGER):ロード時に関連するすべてのコンテンツをロードします.
インスタント・ロードは予測しにくく、どのSQLが実行されるかを追跡するのは難しい.特にJPQLを実行するとN+1の問題がしばしば発生する.
したがって、実際の作業では、すべての関連関係を遅延ロード(LAZY)に設定する必要があります.
関連するエンティティがデータベースで一緒にクエリーする必要がある場合は、fetch joinまたはエンティティグラフィック機能を使用します.(この機能は最適化可能)
」@XToOne
(OneToOne,ManyToOne)関係は基本的にインスタントロードなので、直接すべて検索して遅延ロードに設定する必要があります.
📌 shift + command + F
:検索
fetch joinまたはソリッドグラフィックス機能の使用(必要に応じて)
3.集合をフィールドで初期化する
フィールド内の直接初期化コレクション(null問題)は安全です.
エンティティを永続化すると、仮想名は仮想名に指定された組み込み名に変更されます.getOrders()
のように、任意の方法で不正なセットを作成すると、仮想マシンの内部メカニズムに問題が発生する可能性があります.
したがって,フィールドレベルでの生成が最も安全であり,コードも簡潔になる.
4.テーブル、カラム名生成ポリシー
スプリングブートでHypernetのデフォルトマッピングポリシーが変更されたため、実際のテーブルフィールド名は異なります.
実験をできるだけ簡単に設計するために、
@Getter
および@Setter
を開いて実行したが、実際の動作では、@Getter
は開いており、@Setter
は必要でない限り閉じている.理論的には必要な方法のみを提供するのが理想的であるが、実際の作業ではクエリーを必要とするエンティティが多すぎて、
@Getter
が開き、@Setter
が閉じられる.@Getter
は、呼び出しによってデータを変更することはありませんが、@Setter
にうっかり触れると危険です.[4]開発エンティティクラス2
📌shift + option + command + L
:位置合わせ
✔️ Address.Javaでは、値タイプは変更不可に設計されています.@Setter
は開かれず、ジェネレータですべての値を初期化し、変更不可能なクラスにします.JPA仕様のエンティティまたはimbeddyタイプ(@Embedded
)はjavaデフォルトジェネレータをpublicまたはprotectedに設定する必要があります.
公共の安全よりも保護するように設定します.
(JPAにこのような制限があるのは、JPAインプリメンテーションライブラリがオブジェクトの作成時にレプリケーションなどの技術を使用することをサポートしなければならないためです.)
[5]エンティティを設計する際の注意事項
1.エンティティはなるべくSetterを使用しない
(例ではsetterを開いて操作を簡略化します)
Setterがすべて開いている場合は、変更点が多すぎてメンテナンスが困難です.
後で再構築でSetterを削除
2.すべての関連関係を遅延ロードに設定
インスタントロード(EAGER):ロード時に関連するすべてのコンテンツをロードします.
インスタント・ロードは予測しにくく、どのSQLが実行されるかを追跡するのは難しい.特にJPQLを実行するとN+1の問題がしばしば発生する.
したがって、実際の作業では、すべての関連関係を遅延ロード(LAZY)に設定する必要があります.
関連するエンティティがデータベースで一緒にクエリーする必要がある場合は、fetch joinまたはエンティティグラフィック機能を使用します.(この機能は最適化可能)
」@XToOne
(OneToOne,ManyToOne)関係は基本的にインスタントロードなので、直接すべて検索して遅延ロードに設定する必要があります.
📌 shift + command + F
:検索
fetch joinまたはソリッドグラフィックス機能の使用(必要に応じて)
3.集合をフィールドで初期化する
フィールド内の直接初期化コレクション(null問題)は安全です.
エンティティを永続化すると、仮想名は仮想名に指定された組み込み名に変更されます.getOrders()
のように、任意の方法で不正なセットを作成すると、仮想マシンの内部メカニズムに問題が発生する可能性があります.
したがって,フィールドレベルでの生成が最も安全であり,コードも簡潔になる.
4.テーブル、カラム名生成ポリシー
スプリングブートでHypernetのデフォルトマッピングポリシーが変更されたため、実際のテーブルフィールド名は異なります.
1.エンティティはなるべくSetterを使用しない
(例ではsetterを開いて操作を簡略化します)
Setterがすべて開いている場合は、変更点が多すぎてメンテナンスが困難です.
後で再構築でSetterを削除
2.すべての関連関係を遅延ロードに設定
インスタントロード(EAGER):ロード時に関連するすべてのコンテンツをロードします.
インスタント・ロードは予測しにくく、どのSQLが実行されるかを追跡するのは難しい.特にJPQLを実行するとN+1の問題がしばしば発生する.
したがって、実際の作業では、すべての関連関係を遅延ロード(LAZY)に設定する必要があります.
関連するエンティティがデータベースで一緒にクエリーする必要がある場合は、fetch joinまたはエンティティグラフィック機能を使用します.(この機能は最適化可能)
」
@XToOne
(OneToOne,ManyToOne)関係は基本的にインスタントロードなので、直接すべて検索して遅延ロードに設定する必要があります.📌
shift + command + F
:検索fetch joinまたはソリッドグラフィックス機能の使用(必要に応じて)
3.集合をフィールドで初期化する
フィールド内の直接初期化コレクション(null問題)は安全です.
エンティティを永続化すると、仮想名は仮想名に指定された組み込み名に変更されます.
getOrders()
のように、任意の方法で不正なセットを作成すると、仮想マシンの内部メカニズムに問題が発生する可能性があります.したがって,フィールドレベルでの生成が最も安全であり,コードも簡潔になる.
4.テーブル、カラム名生成ポリシー
スプリングブートでHypernetのデフォルトマッピングポリシーが変更されたため、実際のテーブルフィールド名は異なります.
スプリング起動新規設定(エンティティ(フィールド)→テーブル(列)
1.キャラメルボックス→アンダーコード(memberPoint→memberpoint)
2.
.
→ ``3.大文字→小文字
5. cascade = CascadeType.ALL
6.関連メソッド
// Order.java
//==연관관계 메소드==//
public void setMember(Member member) {
this.member = member;
member.getOrders().add(this);
}
public void addOrderItem(OrderItem orderItem) {
orderItems.add(orderItem);
orderItem.setOrder(this);
}
public void setDelivery(Delivery delivery) {
this.delivery = delivery;
delivery.setOrder(this);
}
// Category.java
//==연관관계 메소드==//
public void addChildCategory(Category child) {
this.child.add(child);
child.setParent(this);
}
Reference
この問題について([SpringBoot&JPA]ドメイン分析設計), 我々は、より多くの情報をここで見つけました https://velog.io/@dbsrud11/SpringBootJPA-도메인-분석-설계テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol