2011-11-28 64 views
1

我有一個名爲Contacts的mySql模式,它包含4個表格:聯繫人,電話,電子郵件和地址。聯繫人表格包含有關人員的基本信息,如身份證號碼,名字和姓氏。其他表都包含一個將其鏈接到聯繫人表的外鍵,例如,聯繫人表中的John Doe可以在電話表中包含多個電話號碼,這些電話號碼都可以使用John Doe的ID號進行搜索。搜索多個表並返回/映射動態結果集

我的問題是如何查詢此模式並返回單個(或多個)用戶的所有數據。可以使用一個SQL語句完成,還是需要根據每個單獨的表聯繫數據庫,這是基於從聯繫人表返回的每一行返回的結果數量不匹配這一事實。例如,我有一個基於搜索條件搜索聯繫人表中的一行或多行的一些基本搜索功能:我使用的春天來查詢和結果映射回跟豆

public class ContactsListDAO { 
//Constants 
private static final String SQL_FIND_BY_SEARCH_CRITERIA = "SELECT * FROM Contacts.Contacts WHERE Id LIKE :searchString OR FirstName LIKE :searchString OR LastName LIKE :searchString"; 

//Variables 
private DAOFactory daoFactory; 
private NamedParameterJdbcTemplate namedParameterJdbcTemplate; 

//Constructors 
public ContactsListDAO(DAOFactory daoFactory) { 
    this.daoFactory = daoFactory; 
    this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(daoFactory.getDataSource()); 
} 

public List<Contact> findSearchResults(String searchCriteria) { 
    Map<String, String> namedParameters = Collections.singletonMap("searchString", searchCriteria); 

    RowMapper<Contact> mapper = new RowMapper<Contact>() { 
     @Override 
     public Contact mapRow(ResultSet resultSet, int row) throws SQLException { 
      Contact contact = new Contact(
        resultSet.getInt("Id"), 
        resultSet.getString("FirstName"), 
        resultSet.getString("LastName") 
       ); 
      return contact; 
     }   
    }; 

    return namedParameterJdbcTemplate.query(SQL_FIND_BY_SEARCH_CRITERIA, namedParameters, mapper); 
} 
} 

。我將如何去修改這個SQL語句和映射功能來搜索聯繫人表,獲取每行的數據,然後根據每個返回行的ID,查詢電話,電子郵件和地址表,然後將這些映射到存儲在bean中的List對象?問題是第1行的ID可能會找到8個與ID匹配的電話號碼行,但第2行的ID可能只能找到3個電話號碼。這是如何存儲在ResultSet中的?或者我必須先查詢聯繫人表,然後對每個其他表(對於從第一個返回的每一行)執行一個單獨的查詢並將該數據逐個添加到bean中?如果第一個查詢返回100個結果,並且我必須爲3個表中的每個查詢執行查詢,則我正在查看301次到數據庫並返回。

是否有可能使用一個查詢,並返回每個電話號碼,電子郵件地址表中的1個結果,以查找聯繫人表中的每個結果?也許我可以添加主列或其他東西,所以它只返回1個結果,然後如果用戶點擊某些內容來請求更多關於結果的信息,它可以執行其他查詢並收集關於該用戶的所有信息。

+0

你使用Ibatis作爲sql adapter嗎?如果是,則可以使用「具有複雜屬性的結果圖」將結果圖上的一個屬性作爲列表存儲。 – Thinhbk

回答

0

查詢我想出了LEFT JOIN使用搜索表:

SELECT * FROM Contacts.Contacts LEFT JOIN Contacts.Phone ON Contacts.Id = Phone.ContactId AND Phone.Primary = 1 LEFT JOIN Contacts.Email ON Contacts.Id = Email.ContactId AND Email.Primary = 1 WHERE Contacts.Id LIKE :searchString OR Contacts.FirstName LIKE :searchString OR Contacts.LastName LIKE :searchString AND Contacts.OrganizationId = :organizationId 

我創建了一個叫做原發於電話,電子郵件一列,地址數據庫包含布爾讓我初始查詢我只會爲數據庫中的每個聯繫人返回1個結果。到目前爲止,這正在做我所需要的。不知道這是否是正確的方式去這樣的事情?