Spring JDBC : 执行 Order By 时结果不一致

Spring JDBC : Inconsistent results when performing Order By

如有任何帮助,我们将不胜感激。我正在开发一个使用 Spring JDBC 进行数据访问的项目,并且正在使用按列排序的表达式执行简单查询,我目前得到的结果不一致,这意味着按排序似乎不起作用.我试了不止一个数据库还是不行。

String sql = "select * from account where upper(name) like upper(:query) order by name asc";
MapSqlParameterSource params = new MapSqlParameterSource().addValue("query", "%" + query + "%");

List<Account> accountsSearched = namedParameterJdbcTemplate.query(sql, params, new BeanPropertyRowMapper<Account>(Account.class));

任何想法可能是什么问题?

所以问题不在您的 SQL 代码中,但问题存在于 搜索方法实现中

现有代码

public List<Account> search(String uncleanedQuery, int offset) {
    String query = uncleanedQuery.replaceAll("([-+.^:,])","");
    String sql = "select * from account where upper(name) like upper(:query) order by name asc";
    MapSqlParameterSource params = new MapSqlParameterSource().addValue("query", "%" + query + "%");
    List<Account> accountsSearched = namedParameterJdbcTemplate.query(sql, params, new BeanPropertyRowMapper<Account>(Account.class));
    Set<Account> accountSearchSet = new HashSet<Account>(accountsSearched);
    List<Account> accounts = new ArrayList<Account>(accountSearchSet);
    return accounts;
}

在上面的代码中,我们正确地获取了数据,但将其分配给了 HashSet。 HashSet 不遵守按名称排序并为帐户生成随机顺序,因此您每次都会获得随机顺序。

解决方案一: 没有理由,您实际上需要 Set。使用 set 只会让你的程序变慢。如果要获取 DISTINCT 数据,请修改 SQL 查询。

public List<Account> search(String uncleanedQuery, int offset) {
    String query = uncleanedQuery.replaceAll("([-+.^:,])","");
    String sql = "select * from account where upper(name) like upper(:query) order by name asc";
    MapSqlParameterSource params = new MapSqlParameterSource().addValue("query", "%" + query + "%");
    List<Account> accountsSearched = namedParameterJdbcTemplate.query(sql, params, new BeanPropertyRowMapper<Account>(Account.class));
    return accountsSearched;
}

方案二:

不过,您想采用您的方法,然后更改代码以使用 TreeSet 并根据名称进行排序

public List<Account> search(String uncleanedQuery, int offset) {
    String query = uncleanedQuery.replaceAll("([-+.^:,])", "");
    System.out.println("Search Query Called");
    String sql = "select * from account where upper(name) like upper(:query) order by name";

    MapSqlParameterSource params = new MapSqlParameterSource().addValue("query", "%" + query + "%");

    List<Account> accountsSearched = namedParameterJdbcTemplate.query(sql, params,
            new BeanPropertyRowMapper<Account>(Account.class));

    Comparator<Account> comp = new Comparator<Account>() {

        @Override
        public int compare(Account a1, Account a2) {
            return a1.getName().compareTo(a2.getName());
        }
    };

    SortedSet<Account> accountSearchSet = new TreeSet<Account>(comp);
    accountSearchSet.addAll(accountsSearched);

    List<Account> accounts = new ArrayList<Account>(accountSearchSet);

    return accounts;
}