巨大なデータベースアプリケーションがあり、リファクタリングする必要があります(これには多くの理由があります。最大の理由はセキュリティです)。
私たちがすでに持っているもの:
- MySQLデータベース
- 100を超えるテーブルのJPA2(Eclipselink)クラス
- データベースに直接アクセスするクライアントアプリケーション
そこにある必要があるもの:
- RESTインターフェース
- データベースを介した役割でのログイン/ログアウト
私がこれまでにしたこと:
- SpringSecurity3.1.1を使用してSpringMVC3.2.1をセットアップします
- カスタムの使用
UserDetailsService
(atmをテストするための静的データのみが含まれています) - テスト用にいくつかのコントローラーを作成しました(単にデータを受信/提供するだけです)
設計上の問題:
- データベースにmaaaaany@OneToManyと@ManyToManyの関係があります
1 .:(重要)
すべての子オブジェクトを含むオブジェクトツリー全体を応答として送信する場合、データベース全体を一度に送信できる可能性があります。
したがって、たとえば「すべての記事」を要求する方法が必要です。ただし、すべての子オブジェクトを省略する必要があります。私は昨日これを試しましたが、受け取ったオブジェクトは数トンのメガバイトでした。
@PersistenceContext
private EntityManager em;
@RequestMapping(method=RequestMethod.GET)
public @ResponseBody List<Article> index() {
List<Article> a = em.createQuery("SELECT a FROM Article a", Article.class).getResultList();
return a;
}
2 .:(重要)
クライアントが記事を受け取った場合、現時点では電話をかけるだけでarticle.getAuthor()
、JPAがを実行しSELECT a FROM Author a JOIN Article ar WHERE ar.author_id = ?
ます。
RESTを使用すると、にリクエストを送信でき/authors/{id}
ます。ただし、この方法では、モデルにが含まれているが含まれていないため、クライアント側で古いJPAモデルを使用することはできませAuthor author
んLong author_id
。
すべてのモデルを書き直す必要がありますか、それとももっと簡単なアプローチがありますか?
3 .:(それほど重要ではない)
認証:ステートレスにするかどうか?私はこれまでステートレス認証を使用したことがありませんが、Springはそれを何らかの形でサポートしているようです。Webでいくつかのサンプル実装を見ると、セキュリティ上の懸念があります。リクエストごとに、ユーザー名とパスワードが送信されます。これは正しい方法ではありません。
誰かがそのための良い解決策を知っているなら、教えてください。それ以外の場合は、標準のHTTPセッションを使用します。
4.:
クライアントサイドモデルを設計するための最良の方法は何ですか?
public class Book {
int id;
List<Author> authors; //option1
List<Integer> authorIds; //option2
Map<Integer, Author> idAuthorMap; //option3
}
(これは複数の著者がいる本です)。3つのオプションはすべて、長所と短所が異なります。
Author
対応するモデルに直接アクセスすることもできますが、 RESTを介してモデルをリクエストしたBook
場合、モデルは今は必要ないかもしれませんが、後で必要になります。したがって、オプション2の方が適しています。Book
RESTを介してモデルを直接リクエストできます。そして、を使用してauthorIds
、後で対応する作成者をフェッチします。しかし、今は単純に使用することはできませんmyBook.getAuthors()
。- これは1と2の混合です。ID
Book
のみが含まれているsを要求した場合、次のAuthor
ようなことができますidAuthorMap.put(authorId, null)
。
しかし、多分私のためにすべてのものを処理するJavaライブラリがありますか?!
今のところ以上です。君たちありがとう :)
多分解決策:
問題:必要なデータのみを選択してください。これは、多かれ少なかれすべて@ManyToMany
の@OneToMany
、、@ManyToOne
関係を無視することを意味します。
解決策:@JsonIgnore
および/またはを使用し@JsonIgnoreProperties
ます。
問題:無視されたすべての関係は、データモデルを変更せずに簡単にフェッチされるはずです。
解決策:モデルの例:
class Book {
int bId;
Author author; // has @ManyToOne
}
class Author {
int aId;
List<Book> books; // has @OneToMany
}
これで、RESTを介して本をフェッチできます。GET /books/4
結果は次のようになります('を介してすべての関係を無視するため@JsonIgnore
):{"bId":4}
次に、関連する作成者を受け取るための別のルートを作成する必要がありますGET /books/4/author
。戻ります:{"aId":6}
。
後方:GET /authors/6/books
-> [{"bId":4},{"bId":42}]
。
、、、ごと@ManyToMany
にルートがありますが@OneToMany
、@ManyToOne
それ以上はありません。したがって、これは存在しませんGET /authors/6/books/42
。クライアントはを使用する必要がありますGET /books/42
。