Java Iterator backed by a ResultSet

后端 未结 17 745
清歌不尽
清歌不尽 2020-12-13 06:51

I\'ve got a class that implements Iterator with a ResultSet as a data member. Essentially the class looks like this:

public class A implements Iterator{
            


        
17条回答
  •  旧时难觅i
    2020-12-13 07:27

    This is a bad idea. This approach requires that the connection is open the whole time until the last row is read, and outside the DAO layer you never know when it will happen, and you also seem to leave the resultset open and risk resource leaks and application crashes in the case the connection times out. You don't want to have that.

    The normal JDBC practice is that you acquire Connection, Statement and ResultSet in the shortest possible scope. The normal practice is also that you map multiple rows into a List or maybe a Map and guess what, they do have an Iterator.

    public List list() throws SQLException {
        List list = new ArrayList();
    
        try (
            Connection connection = database.getConnection();
            Statement statement = connection.createStatement("SELECT id, name, value FROM data");
            ResultSet resultSet = statement.executeQuery();
        ) {
            while (resultSet.next()) {
                list.add(map(resultSet));
            }
        }
    
        return list;
    }
    
    private Data map(ResultSet resultSet) throws SQLException {
        Data data = new Data(); 
        data.setId(resultSet.getLong("id"));
        data.setName(resultSet.getString("name"));
        data.setValue(resultSet.getInteger("value"));
        return data;
    }
    

    And use it as below:

    List list = dataDAO.list(); 
    int count = list.size(); // Easy as that.
    Iterator iterator = list.iterator(); // There is your Iterator.
    

    Do not pass expensive DB resources outside the DAO layer like you initially wanted to do. For more basic examples of normal JDBC practices and the DAO pattern you may find this article useful.

提交回复
热议问题