使用ResultSetExtractor或RowMapper从数据库中提取数据

时间:2014-03-18 13:12:40

标签: hsqldb resultset jdbctemplate

我有一个从数据库中提取数据的探针。我的数据库中有以下表格

TABLE USER,属性ID和USERNAME, 例如

[ ID | USERNAME ]
[ 1  | John     ]
[ 2  | Jane     ]

TABLE FRUIT,属性FRUITID和NAME, e.g。

[ FRUITID | NAME     ]
[ 1       | Apple    ]
[ 2       | Pear     ]

TABLE CONSUMATION,属性UID引用USER.ID,FID引用FRUIT.FRUITID和QUANTITY,PRIMARY KEY(uid,fid), e.g。

[ UID | FID | QUANTITY ]
[ 1   |  1  | 1        ]
[ 1   |  2  | 2        ]
[ 2   |  1  | 1        ]

我试图从数据库中提取的模型用户

public class User {

private int userId;
private String userName;
private Map<Fruit, Integer> fruits;

public User() {
    fruits = new HashMap<Fruit, Integer>();
}

public User(int userId) {
    this.userId = userId;
    fruits = new HashMap<Fruit, Integer>();
}

public User(int userId, String userName) {
    this.userId = userId;
    this.userName = userName;
    fruits = new HashMap<Fruit, Integer>();
}

public int getUserId() {
    return userId;
}

public void setUserId(int userId) {
    this.userId = userId;
}

public Map<Fruit, Integer> getFruits() {
    return fruits;
}

public void setFruits(Map<Fruit, Integer> fruits) {
    this.fruits = fruits;
}

public String getUserName() {
    return userName;
}

public void setUserName(String userName) {
    this.userName = userName;
}
}

我使用此查询从数据库中选择数据

SELECT * FROM USERS U LEFT JOIN CONSUMATION C ON (U.ID = C.UID)

在我执行它之后,我得到了这些值,如下图所示 http://s30.postimg.org/4bbu3q9oh/image.png

对于每个用户,应该创建一个对象,并且它的消耗值应该保存在他的地图中。 e.g。

USER: ID:1 USERNAME: "Amer"    FRUITS: (FRUITID: 1 Q:1); (FRUITID 2 Q:2)
USER: ID:2 USERNAME: "Nina"    FRUITS: (FRUITID: 3 Q:2)
USER: ID:3 USERNAME: "Viktor"  FRUITS: 

我正在使用Spring JdbcTemplate,这是我到目前为止所尝试的。不幸的是,它没有工作......

@Component
public class UserDaoImpl {

private DataSource dataSource;

private JdbcTemplate jdbcTemplate;

public User getUser(int userId) {
    String sql = "SELECT * FROM USERS WHERE id = ?";
    return jdbcTemplate.queryForObject(sql, new Object[] {userId}, new UserMapper());
}

public List<User> getAllUsers() {
    String sql = "SELECT * FROM USERS U LEFT JOIN CONSUMATION C ON (U.ID = C.UID)";
    return jdbcTemplate.query(sql, new MyUserExtractor());
}

public DataSource getDataSource() {
    return dataSource;
}

@Autowired
public void setDataSource(DataSource dataSource) {
    jdbcTemplate = new JdbcTemplate(dataSource);
}

public JdbcTemplate getJdbcTemplate() {
    return jdbcTemplate;
}

public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
    this.jdbcTemplate = jdbcTemplate;
}

private static final class UserMapper implements RowMapper<User> {

    @Override
    public User mapRow(ResultSet resultSet, int rowNum) throws SQLException {
        User user = new User();
        user.setUserId(resultSet.getInt("ID"));
        user.setUserName(resultSet.getString("USERNAME"));
        return user;
    }

}

private static final class MyUserExtractor implements ResultSetExtractor {

    @Override
    public Object extractData(ResultSet rs) throws SQLException,
    DataAccessException {
        ArrayList<User> users = new ArrayList<User>();
        while(rs.next()) {
            User user = new User();

            HashMap<Fruit, Integer> fruits = new HashMap<Fruit, Integer>();
            user.setUserId(rs.getInt("ID"));
            user.setUserName(rs.getString("USERNAME"));
            fruits.put(new Fruit(rs.getInt("FID")), rs.getInt("QUANTITY"));
            user.setFruits(fruits);
            users.add(user);
        }                       
        return users;
    }
}

}

那么如何实现这一目标呢?我会感激任何帮助 谢谢!

1 个答案:

答案 0 :(得分:1)

这取决于什么不具体。通常,ResultSetExtractor的流程和用法是正确的。我可以看到你没有聚合用户 - 继续为结果集中的每一行创建新用户。为此,您可以使用RowMapper。但是,如果您使用ResultSetExtractor为每个用户创建单行,则需要始终检查您的列表是否已包含用户,并仅使用新水果更新他的水果图,而不是创建新用户。