queryforlist query namedparameterjdbctemplate examples example java spring jdbctemplate

java - query - Práctica recomendada para seleccionar datos utilizando Spring JdbcTemplate



jdbctemplate queryforlist examples (4)

Definitivamente, la primera forma es la mejor práctica, ya que en la segunda forma estás golpeando la base de datos dos veces, en la que deberías hacerlo solo una vez. Esto puede causar problemas de rendimiento.

Lo que debe hacer es capturar la excepción EmptyResultDataAccessException y luego devolver el valor nulo. Las plantillas Spring JDBC devuelven una excepción EmptyResultDataAccessException si no encuentra los datos en la base de datos.

Tu código debería tener este aspecto.

try { sql = "SELECT id FROM tableNmae WHERE column_name =''"+ coulmn value+ "''"; id= jdbcTemplate.queryForObject(sql, Long.class); } catch (EmptyResultDataAccessException e) { if(log.isDebugEnabled()){ log.debug(e); } return null }

Quiero saber cuál es la mejor práctica para seleccionar registros de una tabla. Mencioné dos métodos a continuación. Quiero saber cuál es la mejor práctica para seleccionar los datos de una tabla usando Spring JdbcTemplate .

Primer ejemplo

try { String sql = "SELECT id FROM tableName WHERE column_name = ''" + coulmn value + "''"; long id = jdbcTemplate.queryForObject(sql, Long.class); } catch (Exception e) { if (log.isDebugEnabled()) { log.debug(e); } }

Esto arroja la siguiente excepción:

Esperado 1 real 0 me gusta

Cuando la tabla no contiene ningún dato. Mi amigo me dijo que esta no es la mejor práctica para seleccionar los datos. Sugirió que el código mencionado a continuación es la única práctica recomendada para seleccionar datos.

Segundo ejemplo

try { String countQuery = "SELECT COUNT(id) FROM tableName"; int count = jdbcTemplate.queryForInt(countQuery); if (count > 0) { String sql = "SELECT id FROM tableName WHERE column_name = ''" + coulmn value + "''"; long id = jdbcTemplate.queryForObject(sql, Long.class); } } catch (Exception e) { if (log.isDebugEnabled()) { log.debug(e); } }


Estoy ansioso por saber cuál es la mejor o la mejor práctica posible.


Este es el código fuente del método queryForObject.

@Nullable public <T> T queryForObject(String sql, RowMapper<T> rowMapper) throws DataAccessException { List<T> results = this.query(sql, rowMapper); return DataAccessUtils.nullableSingleResult(results); }

DataAccessUtils.nullableSingleResult

@Nullable public static <T> T nullableSingleResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException { if (CollectionUtils.isEmpty(results)) { throw new EmptyResultDataAccessException(1); } else if (results.size() > 1) { throw new IncorrectResultSizeDataAccessException(1, results.size()); } else { return results.iterator().next(); } }

No sé por qué lanzan una excepción en una colección vacía, probablemente esto es solo una copia y pegado del método anterior.

public static <T> T requiredSingleResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException { if (CollectionUtils.isEmpty(results)) { throw new EmptyResultDataAccessException(1); } else if (results.size() > 1) { throw new IncorrectResultSizeDataAccessException(1, results.size()); } else { return results.iterator().next(); } }

Un paso más por encima del método que deberían haber usado.

@Nullable public static <T> T singleResult(@Nullable Collection<T> results) throws IncorrectResultSizeDataAccessException { if (CollectionUtils.isEmpty(results)) { return null; } else if (results.size() > 1) { throw new IncorrectResultSizeDataAccessException(1, results.size()); } else { return results.iterator().next(); } }

NOW SOLUTION me ayudó a: Extender la clase JdbcTemlate (puede construirlo con DataSource inyectado) y anular el método queryForObject:

@Nullable public <T> T queryForObject(String sql, RowMapper<T> rowMapper) throws DataAccessException { List<T> results = this.query(sql, rowMapper); return DataAccessUtils.singleResult(results); }

ahora trabaje con su implementación No se olvide de verificar si funciona en la actualización de la versión de primavera (IMHO muy improbable)


Me enfrento a un escenario similar y encontré una solución más limpia al usar ResultSetExtractor en lugar de RowMapper

jdbcTemplate.query(DBConstants.GET_VENDOR_DOCUMENT, new Object[]{vendorid}, rs -> { if(rs.next()){ DocumentPojo vendorDoc = new DocumentPojo(); vendorDoc.setRegDocument(rs.getString("registrationdoc")); vendorDoc.setMsmeLetter(rs.getString("msmeletter")); vendorDoc.setProprietorshipDocument(rs.getString("propertiershipformat")); vendorDoc.setNeftDocument(rs.getString("neftdoc")); vendorDoc.setPanCardDocument(rs.getString("pancard")); vendorDoc.setCancelledChequeDoc(rs.getString("cheque")); return vendorDoc; } else { return null; } });

Si no se encuentra ningún resultado de la base de datos, puse una condición if para el conjunto de resultados y devolví la referencia nula. Por lo tanto, no tuve que intentar capturar el código y pasar dos consultas a la base de datos.

La principal ventaja de ResultSetExtractor (en este escenario) es con ResultsetExtractor, tendrá que recorrer el conjunto de resultados, digamos en while loop.

Más puntos se pueden encontrar aquí here


Mejor manera de usar ifNull en la consulta, así que si hay un nulo, obtendrás 0, por ejemplo,

sql = "SELECT ifNull(id,0) FROM tableName WHERE column_name =''"+ coulmn value+ "''";

Usando de esta manera usted puede obtener por defecto 0 de lo contrario su ID