问题现状
Query query = JPA.em().createNativeQuery(EXECUTESQL); //若不设置这一行, list中的元素默认为Object[]类型 //若设置后, Object[]会转为HashMap, 字段名为key, 字段值为value的形式 query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); query.getResultList();
问题原因
//该类作为了setResultTransformer方法的参数 public class AliasToEntityMapResultTransformer extends BasicTransformerAdapter implements Serializable { public static final AliasToEntityMapResultTransformer INSTANCE = new AliasToEntityMapResultTransformer(); private AliasToEntityMapResultTransformer() { } public Object transformTuple(Object[] tuple, String[] aliases) { //此处申明的hashMap导致了结果集字段排序打乱 Map result = new HashMap(tuple.length); for(int i = 0; i < tuple.length; ++i) { String alias = aliases[i]; if (alias != null) { result.put(alias, tuple[i]); } } return result; } private Object readResolve() { return INSTANCE; } }
解决方式
//我们自行实现源码包下面的ResultTransformer接口 public interface ResultTransformer extends Serializable { //该方法用来转化结果集中的元组 //参数1为元组 //参数2为对应的字段名数组 Object transformTuple(Object[] var1, String[] var2); List transformList(List var1); }
//自己的实现 package utils.jpa; import org.hibernate.transform.ResultTransformer; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; public class AliasToEntityLinkHashMapResultTransformer implements ResultTransformer { public static final AliasToEntityLinkHashMapResultTransformer INSTANCE = new AliasToEntityLinkHashMapResultTransformer(); @Override public Object transformTuple(Object[] tuple, String[] aliases) { //此处Map申明为LinkedHashMap, 即可使字段排序保持查询时的顺序 Map result = new LinkedHashMap(tuple.length); for(int i = 0; i < tuple.length; ++i) { String alias = aliases[i]; if (alias != null) { result.put(alias, tuple[i]); } } return result; } @Override public List transformList(List list) { return list; } }
解决结果
Query query= JPA.em().createNativeQuery(EXECUTESQL); //此处设置使用了我们自行实现的AliasToEntityLinkHashMapResultTransformer类 //即可使结果集保持查询的顺序 query.unwrap(SQLQuery.class).setResultTransformer(AliasToEntityLinkHashMapResultTransformer.INSTANCE); list = query.getResultList();