使用 `JdbcTemplate.queryForObject(sql, params, Integer.class)` 執行統計查詢時,若 SQL 寫為 `SELECT * FROM ...` 而非 `SELECT COUNT(1) ...`,會拋出:
org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expected 1, actual N
或類型轉換異常:`Cannot convert value of type [com.xxx.Entity] to required type [java.lang.Integer]`。
queryForObject 契約:
`SELECT *` 返回多列、多行,違反契約;`SELECT COUNT(1)` 返回單行單列數值,完美匹配。
public int countByCondition(String title, int mediaType, String status,
String provider, String region, Date from, Date to) {
StringBuilder sql = new StringBuilder("SELECT COUNT(1) FROM checkin_request WHERE 1=1 ");
List<Object> params = new ArrayList<>();
if (StringUtils.isNotEmpty(title)) {
sql.append("AND title = ? ");
params.add(title);
}
if (mediaType != -1) {
sql.append("AND media_type = ? ");
params.add(mediaType);
}
if (StringUtils.isNotEmpty(status)) {
sql.append("AND current_status = ? ");
params.add(status);
}
if (StringUtils.isNotEmpty(provider)) {
sql.append("AND provider = ? ");
params.add(provider);
}
if (StringUtils.isNotEmpty(region)) {
sql.append("AND region = ? ");
params.add(region);
}
if (from != null) {
sql.append("AND create_time >= ? ");
params.add(from);
}
if (to != null) {
sql.append("AND create_time <= ? ");
params.add(to);
}
return jdbcTemplate.queryForObject(sql.toString(), params.toArray(), Integer.class);
}
若需查詢單行映射為 POJO,請使用 `queryForObject(sql, params, new BeanPropertyRowMapper<>(Entity.class))`,前提同樣是 **SQL 必須保證只返回 1 行**。
`queryForObject` = **單行單列** 或 **單行映射對象**。統計計數請堅持 `SELECT COUNT(1) ...`,類型匹配 `Integer`/`Long`,即可避開 90% 的誤用異常。