groovy hibernate createSQLQuery 获取ResultSetMetaData?

groovy hibernate createSQLQuery access to ResultSetMetaData?

我有一个简单的 groovy/grails SQL 查询,我想从查询结果中访问元数据,但我不确定如何。

代码示例:

String sqlString = “select * from my_table where id = :myID”
def queryParams = [ myID: 1 ]
final sqlQuery = session.createSQLQuery(sqlString)
final queryResults = sqlQuery.with {
    setProperties( queryParams )
    list()
}

queryResults.collect { r ->
    r.each{ c ->
        // I extract result data here
    }
}   

我看到

sqlQuery.class == org.hibernate.impl.SQLQueryImpl
queryResults.class == java.util.ArrayList

我看到了下面的文章 Groovy 优点:使用 Groovy SQL 访问 ResultSetMetaData: (http://mrhaki.blogspot.com/2011/09/groovy-goodness-access.html) 但我可以使用上面的 queryReults 代码获取 ResultSetMetaData 吗?

编辑 1:我想我可以使用 AliasToEntityMapResultTransformer (Retrieve a row from DB as a Map in Hibernate)如果我能弄清楚怎么做。

你在问题中提到的 link 直接使用 JDBC 类.

获取元数据

在您使用休眠模式的情况下,我认为您无法获取元数据。 list() org.hibernate.impl.SQLQueryImpl 上的方法 return 是您的结果值列表,如果每一行有多个结果,那么它 return 是 object[] 的列表,但是在此object[] 您只有 table 上列的值,但没有元数据,例如列名。

用休眠来做到这一点;如果您在 类 中定义了实体,则可以使用以下方法获取元数据:

def metadataForMyEntity = sessionFactory.getClassMetadata(YourEntities.class)
def columnNames = metadataForMyEntity .getPropertyNames()
def columnTypes = metadataForMyEntity.getPropertyTypes();

参见 SessionFactory and ClassMetadata

相反,如果您想避免创建实体,并且想以与 JDBC 中相同的方式进行操作,请直接使用 JDBC,就像您参考的文章中那样:

import groovy.sql.*
def db = Sql.newInstance('yourConnectionString', 'user', 'password', 'driver')
String sqlString = 'select * from my_table where id = 1'
def rows = db.rows(sqlString , { meta ->
   ....
}

顺便请注意,在您的示例中有一个拼写错误,您定义了 queryResults 但随后您尝试使用 queryReults 来迭代结果 :).

希望这对您有所帮助,

谢谢albciff,我也找到了另一个解决方案: 我阅读了 post Retrieve a row from DB as a Map in Hibernate,发现我可以将 AliasToEntityMapResultsTransformer 与我拥有的 sqlQuery 代码一起使用:

final queryResults = sqlQuery.with {
    setProperties( queryParams )
    setResultsTransformer(AliasToEntityMapResultsTransformer.INSTANCE)
    list()
}

然后它将 return 一个包含结果中列名的 HashMap:

queryResults.collect { r ->
    r.each{ k, v ->
        // k = key from MetaData = table column, v = value
    }
}

我确实注意到结果中列的顺序不再与 SQL 查询中字段的顺序匹配,但是由于它现在 returned 了列名,所以这并不匹配事情。