返回布尔值 - jdbcTemplate

16

我希望在这个方法中返回一个布尔值:

public Boolean isSizeOk(String transactionId){ 
    String sqlQuery = "SELECT true FROM customer_pool WHERE id = "+ transactionID + " AND level = 13)";

//The next line is the problem. 
    //If I am returning a Boolean List, I can write

    List <Boolean> sizeResult = jdbcTemplate.queryForList(sqlQuery, Boolean.class, transactionId);

    //But since I only want a boolean value, what will the statement be?
     Boolean sizeResult = jdbcTemplate......?

    return sizeResult;
}

请帮忙,谢谢。


非常感谢你,你的解决方案都是正确的。现在我不知道该将正确答案授予给谁 : )。感谢你的帮助! - bdfios
4个回答

28
如果您想编写一个检查数据库中是否存在记录的方法,可以使用以下代码:
Integer cnt = jdbcTemplate.queryForObject(
    "SELECT count(*) FROM customer_pool WHERE id = ? AND level = 13)", Integer.class, id);
return cnt != null && cnt > 0

好的,这看起来不错。但是如果记录不存在它会返回什么? - bdfios
查询将返回0,而“cnt!= null && cnt> 0”将返回false。 - kostya
@orbfish,我的原始答案有一个错误(缺少id参数)。我已经更正了答案。希望现在清楚了。 - kostya
4
因为 Count(*) 总会返回一个整数,所以“cnt != null”是否多余? - Pepster
1
count(*) 会读取所有匹配的记录,添加 limit 1 作为优化,这样数据库可以在找到第一条记录后停止计数。 - LaFayette

8

在 SQL 中计算行数,仅为了获取关于结果非空的简单信息可能是不必要的过度操作,你只需请求结果集的第一行即可结束。对于使用主键或其他索引进行简单查询,性能可能相似,但对于复杂查询或全表扫描查询,它可能会很慢。在 Spring 中,我更喜欢简单实用的方法。

public boolean exists(String sql, Object... args) {
    boolean result = query(sql, args, new ResultSetExtractor<Boolean>() {
        @Override
        public Boolean extractData(ResultSet rs) throws SQLException,DataAccessException {
            boolean result = rs.next();
            return result;
        }
    });
    return result;
}

(Google搜索“sql exists vs count”获取更多信息。)

4
值得一提的是,在Java 8中,这段代码可以写成“return jdbcTemplate.query(searchQuery, args, ResultSet::next)”。 - David Maes
尽管 next() 方法返回新的当前行是否有效,但应将此作为正确答案标记,并使用 return result.getBoolean(1) 读取该行中的值。 - dehumanizer
@dehumanizer,我不完全理解你的观点。根据javadoc的说明,“当对next方法的调用返回false时,光标定位在最后一行之后。”因此,我认为在非空结果集上,rs.next()的第一次调用返回true,在空结果集上返回false。这与实际结果集中有哪些列是无关的。getBoolean(1)假设查询的第一列是boolean类型(或者可以转换为boolean),这既过于严格,也会导致错误的结果,例如在Postgres上执行select false时。 - Tomáš Záluský
@TomášZáluský,我的观点是如果例如你执行select exists(...)这种查询,那么即使select exists查询返回false,你也会始终得到true,因为只有rs.next()会移动游标。 - dehumanizer
@dehumanizer 这个方法的目的是检查结果是否有行,仅此而已。我的目标是不对传入参数中的 SQL 应用任何限制,只是假设它返回一些数据,例如 select * from all_the_things。如果你自己包装这样的查询,即 select exists (select * from all_the_things),你实际上将评估负担转移到了 SQL 引擎上,并且查询返回元数据而不是数据,因此你不需要以这种形式使用该方法,或者你必须读取 getBoolean(1)。我不确定这种方法是否会使事情变得更简单,考虑到 SQL 性能和字符串连接。 - Tomáš Záluský

6
什么情况?(与IT技术有关)
// Change query accordingly
String query = "SELECT 1 FROM " + tableName + " WHERE " + idColumnName + " = ? LIMIT 1";
try {
    jdbcTemplate.queryForObject(query, new Object[]{id}, Long.class);
    return true;
} catch (EmptyResultDataAccessException e) {
    return false;
}

0

情况1:如果你要返回布尔值: 只需检查 sizeResult 列表的 size,如果大小大于 0,则返回 true,否则返回 false

情况2:如果你要返回布尔值列表,则返回类型必须是布尔值列表。你必须按照以下方式编写方法:

public List<Boolean> isSizeOk(String transactionId, int sizeLimit){ 
String sqlQuery = "SELECT true FROM customer_pool WHERE id = ? AND level = 13)";


List <Boolean> sizeResult = jdbcTemplate.queryForList(sqlQuery, Boolean.class, transactionId);

 Boolean sizeResult = jdbcTemplate......?

return sizeResult;

}


谢谢Akash。是的,当我将值返回为布尔列表时,它确实起作用,但是没有理由将其作为列表返回,因为我知道我想要的答案只能是TRUE或FALSE。这就是为什么我想以布尔方式返回它的正确方法,而不是作为布尔列表。 - bdfios
然后你可以使用Case 1的解决方案。 - Akash Goswami

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接