Глава 12. Объектно-реляционные типовые решения... 281
if (!inProgress.keyset() .contains (ID))
inProgress.put(ID, sourceMapper.loadRow(ID, rs) ) ;
targetAdder.add((DomainObject) inProgress.get (ID), rs); } }
class AbstractMapper...
boolean hasLoaded(Long id) {
return loadedMap.containsKey(id) ; }
Загрузчик сохраняет порядок строк результирующего множества данных, поэтому
выходной список служащих будет отсортирован так же, как и ранее. Таким образом, я
буду вести список идентификаторов служащих в той последовательности, в которой
они ко мне поступают. Переходя к очередному идентификатору, я проверяю, был ли
соответствующий объект полностью загружен в преобразователь (как правило, в соот-
ветствии с результатами предыдущего запроса). Если это не так, я загружаю те данные,
которые у меня есть, и сохраняю идентификатор в списке идентификаторов служащих,
находящихся в состоянии загрузки. Подобный список нужен на тот случай, если
сведения о профессиональных качествах служащего будут состоять из нескольких строк,
не идущих последовательно одна задругой.
Самое сложное в написании всего этого кода — гарантировать, что я смогу добавить
профессиональное качество, которое загружается в список профессиональных качеств
служащих, и одновременно сохранить загрузчик универсальным, чтобы он не зависел от
служащих или их профессиональных качеств. Для этого мне пришлось изрядно поко-
паться в своих "закромах", чтобы извлечь оттуда внутренний интерфейс по имени Adder.
class AssociationTableLoader...
public static interface Adder {
void add(DomainObject host, ResultSet rs)
throws SQLException;
}
Объект, вызывающий метод поиска, должен реализовать интерфейс Adder, чтобы
привязать его к конкретным потребностям объекта служащего или профессионального
качества.
class EmployeeMapper...
private static class SkillAdder implements
AssociationTableLoader.Adder {
public void add(DomainObject host, ResultSet rs)
throws SQLException {
Employee emp = (Employee) host;
Long skillld = new Long (rs.getLong("skillld"));
emp.addSkill((Skill) MapperRegistry.skill().loadRow( skillld,
rs));
} }