2013-05-09 39 views
7

我有一個看起來像這樣的類。我需要從兩個數據庫表中填充它,這也在下面顯示。有沒有任何首選的方法來做到這一點?JDBC模板 - 一對多

我的想法是有一個服務類,通過從DAO的ResultSetExtractor選擇List<>。然後在該列表上執行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 2013-05-09 17:02:02

+0

它只是從地圖獲取值,因爲您可能想要作爲查詢的結果是人的集合,而不是'Map '。閱讀'Map.values()'的javadoc以獲取更多細節。 – 2013-05-09 17:07:42

+1

或者你可以使用 'java.util.Set ' 其中'class Person {public boolean equals(Object o){return id ==(Person)o.id; public int hashCode(){return id.hashCode(); }}'這樣可以避免調用'Map.values()',這對於性能和可讀性來說可能更加理想。 – juanchito 2014-08-19 19:53:12