Parse resulttransformer in hibernate using query

Source: Internet
Author: User

Reproduced http://www.iflym.com/index.php/code/resolve-hibernate-result-transformer-by-query.html

Any framework that encapsulates JDBC cannot do without encapsulating the final data into a Java object. In JDBC, the obtained data is encapsulated in the resultset, and the corresponding fields and data values are obtained again and again through iterative resultset. The problem that the database framework always needs to solve is to map the field name information in the resultset to the corresponding field value, encapsulate it into an object, and finally form a set of all objects, and finally return it to the caller.
Any database framework cannot escape the intermediate processing logic, but how to distribute the logic in the upper and lower processing. In hibernate, there are similar things. This interface is called resulttransformer.

Transformer is defined as follows:

public interface ResultTransformer extends Serializable 

{      

public Object transformTuple(Object[] tuple, String[] aliases);      

public List transformList(List collection); 

The first method, transformtuple, is how to process the field values (which may have been processed twice) queried from the database and the corresponding field name values, for example, combine the field value and field name into a map. Field value, that is, the list of fields queried during the Query Process, and the field name is the Select name during the query.
The second method, transformlist, provides encapsulation for the returned results from the database, and then the last processing of the encapsulated data list. Such as deduplication.

To illustrate the use of resulttransformer in hibernate, we can start with the query in hibernate to see how resulttransformer is used in it (taking hibernate3.6.3 as an example, unnecessary code is not displayed in the Code ).

Start with the list in queryimpl:

public List list() throws HibernateException {             

return getSession().list(expandParameterLists(namedParams), getQueryParameters(namedParams));     

Note that the getqueryparameters call in the above Code encapsulates all parameters passed to the query, including the resulttransformer passed to the query. If we use query. setresulttransformer to pass to query, this will be passed to the corresponding function during the call and generate a queryparameters object.
Next, let's look at the implementation in sessionimpl:

public List list(String query, QueryParameters queryParameters) throws HibernateException 

{         

HQLQueryPlan plan = getHQLQueryPlan( query, false );             

results = plan.performList( queryParameters, this );         

return results;     

The following code encapsulates a query statement into a query plan, executes the plan, and returns a query result. Go to the method implementation, and use the merge MList method of the hqlqueryplan class:

Public list parameter MList (queryparameters, sessionimplementor session) throws hibernateexception {
List combinedresults = new arraylist ();
Translator_loop: For (INT I = 0; I <translators. length; I ++ ){
List TMP = translators [I]. List (Session, queryparameterstouse );
Combinedresults. addall (TMP );
}
Return combinedresults;

}

The above code calls an implementation called querytranslator, which converts hql to SQL and performs query operations. Go to the List Method of the querytranslatorimpl class:

public List list(SessionImplementor session, 

QueryParameters queryParameters) throws HibernateException 

List results = queryLoader.list( session, queryParametersToUse ); 

return results; 

The above code calls the final query logic implementation, that is, the final Database loading logic of querytranslator, to query and enter the list method that implements the queryloader class:

Public list (sessionimplementor session, queryparameters) throws hibernateexception {

Return list (Session, queryparameters, querytranslator. getqueryspaces (), queryreturntypes );
}
 
Protected list (final sessionimplementor session, final queryparameters, final set queryspaces, final type [] resulttypes) throws hibernateexception {
Return listignorequerycache (Session, queryparameters );
}
 
Private list listignorequerycache (sessionimplementor session, queryparameters ){
Return getresultlist (dolist (Session, queryparameters), queryparameters. getresulttransformer ());
}

The above three methods are some internal implementation logic, so we will not go into it here. The most important thing is the final getresult method and the dolist method in it. Here, dolist is the final database query implementation and preliminary object conversion (for example, the data result is converted into a DOM object during the from class query ). Then, the result set is delivered to getresultlist for processing, that is, our most important resulttransformer processing.

Protected list getresultlist (list results, resulttransformer) throws queryexception {
Holderinstantiator = buildholderinstantiator (resulttransformer );
If (holderinstantiator. isrequired ()){
For (INT I = 0; I <results. Size (); I ++ ){
Object [] ROW = (object []) results. Get (I );
Object result = holderinstantiator. instantiate (ROW );
}......
Return resulttransformer. transformlist (results );
}

}

In the above section, a key class holderinstantiator is used to process data according to resulttransformer. First, we will instantiate the returned data value (the default value is the object array) as an object, which is to convert the array to an object. In this case, we will call transformer to convert the data for the first time, convert the data returned by the database to the required data:

Public object instantiate (object [] row ){
If (transformer = NULL ){
Return row;
} Else {
Return transformer. transformtuple (row, queryreturnaliases );
}

}

Next we will perform the second processing. If deduplication is required, we will load the object set in the List into the set, and then convert it back for deduplication. The final result is what we need.

In these processes, not every process passes resulttransformer. In the absence of resulttransformer, Hibernate has processed it internally. If we need to query a domain object, Hibernate will use entitykey to parse the data. If we query the attribute list, we will use the default object array to load the results. However, once resulttransformer is set, the above query results are processed. For example, convert an object array to another format, such as list or map (this is the most frequently used aliastoentitymapresulttransformer )..
Hibernate uses the static single-State mode to encapsulate the corresponding resulttransformer implementation. When the corresponding data is required, it can be directly obtained and transmitted through public static fields (and the only method ). For example, you can use resulttransformerimpl. instance or transformers. Static Field Reference to obtain the corresponding resulttransformer and pass it to query and criteria to obtain the data.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.