1. 程式人生 > 實用技巧 >hibernate原生SQL查詢結果直接轉換為實體類物件

hibernate原生SQL查詢結果直接轉換為實體類物件

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)); } }