当前位置: 首页 > 知识库问答 >
问题:

当我按ID获取行时,如何修复“不正确的结果大小:应为1,实际为0”?

黎同
2023-03-14

上下文:

我的数据库中有很多表。我在java中没有显式的实体类,但我将有关列和值的信息存储在一个特殊的类中,如下所示:

public class Spravochnik extends BaseEntity {  
    private List<String> columnName;
    private List<List<String>> valuesInRows;
    public List<String> getColumnName() {
        return columnName;
    }
    public void setColumnName(List<String> columnName) {
        this.columnName = columnName;
    }
    public List<List<String>> getValuesInRows() {
        return valuesInRows;
    }
    public void setValuesInRows(List<List<String>> valuesInRows) {
        this.valuesInRows = valuesInRows;
    }   
}

Base Entity只有一个id,因为我所有的表都有一个id,这里是所有其他字段(列名)和按行插入的所有值(行中的值是一行中的值列表包装在另一个列表中,以获取行列表,而行列表又是其中的值列表)。我还有一个行映射器:

public class SpravochnikRowMapper implements RowMapper<Spravochnik> {
    @Override
    public Spravochnik mapRow(ResultSet rs, int arg1) throws SQLException {
        Spravochnik spr = new Spravochnik();
        ResultSetMetaData rsmeta = rs.getMetaData();
        List<String> columnNames = new ArrayList<>();
        List<List<String>> valuesInRows = new ArrayList<List<String>>();
        int columnCount = rsmeta.getColumnCount();

        for(int column = 1; column <= columnCount; column++){
            columnNames.add(rsmeta.getColumnName(column));
        }
        spr.setColumnName(columnNames);
        
        do {
            List<String> values = new ArrayList<>();
            for(int column = 1; column <= columnCount; column++){
                values.add(rs.getString(column));
            }
            
            valuesInRows.add(values);
        }while(rs.next());
        spr.setValuesInRows(valuesInRows);

        return spr;
    }
}

因此,我有一种方法可以根据其id获取一行(是的,起初我从另一种形式的id中获取一种形式的id,但它不是那么重要):

    @Override
    public Spravochnik selectOne(String id) {
        return spravochnikDao.selectOne(getSpravId(id), getRowId(id) );
    }
    
    protected int getSpravId(String id) {
        return Integer.valueOf(id.substring(0, 3));
    }
    
    protected int getRowId(String id) {
        return Integer.valueOf(id);
    }

所以在道器中实际有问题的方法:

    @Override
    public Spravochnik selectOne(int spravochnikId, int rowId) {
        return jdbctemplate.queryForObject(getQueryDinamicTable(SQL_SELECT_ROW, getSpravNameAtId(spravochnikId)),
                new SpravochnikRowMapper(), rowId);
    }

问题是,它适用于包含2列的表(id和另一个;我的所有表都满足这一点,除了一个),但是当我试图从只有3列的表中获取一行时,它说

org . spring framework . Dao . emptyresultdataaccessexception:结果大小不正确:应为1,实际为0。同样,当我从一个有2列的表中获取一行时,它工作得很好,而当有3列时就不行了。我猜问题出在rowmapper或者方法本身。如果您需要额外的信息,请随时询问,并提前感谢大家!

共有1个答案

长孙德惠
2023-03-14

将为每一行调用mapRow方法。因此,执行rs.next()不是一个好的做法。您可以像下面这样重写映射器:

public class SpravochnikRowMapper implements RowMapper<Spravochnik> {

    private List<String> columnNames;
    private int columnCount;

    @Override
    public Spravochnik mapRow(ResultSet rs, int arg1) throws SQLException {
        Spravochnik spr = new Spravochnik();
        if (columnNames == null) {
            ResultSetMetaData rsmeta = rs.getMetaData();
            columnNames = new ArrayList<>();
            columnCount = rsmeta.getColumnCount();
            for(int column = 1; column <= columnCount; column++){
                columnNames.add(rsmeta.getColumnName(column));
            }

        }

        List<List<String>> valuesInRows = new ArrayList<List<String>>();
        spr.setColumnName(columnNames);

        List<String> values = new ArrayList<>();
        for(int column = 1; column <= columnCount; column++){
            values.add(rs.getString(column));
        }

        valuesInRows.add(values);
        spr.setValuesInRows(valuesInRows);
        return spr;
    }
}
 类似资料: