4

これは、データベースに接続する必要があるときに常に遭遇する問題です。SQLを通常のJavaコードから分離する方法は?私は通常、データベース接続に個別のクラスを使用しますが、各データベースに複数のデータベースと複数のテーブルがある場合、これを100%行うことは常に困難です。

例として、すべてのJava SQLをDBConnector.javaという名前のクラスに入れたい場合、さまざまな挿入、削除、データ取得などを一般的にコーディングするにはどうすればよいでしょうか。私が理想的なケースとして考えているのは、すべてのSQLステートメントが同じクラスにあり、データベースアプリケーションのスコープ内で同じ操作のさまざまなフレーバーと互換性があるため、残りのコードから論理的に分離されている必要があるということです。

public void insertData (String db, String table, <Whatever Fields to be Inserted>)
{
  //generic SQL INSERT statement and execution 
}

public ResultSet retrieveData (String db, String table, <Whatever Fields Relevant>) 
{
  //generic retrieval of data
}

これを達成する方法はありますか?または、挿入、クエリなどのさまざまなフレーバーの機能を追加する必要がありますか?

ありがとうございました!

4

4 に答える 4

7

健全なアーキテクチャが必要な場合は、懸念事項を分離するために少なくともいくつかのレイヤーが必要になります。

まず、モデルクラスから始めます(ほとんどの場合、データベース内のすべてのテーブルに1つ必要です)。それらを自分で作成するか、ORM(EclipseLink、Hibernateなど)を使用して自動的に生成します。これらはPOJO(Plain Old Java Objects)である必要があります。これはsimple、プロパティ(NameStringId型、integer型など)を持つオブジェクトであることを意味します。モデルオブジェクトはデータのキャリアである必要があり、それ以上のものではありません(確かにロジックや処理はありません)。

次に、すべてのモデルクラスに対してDAO(データアクセスオブジェクト)を作成します(必要に応じて、継承するGenericDaoクラスを作成できます)。ここでは、モデルオブジェクトを引数として取るメソッドを介してCRUD操作(挿入、更新、削除)を提供します。これはデータベースバックエンド固有ですが、必要に応じてデータベースに依存しないDAOレイヤーを挿入できます。

第3に、クラスの論理グループごとにサービス層またはマネージャー層を用意します(これは、必要なすべての機能のためにすべてのフロントエンドおよびコントローラーコードが通信する必要がある層です)。典型的なメソッドを呼び出すことができますregisterCustomer(...)(異なるDAOクラスを使用する場合があります)。またはfindCustomerByName()など。

このようにアプリケーションを構造化することはMVC(モデル-ビュー-コントローラー)と呼ばれるので、より多くの情報が必要な場合は、これがグーグルの用語です。

このように、通常、DAOレイヤーより上位のSQLクエリはありません。つまり、アプリケーションはa)保守可能であり、b)後でバックエンドを変更する方が簡単です。

于 2012-06-03T18:57:13.737 に答える
3

Izza、ここでSQLをJavaコードから分離することについての議論があります:Java-外部ファイルへのSQLステートメントの保存 ソリューションは理解できますが、クエリが標準でない場合(たとえば、a = 10の場合だけでなく)、いくつかの問題が発生します。ただし、in(...)またはgroup byが含まれているため、避けることをお勧めします。JavaでDBを使用するときにボイラープレートコードを最小限に抑えるには、Spring JDBCを使用する必要があります。また、許容できる場合は、Hibernateを使用することもできます。 、それはあなたがsqlのいくつかの使用を避けることを可能にします。

于 2012-06-03T18:54:51.867 に答える
1

最善のアプローチは、現在業界標準となっているHibernateを使用することです。

一言で言えば、必要なSQLを生成し、コードは行を表すJavaオブジェクトを処理します。セッターを呼び出すと、Hibernateは更新を実行するために必要なSQLを把握します。

ゲッターの場合、コードは次のようになります。

shoppingCart.getCustomer().getCountry().getCode();

shopping_cartそして、Hibernateは、テーブルからcountryテーブルを介してテーブルに移動するために必要なSQL結合を把握しcustomerます。

それは本当に素晴らしく、移行する価値があります。

于 2012-06-03T18:52:19.240 に答える
1

いくつかを使用する必要がありますDAOFactory。このクラスは接続を取得するために使用されます。データベースにテーブルを反映するDTO - Data Tranfer Objectsには、エンティティを表すを作成する必要があります。したがって、テーブルがある場合は、属性とゲッターおよびセッターを使用してUser作成するだけです。UserDTO.javaそして、データベースとの通信のためのクラスはですDAO - Data Access Object。ここでは、データベースからデータを取得するためのSQLステートメントとメソッドのみを作成する必要があります。そもそも適切に設計された構造です。そうすると、コードがよりクリーンに、より速く、より安全になります。自分で作成することをお勧めしますORM。だから、さまざまなフレームワークで見て、いくつかのテストをしてください


EasyORM

double count = 0;
TransDB trans = new TransDB() ;
List<Trans> list = new ArrayList<Trans>();
list = trans.getAll();
for (Trans element : list)
{
count+= element.getData();
}
...

Hibernate

double count = 0;
Session session = null;
List<Trans> list = new ArrayList<Trans>();
list = HibernateUtil.getSessionFactory().openSession();
list = (List<Trans>) session
.createQuery("from Trans").list();
for (Trans element : list)
{
count += element.getData().doubleValue();
}
...

と比較しますか?

評価(ミリ秒)

EasyORM:MySQL:init-6344、平均-4868 MS SQL:init-8126、平均-6752

Hibernate:MySQL:init-27406、平均-23728 MS SQL:init-28605(+ 250%)、平均-24912

ORMそれで、実際にから生成されたあなた自身SQL scriptは、Hibernate(10まで)よりも速いオーダーであり、なぜですか?層間に挿入することによって、スループットを向上させることはできません。これはたった1つのテストで、他にもあります。だから私はあなたがあなた自身を作成することをお勧めしますORM、またここに例えば時間の消費や使用される問題のある変更のようないくつかの欠点がありDMSますが、生成されたコマンドの完全な制御としての利点、あなたは特定の機能DMS(ORDM、特別なコマンドなど)を使うことができます。だから私はそれHibernateが最高だとは思いません、本当に違います。

于 2012-06-03T19:15:26.267 に答える