2013-05-09 21 views
7

私はこのようなクラスを持っています。私は、以下に示す2つのデータベーステーブルからそれを設定する必要があります。これを行うための好ましい方法はありますか?JDBCテンプレート - 1対多

私はDAOからResultSetExtractorList<>を選択するサービスクラスを考えています。その後、そのリストにforeachを追加し、別のResultSetExtractorを介して個人のメールのList<>を選択し、foreachループから添付します。

良い方法がありますか、それとも得意なのですか?

public class Person { 
    private String personId; 
    private String Name; 
    private ArrayList<String> emails; 
} 


create table Person (
    person_id varchar2(10), 
    name  varchar2(30) 
); 


create table email (
    person_id varchar2(10), 
    email  varchar2(30) 
); 

答えて

10

これはORMによって最もよく解決されます。 JDBCでは、ORMが何をするのか手作業で行う必要があります。 N + 1回のクエリを実行するのは非常に非効率的です。単一のクエリを実行し、オブジェクトを手動で構築する必要があります。面倒ですが、ハードではありません:

select person.id, person.name, email.email from person person 
left join email on person.id = email.person_id 

... 

Map<Long, Person> personsById = new HashMap<>(); 
while (rs.next()) { 
    Long id = rs.getLong("id"); 
    String name = rs.getString("name"); 
    String email = rs.getString("email"); 
    Person person = personsById.get(id); 
    if (person == null) { 
     person = new Person(id, name); 
     personsById.put(person.getId(), person); 
    } 
    person.addEmail(email); 
} 
Collection<Person> persons = personsById.values(); 
+0

これは素晴らしいです。以前のプロジェクトでこれをやり遂げて欲しいです。最後の行が何をしているのか教えていただけますか?私はその部分に従うかどうか分からない。 – EdgeCase

+0

クエリの結果としておそらく望むものは 'Map 'ではなく、人物の集まりなので、マップから値を取得するだけです。詳細については 'Map.values()'のjavadocを読んでください。 –

+1

または、 'java.util.Set ' を使用できます。ここで 'class Person {public boolean equals(Object o){return id ==(Person)o.id; public int hashCode(){戻り値id.hashCode(); 'Map.values()'の呼び出しを避けることができます。これは、パフォーマンスと可読性の目的でもっと望ましいかもしれません。 – juanchito