实现了一对多关系,并且工作正常。
我的问题是当我运行以下查询时,如果该表有100个员工行,并且每个员工有2个部门。数据库查询被调用了101次,因为对于每个员工来说它正在调用部门查询,完成调用所有100行需要很长时间,是否可以建议任何替代解决方案?
请参阅下面的详细信息
查询它正在调用:
First query is : SELECT * FROM Employee e
Next 100 queries : SELECT * FROM DEPARTMENT d WHERE d.EmployeeId=?
JPA数据库电话:
javax.persistence.Query query = em.createNamedQuery("SELECT * FROM Employee e", Employee.class);
return query.getResultList();
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.NamedNativeQueries;
import javax.persistence.NamedNativeQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
@Entity
@Table(name = "EMPLOYEE")
public class Employee implements Serializable
{
@Id
@Column(name = "EmployeeId")
String employeeId;
@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Department> departments;
public List<Department> getDepartments() {
return departments;
}
public void setDepartments(List<Department> departments) {
this.departments = departments;
}
public String getEmployeeId() {
return employeeId;
}
public void setEmployeeId(String employeeId) {
this.employeeId = employeeId;
}
}
@Entity
@Table(name = "DEPARTMENT")
public class Department implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@Column(name = "DepartmentID")
String departmentId;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "EmployeeId", insertable = false, updatable = false)
private Employee employee;
}
输出xml:
<Employees>
<Employee>
<name>Rob</name>
<Departments>
<Departmnet><id>1</id></Departmnet>
<Departmnet><id>2</id></Departmnet>
</Departments>
</Employee>
<Employee>
<name>Sam</name>
<Departments>
<Departmnet><id>1</id></Departmnet>
<Departmnet><id>2</id></Departmnet>
</Departments>
</Employee>
</Employees>
答案 0 :(得分:4)
这是典型的N+1 selects issue。我通常使用described here和here
JOIN FETCH
次查询解决此问题
答案 1 :(得分:1)
您可以将fetchtype切换为lazy,这将导致仅在必要时查询部门。
@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Department> departments;
答案 2 :(得分:1)
将FetchType.EAGER
更改为FetchType.LAZY
。仅在需要时加载部门,例如循环employee.getDepartmentList()
for(Department dept:employeeGetDepartmentList()){
dept.getId();
}
在使用部门之前
答案 3 :(得分:1)
经典N + 1问题。 您可以使用Batch Fetching减少查询次数,这只会将许多惰性sql子句组合成单个。
例如:
@OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@BatchSize(size=10)
private List<Department> departments;