本文为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
}
这样一个需求如果使用前两种方式实现,无疑会非常麻烦。使用这种方式能够直接反射需要的自定义实体类。
可以根据需求整理封装成不同的方法,加入排序,分页等。
主要提供一种方便的解决思路,有问题欢迎指正