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



我有一个从数据库中提取数据的问题。我有以下表在我的数据库

TABLE USER,属性ID和USERNAME,例如

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

TABLE FRUIT,属性FRUITID和NAME,例如

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

TABLE CONSUMATION,属性UID引用USER。ID, FID引用FRUIT。主键(uid, fid),例如

[ 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

对于每个用户,应该创建一个对象,并且它的消费值应该保存在他的映射中。例如

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;
    }
}
}

那么如何实现这一点呢?我将感激任何帮助谢谢你!

这取决于什么不能工作。总的来说,ResultSetExtractor的流程和用法是正确的。我看到的是,您没有聚合用户—继续为结果集中的每一行创建新的User。为此,您可以使用RowMapper。但是,如果使用ResultSetExtractor为每个用户创建单行,则需要始终检查列表是否已经包含该用户,并只使用新水果更新他的水果映射,而不是创建新用户。

相关内容

  • 没有找到相关文章

最新更新