通过query解析hibernate中的resultTransformer
2021-07-13 02:04
标签:prot java对象 return str 注意 列表 class lis arraylist 任何包装jdbc的框架,都离不开将最终的数据封装成java对象的一个过程。在jdbc中,取得的数据被封装在resultset中,通过迭代resultset来一次次的取得相应的字段和数据值。数据库框架始终需要解决的问题在于将resultset中的字段名称信息和相应的字段值对应起来,然后封装成对象,最后将所有的对象形成一个集合,并最终返回给调用者。 任何数据库框架都逃不过这中间的处理逻辑,只不过如何将这些逻辑分散在上下的处理中。在Hibernate中,同样也有类似的东西,这个接口就叫做ResultTransformer。 Transformer的定义如下: 其中第一个方法transformTuple,即是如何处理从数据库查询出来的字段值(可能经过了二次处理)和相对应的字段名称值,比如将字段值和字段名称组合成一个map。字段值,即在查询过程中查询的字段列表,而字段名称即是在查询时select的名称。 第二个方法transformList,提供了对于从数据库返回结果,进行了封装之后,再对封装之后的数据列表进行最后一次处理。如进行去重等。 为了说明ResultTransformer在Hibernate中的运用,我们从Hibernate中的查询入手,看ResultTransformer如何在其中运用的(以Hibernate3.6.3版本为例,在代码中不显示不必要的代码)。 由类QueryImpl中的list入手: 注意上面代码中的getQueryParameters调用,这里会将传递给query的所有参数进行封装,包括传递给query的resultTransformer。如果我们使用query.setResultTransformer传递给query,在调用时这里就会传递给相应的函数,并生成一个QueryParameters对象。 以下代码将查询语句封装成一个查询计划,并执行该计划,返回一个查询结果。进入方法实现,类HQLQueryPlan的performList方法: 以上代码会调用一个叫QueryTranslator的实现,即将hql转化为sql并进行查询操作。进入实现类QueryTranslatorImpl类的list方法: 以上代码会调用最终的查询逻辑实现即queryTranslator的最终数据库加载逻辑去查询,进入实现类QueryLoader的list方法: 以上3个方法是一些内部实现逻辑,这里就不深究了。最重要的是最后的getResult方法和里面的doList方法。其中doList即是最终的数据库查询实现,以及初步的对象转化(比如from 类查询时,会将数据结果转换成一个dom对象)。然后将结果集交到getResultList中进行处理,即到了我们最重要的resultTransformer处理了。 在上面的地方,这里出现了一个关键的类HolderInstantiator,就是根据resultTransformer来处理数据。首先会将返回的数据值(默认即为object数组)进行实例化为一个对象,就是将数组转换为对象,这里面就会调用我们transformer第一次转换数据了,即将数据库返回数据转换为需要的数据: 接下来就进行第二次处理,如果需要去重,就将list中的对象集合装入set,再转换回来进行去重处理。最后就是我们所需要的结果了。 在这些处理当中,并不是每次处理都传递了resultTransformer的。对于没有resultTransformer的情况,Hibernate在内部已经进行了处理。如果我们需要查询一个domain对象,Hibernate就会使用entityKey来解析数据;如果查询的是属性列表,即是使用默认的object数组来装结果。但一旦设置了resultTransformer,就是将上面查询的结果进行处理了。如将object数组转换成其它格式,如list格式,或者map格式(这一种用得最频繁,即经常使用的AliasToEntityMapResultTransformer).。 Hibernate使用了静态单态的模式来封装相应的resultTransformer实现,当需要相应的数据时,即可直接通过公共的静态字段进行获取和传递(而且也是惟一的手段)。如通过ResultTransformerImpl.INSTANCE或通过Transformers.静态字段引用来获取相应的resultTransformer,最终传递给query,criteria等,以达到获取数据的目的。 转载请标明出处:i flym 本文地址:https://www.iflym.com/index.php/code/resolve-hibernate-result-transformer-by-query.html 通过query解析hibernate中的resultTransformer 标签:prot java对象 return str 注意 列表 class lis arraylist 原文地址:http://www.cnblogs.com/shuilangyizu/p/7079869.htmlpublic interface ResultTransformer extends Serializable {
public Object transformTuple(Object[] tuple, String[] aliases);
public List transformList(List collection);
}
public List list() throws HibernateException {
return getSession().list(expandParameterLists(namedParams), getQueryParameters(namedParams));
}
接下来看sessionImpl中的实现:public List list(String query, QueryParameters queryParameters) throws HibernateException {
HQLQueryPlan plan = getHQLQueryPlan( query, false );
results = plan.performList( queryParameters, this );
return results;
}
public List performList(QueryParameters queryParameters,SessionImplementor session) throws HibernateException {
List combinedResults = new ArrayList();
translator_loop: for ( int i = 0; i ) {
List tmp = translators[i].list( session, queryParametersToUse );
combinedResults.addAll( tmp );
}
return combinedResults;
}
public List list(SessionImplementor session, QueryParameters queryParameters) throws HibernateException {
List results = queryLoader.list( session, queryParametersToUse );
return results;
}
public List list(SessionImplementor session,QueryParameters queryParameters) throws HibernateException {
return list( session, queryParameters, queryTranslator.getQuerySpaces(), queryReturnTypes );
}
protected List list( final SessionImplementor session,final QueryParameters queryParameters, final Set querySpaces, final Type[] resultTypes) throws HibernateException {
return listIgnoreQueryCache( session, queryParameters );
}
private List listIgnoreQueryCache(SessionImplementor session, QueryParameters queryParameters) {
return getResultList( doList( session, queryParameters ), queryParameters.getResultTransformer() );
}
protected List getResultList(List results, ResultTransformer resultTransformer) throws QueryException {
HolderInstantiator holderInstantiator = buildHolderInstantiator( resultTransformer );
if ( holderInstantiator.isRequired() ) {
for ( int i = 0; i ) {
Object[] row = ( Object[] ) results.get( i );
Object result = holderInstantiator.instantiate(row);
}......
return resultTransformer.transformList(results);
}
}
public Object instantiate(Object[] row) {
if(transformer==null) {
return row;
} else {
return transformer.transformTuple(row, queryReturnAliases);
}
}
上一篇:webpackの学习笔记2
下一篇:web前端浏览器兼容性问题
文章标题:通过query解析hibernate中的resultTransformer
文章链接:http://soscw.com/index.php/essay/104422.html