chr*_*isw 4 java database orm hibernate
我相信我误解了如何选择和渴望工作; 我的目标是在遇到N + 1问题时提高性能
编辑我想知道我是否会更快地使用create SQL查询方法并自己创建对象,尽管我希望hibernate与性能相提并论.我可以在单个查询中拉回下面示例中所需的所有数据,那么为什么hibernate会为每个查询执行单独的查询?
我创建了以下测试用例来突出我的问题,请原谅这个模型的粗糙.
@Entity
@Table(name = "Area")
public class Area implements Serializable
{
@Id
@GeneratedValue(generator = "areaId" )
@GenericGenerator(name = "areaId", strategy = "uuid2")
public String areaId;
@OneToMany(mappedBy = "area", fetch=FetchType.EAGER)
@Fetch(FetchMode.SUBSELECT)
public Set<EmployeeArea> employeeAreas = new HashSet<EmployeeArea>();
}
@Entity
@Table(name = "Employee")
public class Employee implements Serializable
{
@Id
@GeneratedValue(generator = "employeeId" )
@GenericGenerator(name = "employeeId", strategy = "uuid2")
public String employeeId;
@OneToMany(mappedBy = "employee", fetch=FetchType.EAGER)
@Fetch(FetchMode.SUBSELECT)
public Set<EmployeeArea> employeeAreas = new HashSet<EmployeeArea>();
}
@Entity
@Table(name = "EmployeeArea")
public class EmployeeArea implements Serializable
{
@Id
@GeneratedValue(generator = "employeeAreaId" )
@GenericGenerator(name = "employeeAreaId", strategy = "uuid2")
public String employeeAreaId;
@Id
@ManyToOne
public Employee employee;
@Id
@ManyToOne
public Area area;
}
Run Code Online (Sandbox Code Playgroud)
然后我填写了一些样本测试数据: -
Employee employee = new Employee();
Area area = new Area();
EmployeeArea employeeArea = new EmployeeArea();
employeeArea.area = area;
employeeArea.employee = employee;
session.save(employee);
session.save(area);
session.save(employeeArea);
Run Code Online (Sandbox Code Playgroud)
这可以运行几次以提供一些数据.
然后我执行以下操作: -
session.createQuery("FROM Employee e INNER JOIN e.employeeAreas ea INNER JOIN ea.area").list();
Run Code Online (Sandbox Code Playgroud)
我加入JOIN的原因是我可以进行专业搜索.我在看标准,但似乎它不允许我用WHERE做我能做的一切
我希望它最多可以进行3次查询和2次子查询.
事实上,对于前面提到的测试数据的6个输入,我似乎为一个员工获得了6个选择,6个选择了一个区域,看起来像我假定的'1'查询.然后是两个看起来完全错误的大型查询: -
Run Code Online (Sandbox Code Playgroud)select employeear0_.employee_employeeId as employee2_3_2_, employeear0_.employeeAreaId as employee1_4_2_, employeear0_.employee_employeeId as employee2_4_2_, employeear0_.area_areaId as area3_4_2_, employeear0_.employeeAreaId as employee1_4_1_, employeear0_.employee_employeeId as employee2_4_1_, employeear0_.area_areaId as area3_4_1_, area1_.areaId as areaId1_0_0_ from EmployeeArea employeear0_ inner join Area area1_ on employeear0_.area_areaId=area1_.areaId where employeear0_.employee_employeeId in ( select employee1_.employeeId from EmployeeArea employeear0_ inner join Employee employee1_ on employeear0_.employee_employeeId=employee1_.employeeId where employeear0_.area_areaId in ( select area2_.areaId from Employee employee0_ inner join EmployeeArea employeear1_ on employee0_.employeeId=employeear1_.employee_employeeId inner join Area area2_ on employeear1_.area_areaId=area2_.areaId ) )
然后是一个非常相似的区域.
我的目标是能够使用返回列表中的每个员工对象来识别工作区域.每个实体中会有更多字段,但是这个测试用例已经简化了.
我解决了这个问题; 这是我的联接表的一个问题.请参阅以下内容: -
@Id
@ManyToOne
public Employee employee;
@Id
@ManyToOne
public Area area;
Run Code Online (Sandbox Code Playgroud)
我使用了@Id导致了抛出的StackOverflowError异常.使用以下查询,在Employee上获取EAGER和@Fetch JOIN的OneToMany,以及在Area上获取LAZY和@Fetch SELECT的OneToMany,然后我可以执行以下查询: -
List<Employee> employees = session.createQuery("FROM Employee e INNER JOIN FETCH e.employeeAreas ea INNER JOIN FETCH ea.area").list();
Run Code Online (Sandbox Code Playgroud)
虽然能够在其中一个连接表列上使用WHERE.
| 归档时间: |
|
| 查看次数: |
6634 次 |
| 最近记录: |