JDBC SQL别名不起作用

时间:2014-11-29 19:00:07

标签: mysql java-ee jdbc thymeleaf

我正在尝试在我的java Web应用程序中运行以下查询:

SELECT platform AS "Platform" FROM edb.cases

web-app工作正常并且能够执行所有查询但是每当我使用别名(通过'AS')时,结果数据集为别名提供了空值。事实上,尽管在上面的查询中使用了列'platform'的别名,但结果数据集对于'Platform'键有一个空值,但是为我提供了键'platform'的正确值(这是原始的)专栏的名称。)

现在我需要执行的实际sql语句对于select语句来说有点复杂,并且使用别名在同一个表上左联接两次,如下所示:

 SELECT numOne.platform , numTwo.platform AS 'PlatformTwo' FROM edb.cases LEFT JOIN 
 edb.platform as numOne ON (numOne.rank = cases.platform) LEFT JOIN edb.platform as numTwo ON 
 (numTwo.rank = cases.highestPlatform) WHERE cases.index = 1000

问题是结果数据集包含键'platform'的正确值(对于numOne表),但键'PlatformOne'和'PlatformTwo'不存在。别名不起作用!

我已经在MySql工作台中尝试了两个语句,但它们运行正常。

请不要犹豫,询问更多信息。

编辑:

准备查询并将其发送到数据库的代码:

public static List<Map<String, Object>> executeQuery(final String query,
        Map<Integer, Object> data) {
    List<Map<String, Object>> result = null;
    try {
        Connection conn = createConnection();
        PreparedStatement pstmt = null;

        pstmt = conn.prepareStatement(query);
        if(data != null) {
            pstmt = createPreparedStatement(pstmt, data);
        }

        System.out.println(pstmt.toString());
        //The GET_CASE_FOR_INDEX query uses the executequery function in the else block:
        if((pstmt.toString().indexOf("INSERT") >= 0) || (pstmt.toString().indexOf("UPDATE") >= 0)) { 
            pstmt.executeUpdate();
        } else {
            ResultSet rs = pstmt.executeQuery();

            ResultSetMetaData md = rs.getMetaData();
            int columns = md.getColumnCount();
            result = new ArrayList<Map<String, Object>>();
            /*
             * Get the next row of the ResultSet 'rs' and insert a Map of the Column/Value pair
             * into the ArrayList of Maps 'result'
             */
            while(rs.next()) {
                Map<String, Object> row = new HashMap<String, Object>(columns);
                for(int i=1; i <= columns; i++) {
                    try {
                        row.put(md.getColumnName(i), rs.getObject(i));
                    } catch(Exception e) {
                        System.out.println(md.getColumnName(i));
                        System.out.println(row);
                        e.printStackTrace();
                    }
                }
                result.add(row);
            }
        }

        destroyConnection(conn);
        pstmt.close();
    } catch(SQLException e) {
        //TODO
        e.printStackTrace();
    }
    return result;
}

创建预准备语句的函数:

//creates a prepared statement by checking the type of the value that needs to be set.
private static PreparedStatement createPreparedStatement(
        PreparedStatement pstmt, Map<Integer, Object> data) {
    try {
        for(Integer key : data.keySet()) {
            Object value = data.get(key);

            System.out.println(key);
            if(data.get(key).equals(Types.NULL)) {
                pstmt.setNull(key, Types.INTEGER);
            } else if(value.getClass().equals(Integer.class)) {
                pstmt.setInt(key, (Integer) value);
            } else if(value.getClass().equals(String.class)) {
                pstmt.setString(key, (String) value);
            } else if(value.getClass().equals(Date.class)) {
                pstmt.setDate(key, (Date) value); 
            } else if(value.getClass().equals(Timestamp.class)) {
                pstmt.setTimestamp(key, (Timestamp) value);
            }
        }
    }catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return pstmt;
}

使用executeQuery函数执行查询并将其发送到Web模板的代码片段:

Map<Integer, Object> data_details = new HashMap<Integer, Object>();
data_details.put(1, parameter_ID);

List<Map<String, Object>> details = DBUtility.executeQuery(DBQuery.GET_CASE_FOR_INDEX, data_details);

webContext.setVariable("details", details);//This is where the template variable is being set

System.out.println(details);

GET_CASE_FOR_INDEX查询是:

SELECT numOne.platform , numTwo.platform AS 'PlatformTwo' FROM edb.cases LEFT JOIN 
edb.platform as numOne ON (numOne.rank = cases.platform) LEFT JOIN edb.platform as numTwo ON 
(numTwo.rank = cases.highestPlatform) WHERE cases.index = ?

当我打印详细信息哈希映射(结果数据集)时,关键的PlatformTwo完全不存在!

1 个答案:

答案 0 :(得分:8)

您正在使用.getColumnName ResultSetMetaData方法,该方法返回基础列的名称(如果可用)。 .getColumnLabel将返回SELECT ... AS ...定义的列别名。

为了说明,以下Java代码

PreparedStatement ps = conn.prepareStatement(
    "SELECT platform AS Platypus FROM cases");
ResultSet rs = ps.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
System.out.println(String.format(
    ".getColumnName returns \"%s\"", 
    rsmd.getColumnName(1)));
System.out.println(String.format(
    ".getColumnLabel returns \"%s\"", 
    rsmd.getColumnLabel(1)));

返回

.getColumnName returns "platform"
.getColumnLabel returns "Platypus"