Last active
August 29, 2015 13:58
-
-
Save hizhengfu/9947416 to your computer and use it in GitHub Desktop.
AliasToBeanResultTransformer 修改版本,支持任意大小写字段,任意类型映射。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.shxt.wdcc3.common.persistence; | |
import org.apache.commons.beanutils.ConvertUtils; | |
import org.hibernate.HibernateException; | |
import org.hibernate.property.ChainedPropertyAccessor; | |
import org.hibernate.property.PropertyAccessor; | |
import org.hibernate.property.PropertyAccessorFactory; | |
import org.hibernate.property.Setter; | |
import org.hibernate.transform.AliasedTupleSubsetResultTransformer; | |
import org.springframework.beans.BeanUtils; | |
import java.beans.PropertyDescriptor; | |
import java.util.Arrays; | |
import java.util.HashMap; | |
import java.util.Map; | |
/** | |
* Result transformer that allows to transform a result to | |
* a user specified class which will be populated via setter | |
* methods or fields matching the alias names. | |
* <p/> | |
* <pre> | |
* List resultWithAliasedBean = s.createCriteria(Enrolment.class) | |
* .createAlias("student", "st") | |
* .createAlias("course", "co") | |
* .setProjection( Projections.projectionList() | |
* .add( Projections.property("co.description"), "courseDescription" ) | |
* ) | |
* .setResultTransformer( new AliasToBeanResultTransformer(StudentDTO.class) ) | |
* .list(); | |
* | |
* StudentDTO dto = (StudentDTO)resultWithAliasedBean.get(0); | |
* </pre> | |
* | |
* @author max | |
*/ | |
public class AliasToBeanResultTransformer extends AliasedTupleSubsetResultTransformer { | |
// IMPL NOTE : due to the delayed population of setters (setters cached | |
// for performance), we really cannot properly define equality for | |
// this transformer | |
private final Class resultClass; | |
private boolean isInitialized; | |
private String[] aliases; | |
private Setter[] setters; | |
private Map<String, String> mappedFields; | |
private Map<String, Class> mappedTypes; | |
public AliasToBeanResultTransformer(Class resultClass) { | |
if (resultClass == null) { | |
throw new IllegalArgumentException("resultClass cannot be null"); | |
} | |
isInitialized = false; | |
this.resultClass = resultClass; | |
} | |
/** | |
* {@inheritDoc} | |
*/ | |
public boolean isTransformedValueATupleElement(String[] aliases, int tupleLength) { | |
return false; | |
} | |
public Object transformTuple(Object[] tuple, String[] aliases) { | |
Object result; | |
try { | |
if (!isInitialized) { | |
initialize(aliases); | |
} else { | |
check(aliases); | |
} | |
result = resultClass.newInstance(); | |
for (int i = 0; i < aliases.length; i++) { | |
if (setters[i] != null && tuple[i] != null && mappedTypes.get(aliases[i].toLowerCase()) != null) { | |
setters[i].set(result, ConvertUtils.convert(tuple[i], mappedTypes.get(aliases[i].toLowerCase())), null); | |
} | |
} | |
} catch (InstantiationException e) { | |
throw new HibernateException("Could not instantiate resultclass: " + resultClass.getName()); | |
} catch (IllegalAccessException e) { | |
throw new HibernateException("Could not instantiate resultclass: " + resultClass.getName()); | |
} | |
return result; | |
} | |
private void initialize(String[] aliases) { | |
PropertyAccessor propertyAccessor = new ChainedPropertyAccessor( | |
new PropertyAccessor[]{ | |
PropertyAccessorFactory.getPropertyAccessor(resultClass, null), | |
PropertyAccessorFactory.getPropertyAccessor("field") | |
} | |
); | |
PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(resultClass); | |
this.mappedFields = new HashMap<String, String>(pds.length); | |
this.mappedTypes = new HashMap<String, Class>(pds.length); | |
String name; | |
for (PropertyDescriptor pd : pds) { | |
if (pd.getWriteMethod() != null) { | |
name = pd.getName().toLowerCase(); | |
this.mappedTypes.put(name, pd.getPropertyType()); | |
this.mappedFields.put(name, pd.getName()); | |
} | |
} | |
this.aliases = new String[aliases.length]; | |
setters = new Setter[aliases.length]; | |
for (int i = 0; i < aliases.length; i++) { | |
String alias = aliases[i]; | |
if (alias != null) { | |
this.aliases[i] = alias; | |
String field = mappedFields.get(alias.toLowerCase()); | |
if (field != null) { | |
setters[i] = propertyAccessor.getSetter(resultClass, field); | |
} | |
} | |
} | |
isInitialized = true; | |
} | |
private void check(String[] aliases) { | |
if (!Arrays.equals(aliases, this.aliases)) { | |
throw new IllegalStateException( | |
"aliases are different from what is cached; aliases=" + Arrays.asList(aliases) + | |
" cached=" + Arrays.asList(this.aliases) | |
); | |
} | |
} | |
public boolean equals(Object o) { | |
if (this == o) { | |
return true; | |
} | |
if (o == null || getClass() != o.getClass()) { | |
return false; | |
} | |
AliasToBeanResultTransformer that = (AliasToBeanResultTransformer) o; | |
if (!resultClass.equals(that.resultClass)) { | |
return false; | |
} | |
if (!Arrays.equals(aliases, that.aliases)) { | |
return false; | |
} | |
return true; | |
} | |
public int hashCode() { | |
int result = resultClass.hashCode(); | |
result = 31 * result + (aliases != null ? Arrays.hashCode(aliases) : 0); | |
return result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment