JPA使用nativequery多表关联查询返回自定义实体类
本文为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