當遇到複雜多表查詢時,而且同時還須要確保查詢性能,此時則須要使用自定義sql查詢,然而spring data jpa對於自定義sql則需使用查詢須要在對應的bean中作太多的配置映射,我嘗試了一下,最終仍是沒成功。故選擇了另外一種方式來解決。spring
String sql = "select a.name,b.className,a.createTime from A a left join B b on a.id = b.id";
Query query = entityManager.createNativeQuery(sql); //此方法是將數據集合轉換位map類型的List集合
//query.unwrap(SQLQuery.class).setResultTransformer(Transformers.aliasToBean(HashMap.class)); List<Object[]> resultList = query.getResultList(); List<MyEntity> list = CommonUtils.castEntity(resultList, MyEntity.class);
使用entityManage建立nativeQuery,此時獲取到的結果集返回的數據是 List<Object[]> 類型的,因爲我所須要的字段僅只有name,className,createTime,故構造對應的bean。sql
public class MyEntity { private String name; private String className; private Long createTime; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public Long getCreateTime() { return createTime; } public void setCreateTime(Long createTime) { this.createTime = createTime; } //必須構建的構造方法,含有查詢列全部的對應的字段 public MyEntity(String name, String className, BigInteger createTime) { this.name = name; this.className = className; this.createTime = createTime != null ? createTime.longValue() : null ; } public MyEntity() { } }
因爲數據庫中createTime保存的是Long型,發現用 entityManager 獲取到的是 BigInteger ,故構造方法的參數類型設爲BigInteger,是爲了便於數據作轉換。數據庫
/** * 數組集合轉化爲指定對象集合 * 指定的實體對象必須包含因此字段的構造方法,數組的元素的順序將和構造方法順序和類型一一對應 * @param list * @param clazz * @param <T> * @return * @throws Exception */ public static <T> List<T> castEntity(List<Object[]> list, Class<T> clazz) throws Exception { List<T> returnList = new ArrayList<>(); if (list.size() == 0){ return returnList; } Class[] c2 = null; Constructor[] constructors = clazz.getConstructors(); for (Constructor constructor : constructors){ Class[] tClass = constructor.getParameterTypes(); if (tClass.length == list.get(0).length){ c2 = tClass; break; } } //構造方法實例化對象 for(Object[] o : list){ Constructor<T> constructor = clazz.getConstructor(c2); returnList.add(constructor.newInstance(o)); } return returnList; }
上面方法則是對數據進行了轉換,經過反射構造方法進行實例化對象。返回目標類型的List集合。數組