hibernate原生的结果解析器对sql查询字段的命名要求比较严格,必须跟实体属性名称一致,而往往字段都是驼峰命名,所以重写了一个,优先按照驼峰命名映射,然后是直接匹配
使用的时候,直接设置结果解析器,指定接收结果类型就行了
SQLQuery query = ... query.setResultTransformer( new AliasedToHumpResultTransformer(StudentOrderChange.class));
List<StudentOrderChange> result = query.list();
import java.util.Arrays; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.hibernate.HibernateException; import org.hibernate.PropertyNotFoundException; import org.hibernate.property.access.internal.PropertyAccessStrategyBasicImpl; import org.hibernate.property.access.internal.PropertyAccessStrategyChainedImpl; import org.hibernate.property.access.internal.PropertyAccessStrategyFieldImpl; import org.hibernate.property.access.spi.Setter; import org.hibernate.transform.AliasedTupleSubsetResultTransformer; /** * 别名转驼峰命名结果解析器 * @author liu08dzxx * */ public class AliasedToHumpResultTransformer extends AliasedTupleSubsetResultTransformer { private static final long serialVersionUID = 4367861232547899096L; // private static Logger LOGGER = LoggerFactory.getLogger(AliasedToHumpResultTransformer.class); private final Class<?> resultClass; private boolean isInitialized; private String[] aliases; private Setter[] setters; public AliasedToHumpResultTransformer(Class<?> resultClass) { if (resultClass == null) { throw new IllegalArgumentException("resultClass cannot be null"); } isInitialized = false; this.resultClass = resultClass; } @Override public boolean isTransformedValueATupleElement(String[] aliases, int tupleLength) { return false; } @Override 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) { setters[i].set(result, tuple[i], 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) { PropertyAccessStrategyChainedImpl propertyAccessStrategy = new PropertyAccessStrategyChainedImpl( PropertyAccessStrategyBasicImpl.INSTANCE ,PropertyAccessStrategyFieldImpl.INSTANCE); 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; try { //修改为驼峰命名,如果找不到就不赋值 setters[i] = propertyAccessStrategy.buildPropertyAccess(resultClass, lineToHump(alias)).getSetter(); }catch(PropertyNotFoundException e) { //todo 不知道是否有必要,暂时不做 try { //找不到,尝试直接使用字段名作为属性名 setters[i] = propertyAccessStrategy.buildPropertyAccess(resultClass, alias).getSetter(); }catch(PropertyNotFoundException e2) { //还找不到,尝试直接使用去掉下划线的方式命名 try { setters[i] = propertyAccessStrategy.buildPropertyAccess(resultClass, alias.replace("_", "")).getSetter(); }catch(PropertyNotFoundException e3) { // LOGGER.warn("结果集字段"+alias+",在对象"+resultClass.getName()+"中没有属性对应,不使用的字段建议不要加入结果集"); setters[i] = null; } } } } } 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)); } } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } AliasedToHumpResultTransformer that = (AliasedToHumpResultTransformer) o; if (!resultClass.equals(that.resultClass)) { return false; } if (!Arrays.equals(aliases, that.aliases)) { return false; } return true; } @Override public int hashCode() { int result = resultClass.hashCode(); result = 31 * result + (aliases != null ? Arrays.hashCode(aliases) : 0); return result; } private static Pattern linePattern = Pattern.compile("_(\\w)"); /** 下划线转驼峰 */ public static String lineToHump(String str) { str = str.toLowerCase(); Matcher matcher = linePattern.matcher(str); StringBuffer sb = new StringBuffer(); while (matcher.find()) { matcher.appendReplacement(sb, matcher.group(1).toUpperCase()); } matcher.appendTail(sb); return sb.toString(); } private static Pattern humpPattern = Pattern.compile("[A-Z]"); /** 驼峰转下划线, */ public static String humpToLine2(String str) { Matcher matcher = humpPattern.matcher(str); StringBuffer sb = new StringBuffer(); while (matcher.find()) { matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase()); } matcher.appendTail(sb); return sb.toString(); } public static void main(String[] args) { String name = "user_type"; System.out.println(lineToHump(name)); } }