Skip to content

Instantly share code, notes, and snippets.

@hizhengfu
Last active August 29, 2015 13:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hizhengfu/9947416 to your computer and use it in GitHub Desktop.
Save hizhengfu/9947416 to your computer and use it in GitHub Desktop.
AliasToBeanResultTransformer 修改版本,支持任意大小写字段,任意类型映射。
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