14

アプリケーションにデータ アクセス コードを実装するには、jdbc をラップするフレームワークが必要です (スケーラビリティのため、ORM は選択しません)。

私が使っていた最もクールなフレームワークはSpring-Jdbcです。ただし、私の会社のポリシーは、外部依存、特にSpring、J2EEなどを避けることです。そのため、Spring-jdbcに似た機能を持つ独自の便利なjdbcフレームワークを作成することを考えています:行マッピング、エラー処理、java5のサポート機能、ただしトランザクション サポートなし。

そのような jdbc ラッパー フレームワークを作成した経験のある人はいますか? 他の jdbc ラッパー フレームワークを使用した経験がある場合は、その経験を共有してください。

前もって感謝します。

4

8 に答える 8

14

独自のラッパーを作成しました。このトピックは論文に値するものですが、これを書く時間がないのではないかと思います。そのため、いくつかの重要なポイントを以下に示します。

  • 私たちはSQLを受け入れ、それを隠そうとはしませんでした。唯一の調整は、名前付きパラメーターのサポートを追加することでした。パラメータは重要です。なぜなら、(セキュリティ上の理由から) オンザフライでの sql の使用を推奨しておらず、常に PreparedStatements を使用しているからです。

  • 接続管理には、Apache DBCP を使用しました。これは当時は便利でしたが、最新の JDBC 実装でこれがどれだけ必要かは不明です (これに関するドキュメントはありません)。DBCP は、PreparedStatements もプールします。

  • 行のマッピングは気にしませんでした。代わりに (クエリ用に) Apache dbutil の ResultSetHandler に似たものを使用しました。これにより、結果セットをメソッドに「フィード」して、必要な場所に情報をダンプできます。これはより柔軟で、実際、行マッピングのために ResultSetHandler を実装することは難しくありません。挿入/更新のために、一般的なレコード クラスを作成しました (基本的には、追加の機能を備えたハッシュマップ)。行マッピングの最大の問題 (私たちにとって) は、さまざまなクラスにマップされるフィールドがある可能性があるため、「興味深い」クエリを実行するとすぐに動けなくなることです。階層的なクラス構造を持っていても、フラットな結果セットを持っている可能性があるためです。または、マッピングが複雑でデータに依存しているためです。

  • エラーログが組み込まれています。例外処理: クエリではトラップしてログに記録しますが、更新では未チェックの例外をトラップしてログに記録し、再スローします。

  • ラッパー アプローチを使用してトランザクション サポートを提供しました。呼び出し元はトランザクションを実行するコードを提供し、トランザクションが適切に管理されていることを確認します。トランザクションの終了を忘れる可能性はなく、ロールバックとエラー処理が組み込まれています。

  • 後で、単一の更新/挿入をレコードとそのすべての依存関係に適用できるようにする、非常に単純な関係スキームを追加しました。単純にするために、クエリではこれを使用しませんでした。カスケード削除を使用する方が信頼性が高いため、削除ではこれをサポートしないことにしました。

このラッパーは、これまでに 2 つのプロジェクトで成功裏に使用されています。もちろん軽量ですが、最近ではコードが軽量であると誰もが言います。さらに重要なことは、プログラマーの生産性が向上し、バグの数が減り (そして問題の追跡が容易になります)、必要に応じて比較的簡単に追跡できることです。これは、美しいアーキテクチャを提供するためだけに多くのレイヤーを追加することは考えていないためです。

于 2008-11-18T19:13:17.450 に答える
5

Spring-JDBC は素晴らしいです。Spring のようなオープン ソース プロジェクトの場合、外部依存のマイナス面が最小限に抑えられることを考慮してください。JDBC の抽象化要件を満たす最も安定したバージョンの Spring を採用できます。また、問題が発生した場合に、外部の関係者に依存することなく、いつでも自分でソース コードを変更できることがわかっています。また、組織が外部の関係者によって記述されたコードで発生する可能性のあるセキュリティ上の懸念について、実装を調べることもできます。

于 2008-11-18T18:28:50.723 に答える
3

私が好むもの:デールズブレッド。MITライセンスです。

カスタム クラス (Department) のすべての行を取得する簡単な例。

List<Department> departments = db.findAll(Department.class,
    "select id, name from department");

カスタム クラスが次のように定義されている場合:

public final class Department {
    private final int id;
    private final String name;

    public Department(int id, String name) {
        this.id = id;
        this.name = name;
    }
}

免責事項:それは私が働いている会社によるものです。

于 2012-10-11T18:30:45.560 に答える
1

これは非常に近視眼的な決定のように聞こえます。このようなフレームワークの開発/保守のコストを考慮してください。特に、フレームワークを入手できる場合は、無料でソースコードを入手できます。自分で開発する必要がないだけでなく、必要に応じて自由に変更することができます。

そうは言っても、実際に複製する必要があるのは、JdbcTemplateとそのコールバック(PreparedStatementCreator、PreparedStatementCallback)、およびRowMapper/RowCallbackHandlerの概念です。このようなものを書くことは過度に複雑であってはなりません(特にトランザクション管理を行う必要がないことを考えると)。

しかし、私が言ったように、無料で入手でき、適切と思われるソースコードを変更できるのに、なぜそれを書くのでしょうか。

于 2012-05-17T12:08:49.090 に答える
1

jcabi-jdbcJdbcSessionから試してください。これは、JDBCのように単純です。たとえば、次のようになります。

String name = new JdbcSession(source)
  .sql("SELECT name FROM foo WHERE id = ?")
  .set(123)
  .select(new SingleOutcome<String>(String.class));

それでおしまい。

于 2012-05-17T11:46:54.023 に答える