119

Jdbctemplateを使用して、データベースから単一の文字列値を取得しています。これが私の方法です。

    public String test() {
        String cert=null;
        String sql = "select ID_NMB_SRZ from codb_owner.TR_LTM_SLS_RTN 
             where id_str_rt = '999' and ID_NMB_SRZ = '60230009999999'";
        cert = (String) jdbc.queryForObject(sql, String.class); 
        return cert;
    }

私のシナリオでは、クエリにヒットしない可能性が完全にあるので、私の質問は、次のエラーメッセージを回避する方法です。

EmptyResultDataAccessException: Incorrect result size: expected 1, actual 0

例外をスローするのではなく、nullを取り戻す必要があるように思われます。どうすればこれを修正できますか?前もって感謝します。

4

18 に答える 18

199

JdbcTemplate 、queryForInt、 ではqueryForLongqueryForObjectそのようなすべてのメソッドは、実行されたクエリが 1 つの行のみを返すことを期待しています。行を取得しないか、複数の行を取得すると、IncorrectResultSizeDataAccessException. 正しい方法は、この例外または をキャッチしないEmptyResultDataAccessExceptionことですが、使用しているクエリが 1 行のみを返すようにしてください。まったく不可能な場合は、query代わりにメソッドを使用してください。

List<String> strLst = getJdbcTemplate().query(sql, new RowMapper<String>() {
    public String mapRow(ResultSet rs, int rowNum) throws SQLException {
        return rs.getString(1);
    }
});

if (strLst.isEmpty()) {
    return null;
} else if (strLst.size() == 1) { // list contains exactly 1 element
    return strLst.get(0);
} else { // list contains more than 1 element
         // either return 1st element or throw an exception
}
于 2012-05-16T05:46:11.900 に答える
25

制御フローの例外に依存しているため、これは良い解決策ではありません。あなたのソリューションでは、例外が発生するのは正常です。ログに記録されるのは正常です。

public String test() {
    String sql = "select ID_NMB_SRZ from codb_owner.TR_LTM_SLS_RTN where id_str_rt = '999' and ID_NMB_SRZ = '60230009999999'";
    List<String> certs = jdbc.queryForList(sql, String.class); 
    if (certs.isEmpty()) {
        return null;
    } else {
        return certs.get(0);
    }
}
于 2012-05-15T20:07:26.293 に答える
12

わかりました、私はそれを理解しました。私はそれをtry catchでラップし、nullを送り返しました。

    public String test() {
            String cert=null;
            String sql = "select ID_NMB_SRZ from codb_owner.TR_LTM_SLS_RTN 
                     where id_str_rt = '999' and ID_NMB_SRZ = '60230009999999'";
            try {
                Object o = (String) jdbc.queryForObject(sql, String.class);
                cert = (String) o;
            } catch (EmptyResultDataAccessException e) {
                e.printStackTrace();
            }
            return cert;
    }
于 2012-05-15T18:11:58.257 に答える
8

データがないときに null を返すことは、queryForObject を使用するときに頻繁に実行したいことなので、JdbcTemplate を拡張して、以下のような queryForNullableObject メソッドを追加すると便利であることがわかりました。

public class JdbcTemplateExtended extends JdbcTemplate {

    public JdbcTemplateExtended(DataSource datasource){
        super(datasource);
    }

    public <T> T queryForNullableObject(String sql, RowMapper<T> rowMapper) throws DataAccessException {
        List<T> results = query(sql, rowMapper);

        if (results == null || results.isEmpty()) {
            return null;
        }
        else if (results.size() > 1) {
            throw new IncorrectResultSizeDataAccessException(1, results.size());
        }
        else{
            return results.iterator().next();
        }
    }

    public <T> T queryForNullableObject(String sql, Class<T> requiredType) throws DataAccessException {
        return queryForObject(sql, getSingleColumnRowMapper(requiredType));
    }

}

queryForObject を使用したのと同じ方法で、これをコードで使用できるようになりました。

String result = queryForNullableObject(queryString, String.class);

他の誰かがこれが良い考えだと思うかどうか知りたいですか?

于 2014-02-25T05:46:16.140 に答える
2

グループ関数を使用して、クエリが常に結果を返すようにすることができます。すなわち

MIN(ID_NMB_SRZ)
于 2012-06-18T14:34:37.917 に答える
0

使用中に同じ例外が発生しました

if(jdbcTemplate.queryForMap("select * from table").size() > 0 ) /* resulted exception */ 

リストに変更すると解決しました

if(jdbcTemplate.queryForList("select * from table").size() > 0) /* no exception */
于 2021-04-01T15:52:09.663 に答える
-1

この「EmptyResultDataAccessException」をキャッチするだけです

public Myclass findOne(String id){
    try {
        Myclass m = this.jdbcTemplate.queryForObject(
                "SELECT * FROM tb_t WHERE id = ?",
                new Object[]{id},
                new RowMapper<Myclass>() {
                    public Myclass mapRow(ResultSet rs, int rowNum) throws SQLException {
                        Myclass m = new Myclass();
                        m.setName(rs.getString("name"));
                        return m;
                    }
                });
        return m;
    } catch (EmptyResultDataAccessException e) { // result.size() == 0;
        return null;
    }
}

その後、次のことを確認できます。

if(m == null){
    // insert operation.
}else{
    // update operation.
}
于 2016-11-16T13:39:10.420 に答える