使用 Spring RowMapper 以从 JDBC 结果集中填充 Collection 类型的字段
Using a Spring RowMapper in order to populate a field of type Collection from a JDBC resultset
我正在尝试使用 Spring RowMapper
将 JDBC ResultSet
映射到 POJO,如下所示:
public class AdvertisementMapper implements RowMapper<Advertisement> {
@Override
public Advertisement mapRow(ResultSet rs, int rowNum) throws SQLException {
Advertisement advertisement = new Advertisement();
advertisement.setId(rs.getLong("id"));
advertisement.setAdvertisementType(AdvertisementType.valueOf(rs.getString("advertisement_type")));
advertisement.setNeed(Need.valueOf(rs.getString("need")));
advertisement.setChildcareWorkerType(ChildcareWorkerType.valueOf(rs.getString("childcare_worker_type")));
advertisement.setChildcareTypes(null);//COLLECTION!
advertisement.setDayToTimeSlots(null);//COLLECTION!
advertisement.setLanguages(null);//COLLECTION!
advertisement.setDescription(rs.getString("description"));
advertisement.setCreationDate(rs.getDate("creation_date"));
advertisement.setExpirationDate(rs.getDate("expiration_date"));
advertisement.setActive(rs.getBoolean("active"));
advertisement.setValidated(rs.getBoolean("validated"));
Member member = new Member();
member.setId(rs.getLong("memberId"));
advertisement.setMember(member);
Address address = new Address();
address.setLat(rs.getDouble("addressLat"));
address.setLon(rs.getDouble("addressLon"));
advertisement.setAddress(address);
advertisement.setFirstAidTraining(Choice.valueOf(rs.getString("first_aid_training")));
advertisement.setGiveBath(Choice.valueOf(rs.getString("give_bath")));
advertisement.setPrepareMeals(Choice.valueOf(rs.getString("prepare_meals")));
advertisement.setHelpWithHomework(Choice.valueOf(rs.getString("help_with_homework")));
advertisement.setCleaningIroning(Choice.valueOf(rs.getString("cleaning_ironing")));
advertisement.setVersion(rs.getInt("version"));
return advertisement;
}
}
我对以下类型的三个字段有疑问:java.util.Set
(我在上面的 java 代码中向它们添加了 //COLLECTION!
注释。)
这里是 SQL:
SELECT * FROM
advertisement a,
advertisement_childcare_types act,
advertisement_day_to_time_slots adtts,
day_to_time_slot dtts,
advertisement_languages al,
language l
WHERE
a.id = act.advertisement AND
a.id = adtts.advertisement AND
adtts.day_to_time_slots = dtts.id AND
a.id = al.advertisement AND
al.languages = l.id
我不确定如何从 ResultSet
...
中填充集合/java.util.Set
字段
有人可以帮忙吗?
由于您没有从结果集中的行到 Advertisement
个实例的一对一映射,因此您将无法使用 RowMapper
执行此操作。您将需要使用 RowCallbackHandler or a ResultSetExtractor<List<Advertisement>>
。 RowCallbackHandler
的优点是您不需要处理调用 next()
.
这是一个非线程安全的,不是超级高效,但清晰的实现:
class AdvertisementRowcallbackHandler implements RowCallbackHandler {
Map<Long, Advertisement> results = new HashMap<>();
@Override
void processRow(ResultSet rs) SQLException {
long id = rs.getLong("id");
Advertisement advertisement = new Advertisement();
advertisement.setChildcareWorkerTypes(new HashSet<>());
results.putIfAbsent(id, advertisement);
advertisement = results.get(id);
// You could be smart about only setting these if it was absent in the map
advertisement.setId(id);
advertisement.setDescription(rs.getString("description"));
advertisement.getChildcareWorkerTypes().add(rs.getString("worker_type"));
// ...
}
}
然后你会得到 new ArrayList<>(handler.results.values())
的结果。
我正在尝试使用 Spring RowMapper
将 JDBC ResultSet
映射到 POJO,如下所示:
public class AdvertisementMapper implements RowMapper<Advertisement> {
@Override
public Advertisement mapRow(ResultSet rs, int rowNum) throws SQLException {
Advertisement advertisement = new Advertisement();
advertisement.setId(rs.getLong("id"));
advertisement.setAdvertisementType(AdvertisementType.valueOf(rs.getString("advertisement_type")));
advertisement.setNeed(Need.valueOf(rs.getString("need")));
advertisement.setChildcareWorkerType(ChildcareWorkerType.valueOf(rs.getString("childcare_worker_type")));
advertisement.setChildcareTypes(null);//COLLECTION!
advertisement.setDayToTimeSlots(null);//COLLECTION!
advertisement.setLanguages(null);//COLLECTION!
advertisement.setDescription(rs.getString("description"));
advertisement.setCreationDate(rs.getDate("creation_date"));
advertisement.setExpirationDate(rs.getDate("expiration_date"));
advertisement.setActive(rs.getBoolean("active"));
advertisement.setValidated(rs.getBoolean("validated"));
Member member = new Member();
member.setId(rs.getLong("memberId"));
advertisement.setMember(member);
Address address = new Address();
address.setLat(rs.getDouble("addressLat"));
address.setLon(rs.getDouble("addressLon"));
advertisement.setAddress(address);
advertisement.setFirstAidTraining(Choice.valueOf(rs.getString("first_aid_training")));
advertisement.setGiveBath(Choice.valueOf(rs.getString("give_bath")));
advertisement.setPrepareMeals(Choice.valueOf(rs.getString("prepare_meals")));
advertisement.setHelpWithHomework(Choice.valueOf(rs.getString("help_with_homework")));
advertisement.setCleaningIroning(Choice.valueOf(rs.getString("cleaning_ironing")));
advertisement.setVersion(rs.getInt("version"));
return advertisement;
}
}
我对以下类型的三个字段有疑问:java.util.Set
(我在上面的 java 代码中向它们添加了 //COLLECTION!
注释。)
这里是 SQL:
SELECT * FROM
advertisement a,
advertisement_childcare_types act,
advertisement_day_to_time_slots adtts,
day_to_time_slot dtts,
advertisement_languages al,
language l
WHERE
a.id = act.advertisement AND
a.id = adtts.advertisement AND
adtts.day_to_time_slots = dtts.id AND
a.id = al.advertisement AND
al.languages = l.id
我不确定如何从 ResultSet
...
java.util.Set
字段
有人可以帮忙吗?
由于您没有从结果集中的行到 Advertisement
个实例的一对一映射,因此您将无法使用 RowMapper
执行此操作。您将需要使用 RowCallbackHandler or a ResultSetExtractor<List<Advertisement>>
。 RowCallbackHandler
的优点是您不需要处理调用 next()
.
这是一个非线程安全的,不是超级高效,但清晰的实现:
class AdvertisementRowcallbackHandler implements RowCallbackHandler {
Map<Long, Advertisement> results = new HashMap<>();
@Override
void processRow(ResultSet rs) SQLException {
long id = rs.getLong("id");
Advertisement advertisement = new Advertisement();
advertisement.setChildcareWorkerTypes(new HashSet<>());
results.putIfAbsent(id, advertisement);
advertisement = results.get(id);
// You could be smart about only setting these if it was absent in the map
advertisement.setId(id);
advertisement.setDescription(rs.getString("description"));
advertisement.getChildcareWorkerTypes().add(rs.getString("worker_type"));
// ...
}
}
然后你会得到 new ArrayList<>(handler.results.values())
的结果。