本文为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();
原文地址:IT虾米网