【发布时间】:2011-11-28 02:55:17
【问题描述】:
我有一个名为 Contacts 的 mySql 架构,其中包含 4 个表:联系人、电话、电子邮件和地址。联系人表包含一个人的基本信息,例如身份证号码、名字和姓氏。其他表都包含将其链接到 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 个结果?也许我可以添加一个主列或其他内容,以便它只返回 1 个结果,然后如果用户单击某些内容以请求有关结果的更多信息,它可以执行其他查询并收集有关该用户的所有信息。
【问题讨论】:
-
你使用Ibatis作为sql Adapter吗?如果是,您可以使用“具有复杂属性的结果映射”将结果映射上的一个属性存储为列表。
标签: java spring jdbctemplate