本文為JPA的學習采坑,如有問題歡迎指正。
JPA官方推薦的多表關聯查詢使用不便,接觸的有些項目可能會使用JPA 做簡單查詢,Mybaits做復雜查詢。所以想要尋找一種好用的解決方案。
JPA多表關聯的實現方式
1.使用Specification實現映射關系匹配,如@ManyToOne等
2.使用NativeQuery等sql或hql來實現
優缺點對比
1.映射關系是hibernate的入門基礎,很多人都會習慣去使用。個人不太喜歡這種方式,復用性太弱,且不靈活特別是在多表復雜業務情況下。
2.使用Specification方式需要繼承JpaSpecificationExecutor接口,構造對應的方法后傳入封裝查詢條件的Specification對象。邏輯上簡單易懂,但是構造Specification對象需要拼接格式條件非常繁瑣。
3.直接使用NativeQuery等方式實現復雜查詢個人比較喜歡,直觀且便利,弊端在於無法返回自定義實體類。需要手動封裝工具類來實現Object到目標對象的反射。
使用sql並返回自定義實體類
個人比較喜歡的實現方式,不多說看代碼
-
-
import org.springframework.stereotype.Repository;
-
import javax.persistence.EntityManager;
-
import javax.persistence.PersistenceContext;
-
import javax.transaction.Transactional;
-
-
@Repository
-
public
class EntityManagerDAO {
-
-
@PersistenceContext
-
private EntityManager entityManager;
-
-
-
-
/**
-
* 人員列表排序
-
* @return
-
*/
-
@Transactional
-
public List<BackstageUserListDTO> listUser(){
-
String sql =
"select a.create_time createTime," +
-
"a.mobilephone phoneNum," +
-
"a.email email,a.uid uid," +
-
"a.enabled enabled," +
-
"c.id_number idNumber," +
-
" (case b.`status` when 1 then 1 else 0 end) status " +
-
"from tbl_sys_user a " +
-
"LEFT JOIN user_high_qic b on a.uid=b.u_id" +
-
"LEFT JOIN user_qic c on a.uid=c.uid " +
-
"ORDER BY status desc";
-
-
SQLQuery sqlQuery = entityManager.createNativeQuery(sql).unwrap(SQLQuery.class);
-
Query query =
-
sqlQuery.setResultTransformer(Transformers.aliasToBean(BackstageUserListDTO.class));
-
List<BackstageUserListDTO> list = query.list();
-
entityManager.clear();
-
return list;
-
}
-
}
-
public
class BackstageUserListDTO implements Serializable{
-
-
private
static
final
long serid =
1L;
-
-
private String createTime;
-
-
private String phoneNum;
-
-
private String email;
-
-
private BigInteger uid;
-
-
private Integer enabled;
-
-
private String idNumber;
-
-
private BigInteger status;
-
-
//GETTER SETTER
-
-
}
這樣一個需求如果使用前兩種方式實現,無疑會非常麻煩。使用這種方式能夠直接反射需要的自定義實體類。
可以根據需求整理封裝成不同的方法,加入排序,分頁等。
主要提供一種方便的解決思路,有問題歡迎指正
2019-07-10更新
新版的API使用方法如下(舊版本Map轉實體會提示不能強轉)
Query nativeQuery = entityManager.createNativeQuery(sql, ArchiveMonthlyInfoBO.class);
List
list = nativeQuery.getResultList();
原文地址:https://blog.csdn.net/lw5885799/article/details/81103183