上一节分享了一下JPA的基本操作,但是有时候这些基本操作并不能满足业务的需求,用惯了Mybatis的我觉得多表查询也是挺容易的一件事情,不用修改实体,自己写sql非常的灵活也非常的方便,但是在JPA中要实现多表查询就稍微麻烦一点,需要对实体进行修改,加上一些注解表示与其他实体的关联关系(一对一、一对多、多对一,多对多),下面我们就通过例子来讲解一下。
现在我们假设有这样的一个需求:查询一个用户列表,列表的信息有用户的id、姓名等以及部门id和部门名称,显然之前的基本操作无法满足我们现在的需求,一个类型的Repository只能返回对应类型的实体(我也觉得这样才是合理的),现在我们不光需要查询用户表还有通过用户表的部门id查询对应的部门信息,接下来说一下其中的一种解决方案。
有一种解决方案就是使用实体关联的方式来实现连接查询
修改之后的UserModel.java
package priv.cwr.model;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.persistence.*;
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "t_user")
@JsonInclude(JsonInclude.Include.NON_NULL)
@Data
public class UserModel extends BaseModel {
/**
* 用户id
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long userId;
/**
* 用户姓名
*/
private String name;
/**
* 性别,1:男,2:女
*/
private Integer gender;
/**
* 用户电话
*/
private String phone;
/**
* 备注
*/
private String note;
/**
* 部门实体
*/
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "dept_id")
private DeptModel dept;
// /**
// * 部门id
// */
// @Column(name = "dept_id")
// private Long deptId;
}
现在将之前的dept_id字段注释掉,改为实体关联,因为这里是用户和部门的多对一关联,所以使用@ManyToOne,@JoinColumn则表示的是关联的字段,这里可以理解为外键。
特别提醒:如果用户对应的部门id为null则查询出的部门实体也为null,如果通过部门id找不到对应的部门,则整个用户也会返回null。
查询结果如下
存在dept_id对应的部门
dept_id为空
查询用户列表(Pageable分页)
现在已经初步达到了我们的要求,连接查询出了用户信息以及对应的部门信息,但是现在的问题是这样查询出来的实体都是所有的字段,也许很多时候我们只需要其中的几个字段,就比如说这里我们只需要部门的id和名称,如果说部门表有几十个甚至上百个字段,毫无疑问这样做是非常浪费时间以及资源的,所以这个时候我们可能会需要自定义一个满足需求的对象即可,下一节会分享一下如何将查询结果映射到自定义的对象中。