搜索多个表并返回/映射动态结果集

时间:2011-11-28 02:55:17

标签: java spring jdbctemplate

我有一个名为Contacts的mySql架构,其中包含4个表:Contacts,Phone,Email和Addresses。 “联系人”表包含有关人员的基本信息,例如ID号,名字和姓氏。其他表都包含一个将其链接到Contacts表的外键,例如,Contacts表中的John Doe可以在Phones表中有多个电话号码,可以使用John Doe的id号进行搜索。

我的问题是如何查询此架构并返回单个(或多个)用户的所有数据。是否可以使用一个SQL语句完成,或者我是否需要根据从Contacts表返回的每一行返回的结果数量不匹配的事实联系每个表的数据库。例如,我有一些基本搜索功能,可根据搜索条件在Contacts表中搜索一行或多行:

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);
}
}

我使用spring查询并将结果映射回Contact bean。我将如何修改此SQL语句和映射功能以搜索联系人表,获取每行的数据,然后根据每个返回行的ID,还查询电话,电子邮件和地址表,然后将这些表映射到存储在bean中的List对象?问题是第1行的id可能会找到8个与id匹配的电话号码行,但第2行的id可能只能找到3个电话号码。这将如何存储在ResultSet中?或者我是否必须首先查询Contacts表,然后对每个其他表(对于从第一个表返回的每一行)执行单独的查询,并将该数据逐个添加到bean中?如果第一个查询返回100个结果,并且我必须对3个表中的每个查询执行查询,那么我将查看301次数据库并返回。

是否可以使用一个查询,只返回每个电话,电子邮件地址表中的1个结果,以查找在Contacts表中找到的每个结果?也许我可以添加一个主列或其他东西,这样它只返回1个结果然后如果用户点击某些内容来请求有关结果的更多信息,它可以执行其他查询并收集有关该用户的所有信息。

1 个答案:

答案 0 :(得分: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

我在Phone,Email和Address数据库中创建了一个名为Primary的列,其中包含一个布尔值,因此在我的初始查询中,我只会为数据库中的每个Contact返回1个结果。到目前为止,这正在做我需要的。不确定这是否是正确的方法?