如果我使用带有获取类型LAZY或任何其他jpaMap注解的@ManyToOne,jpa会在Map的实体上运行查询来获取id吗?
比如
部
@Entity
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
private List<Employee> employees = new ArrayList<>();
// Constructors, getters, setters, and other properties
}
员工:
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "department_id", fetch= FetchType.LAZY)
private Department department;
// Constructors, getters, setters, and other properties
}
现在,假设我尝试在Employee上查找by,并尝试从与该雇员对应的部门获取id,Hibernate是否会向Department类发布一个额外的查询,并从employee = 'x'的部门获取id。或者部门id将与employee实体存储在一起,我可以在不增加查询时间的情况下获取它?因为部门ID存在于mysql中的employee表中。
Employee emp = employeeRepository.findByName("John");
String deparmentId = emp.getDeparment().getId(); //Extra query time or not? As Id is stored in the mysql table
emp.getDepartment().getName(); //Does causes extra query
2条答案
按热度按时间eyh26e7m1#
当您使用Spring JPA进行查询时,您将获得表示返回查询值的数据对象的示例。这 * 包括关系数据 *,只要你有适当的注解(你这样做)。
JPA正在将数据库表Map到Entity的示例。在从查询(
findBy
等)中检索实体示例后,任何字段(通过getter/setter)都可以立即访问。比如说。如果您像这样查询单个部门:
反之亦然:
请注意,当您使用
mappedBy
时,您将为Spring JPA提供字段名称,以便它可以在查询时将其与数据对象的示例相关联。希望这对你有帮助。
7cwmlq892#
是的,调用getDepartment()将强制对惰性关系的数据库进行提取。如果getDepartment()调用立即从数据库中获取,或者如果您获得一个代理对象,调用任何内容然后从数据库中获取,这是特定于实现(和配置)的,所以我不会依赖它。如果您希望在只获取Employee示例而不知道部门是否已被获取时访问FK值(“department_id”),请将其直接Map为实体中的基本Long属性。你可以有多个Map到同一个“department_id”,只要你只指定一个为可写的(所以所有其他的为updatable=false,insertable=false)。Ie
这允许您继续在查询中使用和引用department来执行联接,但也允许您直接使用departmentId来避免它们。即:
vs
第一个查询应该强制对部门进行内部联接,而第二个查询则没有。
根据您的应用程序需求,您还可以反转设置“department_id”列值的属性,以便可以通过departmentId设置它-这在您可能希望通过REST合并员工而不必构建回Department对象并处理阅读和合并它们时可能很有用-序列化只需要departmentId long。