2016-07-28 1 views
0

私はJavaのORMからスイッチを外しています。私は、ORM以外の設定で多対1多対1の関係を処理する最良の方法は何か疑問に思っていました。ORMを使用しない場合、どのようにネストされたオブジェクトを扱うのですか?

私が持っている私の Customer.javaクラスで

:私が持っているPet.java

private Long id; 
private String name; 
private Date dob; 
//About 10 more fields 
private List<Pet> pets; 

:ペットのための

private String id; 
private String name; 
private Customer owner; 

私のデータベーステーブルは、今私が気付いている場合、この

id BIGSERIAL PRIMARY KEY, 
name VARCHAR(20), 
owner_id BIGSERIAL REFERENCES... 

のように見えます私は2つのテーブルを結合するクエリを実行し、私は "フラット"データ構造を返すwhiを得るchにはCustomerPetの両方のフィールドと外部キーが含まれています。このシナリオでデータを処理するための共通の/最も効率的な方法は何ですか?

a。 customer.setName(resultSet.getString(("name")) ...を呼び出して手動でオブジェクトグラフを再構築しますか?
b。返されたデータは、そのままMap<String, Object>に変換して使用しますか?

データは次のとおりです。データはデータベースから読み込まれ、AngularJSフロントエンドで使用するためにJSONにレンダリングされます。>変更されたデータは検証のためにサーバーに送り返されます>ドメインロジックが適用されます>データベースに保存されます。

+0

列 'テーブルのid'' Pet'ある 'BIGSERIAL'、なぜならばフィールド 'id'は' String'ですか?それは「長い」ものでなければなりません。また、テーブル 'Pet'は' BIGSERIAL'という2つのカラムを持つべきではありません。 – Andreas

+0

これは単なる説明のためのものです。実際のスキーマはずっと穏やかで一貫しています。 – kshep92

答えて

1

あなたは、パフォーマンスを向上させるために、単一のクエリ内の両方のお客様とペットを読みたい場合は、このような何かを行うことができます。

List<Customer> customers = new ArrayList<>(); 
String sql = "SELECT c.id AS cust_id" + 
        ", c.name AS cust_name" + 
        ", c.dob AS cust_dob" + 
        ", p.id AS pet_id" + 
        ", p.name AS pet_name" + 
       " FROM Customer c" + 
       " LEFT JOIN Pet p ON p.owner_id = c.id" + 
      " WHERE c.name LIKE ?" + 
      " ORDER BY c.id"; 
try (PreparedStatement stmt = conn.prepareStatement(sql)) { 
    stmt.setString(1, "%DOE%"); 
    try (ResultSet rs = stmt.executeQuery()) { 
     Customer customer = null; 
     while (rs.next()) { 
      long cust_id = rs.getLong("cust_id"); 
      if (customer == null || customer.getId() != cust_id) { 
       customer = new Customer(); 
       customer.setId(cust_id); 
       customer.setName(rs.getString("cust_name")); 
       customer.setDob(rs.getDate("cust_dob")); 
       customers.add(customer); 
      } 
      long pet_id = rs.getLong("pet_id"); 
      if (pet_id != 0) { 
       Pet pet = new Pet(); 
       pet.setId(pet_id); 
       pet.setName(rs.getString("pet_name")); 
       pet.setOwner(customer); 
       customer.addPet(pet); 
      } 
     } 
    } 
} 
+0

オンラインで数日の検索をしたところ、これは長い道のり(そして私が最も遠ざかることを望んでいたやり方)であると思われますが、他の人たちがやっているようです。手動のオブジェクト・リレーショナル・マッピングはちょっと面倒ですが、時にはそれが必要だと思います。 これを承認済みとしてマークします。 – kshep92

+1

オブジェクト*への手動マッピングは面倒です。そのためORMが発明されたのはこのためです。ORMで列をフィールドにマップする必要がない場合は、自分で行う必要があります。つまり、ORM(Object-Relational Mapping)と呼ばれています。 – Andreas

+0

SQL生成物や外部XML設定ファイルが必要ない場合は、もっと頻繁に使用します。 – kshep92

1

この時点で最良のオプションは以下のとおりです。

  1. 春JDBC(それはなどのマッピングをobjectに豆のようなORMの利便性を持っている)
  2. iBatisのは(それがORMですが、手動でSQLクエリを記述することができますが、薄いレイヤー)
  3. 独自のDAOレイヤの実装を記述します。

これらのすべてのケースでは、独自のSQLクエリを作成し、ほとんどが結合クエリになります。ところで、あなたが与えた例はネストしたオブジェクトではありません。

+0

Sql2oのようなツールはどうですか?それを使ったことがありますか? – kshep92

+0

私はそれを使用していませんが、それを見て、それは基準のクエリの小さなバージョンと思われる。ところで、私は既存のデータベースのほとんどがDependency Injection(疎結合)であることと、チェックされていない例外と非常に明確な例外階層を持っているため、Spring JDBCを好んでいます。正確なSQLExceptionがどのように発生したかを明確に示すことができます。 – amitmah

関連する問題