创建一个自定义映射器,它将使用数据库中的行直到 id 更改
To create a custom mapper which will consume rows from DB until the id changes
我在处理我的 JDBC 项目,我需要从 ResultSet 中获取对象。
这是我的 getAll() 方法
public List<Person> getAll() throws DaoException {
List<Person> persons = new ArrayList<>();
try (Connection connection = connectionProvider.getConnection();
PreparedStatement statement = connection.prepareStatement(getQueryToGetAll(), Statement.RETURN_GENERATED_KEYS)) {
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
students.add(mapper.mapRow(resultSet)); // here I get person from the mapper
}
return persons;
} catch (
SQLException e) {
throw new DaoException("Couldn't get all persons" + persons, e);
}
}
我的模型 Person 有字段集:
class Person {
private int id;
private String name;
private Set<Activity> activities;
}
我还需要使用单个连接查询从 ResiltSet 获取这个集合。
我对数据库的查询得到了下一个数据:
link
所以我的问题是我的映射器不能正常工作。它应该消耗行,直到 person_id 更改为生成单个 Person 实例。
映射器方法:
public Person mapRow(ResultSet resultSet) throws SQLException {
Integer id = resultSet.getInt("person_id");
String name= resultSet.getString("person_name");
Set<Activity> activities = new HashSet<>();
do {
Integer activityId = resultSet.getInt("activity_id");
String activityName = resultSet.getString("activity_name");
activities.add(new Activity(activityId, activityName));
} while (resultSet.next() && id.equals(resultSet.getInt("person_id")));
return new Person(id, name, activities);
}
尝试这样的事情:
public List<Person> getAll() throws DaoException {
Map<Integer, Person> personMap = new HashMap<>();
try (Connection connection = connectionProvider.getConnection();
PreparedStatement statement = connection.prepareStatement(getQueryToGetAll(), Statement.RETURN_GENERATED_KEYS)) {
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
mapper.appOrUpdatePersonFromRow(resultSet, personMap); // here I get person from the mapper
}
return new ArrayList<>(personMap.values());
} catch (
SQLException e) {
throw new DaoException("Couldn't get all persons" + new ArrayList<>(personMap.values()), e);
}
}
public void appOrUpdatePersonFromRow(ResultSet resultSet, Map<Integer, Person> personMap) throws SQLException {
Person person = getOrCreatePerson(resultSet, personMap);
Integer activityId = resultSet.getInt("activity_id");
String activityName = resultSet.getString("activity_name");
person.getActivities().add(new Activity(activityId, activityName));
}
public Person getOrCreatePerson(ResultSet resultSet, Map<Integer, Person> personMap) {
Integer id = resultSet.getInt("person_id");
if(!personMap.containsKey(id)) {
String name= resultSet.getString("person_name");
Person person = new Person(id, name, new HashSet<>());
personMap.put(id, person);
}
return personMap.get(id);
}
我在处理我的 JDBC 项目,我需要从 ResultSet 中获取对象。
这是我的 getAll() 方法
public List<Person> getAll() throws DaoException {
List<Person> persons = new ArrayList<>();
try (Connection connection = connectionProvider.getConnection();
PreparedStatement statement = connection.prepareStatement(getQueryToGetAll(), Statement.RETURN_GENERATED_KEYS)) {
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
students.add(mapper.mapRow(resultSet)); // here I get person from the mapper
}
return persons;
} catch (
SQLException e) {
throw new DaoException("Couldn't get all persons" + persons, e);
}
}
我的模型 Person 有字段集:
class Person {
private int id;
private String name;
private Set<Activity> activities;
}
我还需要使用单个连接查询从 ResiltSet 获取这个集合。
我对数据库的查询得到了下一个数据: link
所以我的问题是我的映射器不能正常工作。它应该消耗行,直到 person_id 更改为生成单个 Person 实例。
映射器方法:
public Person mapRow(ResultSet resultSet) throws SQLException {
Integer id = resultSet.getInt("person_id");
String name= resultSet.getString("person_name");
Set<Activity> activities = new HashSet<>();
do {
Integer activityId = resultSet.getInt("activity_id");
String activityName = resultSet.getString("activity_name");
activities.add(new Activity(activityId, activityName));
} while (resultSet.next() && id.equals(resultSet.getInt("person_id")));
return new Person(id, name, activities);
}
尝试这样的事情:
public List<Person> getAll() throws DaoException {
Map<Integer, Person> personMap = new HashMap<>();
try (Connection connection = connectionProvider.getConnection();
PreparedStatement statement = connection.prepareStatement(getQueryToGetAll(), Statement.RETURN_GENERATED_KEYS)) {
ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
mapper.appOrUpdatePersonFromRow(resultSet, personMap); // here I get person from the mapper
}
return new ArrayList<>(personMap.values());
} catch (
SQLException e) {
throw new DaoException("Couldn't get all persons" + new ArrayList<>(personMap.values()), e);
}
}
public void appOrUpdatePersonFromRow(ResultSet resultSet, Map<Integer, Person> personMap) throws SQLException {
Person person = getOrCreatePerson(resultSet, personMap);
Integer activityId = resultSet.getInt("activity_id");
String activityName = resultSet.getString("activity_name");
person.getActivities().add(new Activity(activityId, activityName));
}
public Person getOrCreatePerson(ResultSet resultSet, Map<Integer, Person> personMap) {
Integer id = resultSet.getInt("person_id");
if(!personMap.containsKey(id)) {
String name= resultSet.getString("person_name");
Person person = new Person(id, name, new HashSet<>());
personMap.put(id, person);
}
return personMap.get(id);
}