Java ResultSetMetaData之getColumnName与getColumnLabel

    xiaoxiao2022-06-30  48

    最近在写一个功能的时候遇到一个问题,今天刚好有空,就把他记录下来。 问题是这样的,在做一个很普通的查询功能,结果却出现了问题。问题是查出来莫名少了一些列,就是说用代码查出来的数据和用数据库客户端查出来的数据不一致,也不报错。这可让我百思不得其解。sql类似如下:

    第一种: SELECT * FROM TEST A LEFT JOIN TEST_1 I ON A.DOMAIN_CODE = I.VERSION_ID; 第二种: SELECT A.*, I.* FROM TEST A, TEST_1 I WHERE A.DOMAIN_CODE = I.VERSION_ID; 第三种: SELECT A.ID AS A_ID, A.CREATE_DATE AS A_CREATE_DATE, I.ID AS I_ID, I.CREATE_DATE AS I_CREATE_DATE FROM TEST A LEFT JOIN TEST_1 I ON A.ID = I.ID;

    但是不管怎么查,最后查询出来的结果列少了一些,而且数据也都有。

    遇到这个比较棘手的问题,无奈之下去看了一下用的框架的底层代码, 大致的意思是这样的:

    DBUtil dbutil = DBUtil.getInstance(); try { Connection conn = dbutil.getConnection(); Statement st = conn.createStatement(); ResultSet rs = st.executeQuery(sql); ResultSetMetaData rsmd = rs.getMetaData() ; int columnCount = rsmd.getColumnCount(); ArrayList ret = new ArrayList(); String[] colNames = new String[columnCount]; int i; for(int bo = 0; bo < colNames.length; ++bo) { i = bo + 1; colNames[bo] = rsmd.getColumnName(i); if(colNames[bo] != null) { colNames[bo] = colNames[bo].toUpperCase(); } } while(rs.next()) { Map var11 = new HashMap(); for(i = 1; i <= columnCount; ++i) { var11.put(colNames[i - 1], rs.getString(i)); } ret.add(var11); } return ret; } catch (Exception e) { e.printStackTrace(); }

    相信代码很容易看懂,为了返回一个装有Map的List,先用ResultSetMetaData去查询了结果集的列的信息,然后在根据列名组装结果集的数据并返回,乍一看没什么问题。别忘了我这篇文章的标题,我把列名打印出来之后,仔细一想就会发现问题所在了:

    由于我的两张表的数据列有几列列名相同,而getColumnName取的是数据库表的原始列名,这样查出来的列数固然是正确的,然而在ResuleSet往Map集合里面装数据的时候,由于Key值相同,后面的列数据覆盖了前面添加的列数据,因此查询返回后的结果集列少了一些。别忘了HashMap是不允许键值重复的,到此发现了问题的所在。

    然后开始解决问题,翻遍了API发现了一个方法似乎可行,

    这个方法取Select的字段别名,那么我在写Sql的时候让字段别名不重复不就行了吗,所以,用下面的代码代替上面的:

    colNames[bo] = rsmd.getColumnLabel(i);

    至此问题解决。

    转载请注明原文地址: https://ju.6miu.com/read-1125569.html

    最新回复(0)