【问题标题】:How to match columns of tables using JPA如何使用 JPA 匹配表的列
【发布时间】:2020-05-21 09:34:43
【问题描述】:

我只是想学习 JPA。我有三个实体类看起来像这样。实体类中提到了关系

@Entity
@Table(name="EMPLOYEE")
public class Employee {
    @Id
    @Column(name="EMP_ID")
    private Integer empId;
    @Column(name="EMP_NAME")
    private String empName;
    @Column(name="EMP_ADDR")
    private String address;
    @OnetoOne
    @JoinColumn(name="PROJ_ID")
    private Project project;
    @OnetoOne
    @JoinColumn(name="TASK_ID")
    private Task task;

}

@Entity
@Table(name="PROJECT")
public class Project {
    @Id
    @Column(name="PROJ_ID")
    private Integer projectId;
    @Column(name="PROJ_NAME")
    private String projectName;
    @Column(name="PROJ_STATUS")
    private String projectStatus;

}

@Entity
@Table(name="TASK")
public class Task {
    @Id
    @Column(name="TASK_ID")
    private Integer taskId;
    @Column(name="TASK_NAME")
    private String taskName;
    @Column(name="TASK_STATUS")
    private String taskStatus;

}

我的预期查询是select * from Employee a , Task b where a.proj_id= ? and a.task_id=b.task_id

在我的员工存储库类中,我有一个方法

findEmployeeByProjectProjectId(int projectId).

但我得到了一些多余的数据,不知道如何处理a.task_id=b.task_id 的情况。

不确定我做错了什么。请提出解决方案,或者如果我做错了什么,请纠正我。

【问题讨论】:

  • 只是一个简单的问题,您想要的预期输出是什么? EMPLOYEE & PROJECT 的所有数据或只有 EMPLOYEE 有任务的人
  • 仅来自有任务的员工
  • 如果可能的话,如果任务名称也显示在里面就好了。

标签: hibernate spring-boot jpa spring-data


【解决方案1】:

您在Employee-ProjectEmployee-Task 之间有@OneToOne 映射。

@OneToOne 的默认 Fetch 策略为 EAGER。因此,无论何时您将 FETCH Employee 实体,关联的 ProjectTask 实体(如果不为空)也将在同一个查询中获取。您不需要 where 子句 e.task_id=b.task_id。

    /* Repository method */
    /*Function 1*/
    @Query("Select E FROM Employee E WHERE E.project.PROJ_ID = :projID")
    Employee findByProject( @Param("projID") Integer projID);
    /*Function 2*/
    Employee findByProject( Project project); // This method can be used by passing a managed object of project.

   /*Usage of repository call*/
   Employee e = employeeRepo.findByProject(projectId); // Function 1
   Task t = e.getTask(); // this will not cause a query because Task was EAGERLY loaded with Employee entity.
   Project p = e.getProject(); // this will not cause a query because Task was EAGERLY loaded with Employee entity. 

注意:第二个接受 Project 对象的函数不应该像这样使用:

     Project p=new Project();
     p.setPROJ_ID(projID);
     employeeRepo.findByProject(p); // Function 2 This will throw Exception stating that p is transient which cannot be used for querying.

要使用第二种方法,我们可以加载项目代理,然后使用它。

    Project p = entityManager.getReference(Project.class, projId);
    employeeRepo.findByProject(p); // Now this is okk

【讨论】:

    【解决方案2】:

    您必须将您的存储库方法更改为 findEmployeeByProject(Project project)。然后添加到 ProjectRepo findById,并在 Employee 的服务层中按 id 查找项目并将此 Project 用作​​您的 findEmployeeByProject(Project project) 的参数。

    【讨论】:

    • 我没有尝试这个,而是在尝试之前问你一个问题。我将如何实现 employee.task_id= task.task_id ?
    • EmployeeRepo中的FindByTask(Task task),作为task->TaskRepo中的FindById,实现服务层
    • 这是预期的查询 select a.emp_id, a.emp_name, b.task_name from Employee a , Task b where a.proj_id= ?和 a.task_id=b.task_id。不会很快得到它吗?而不是更好地使用本机查询 rt?。只是征求专家意见。
    • 通过 JPA,您无法在一个简短的关系实体中做到这一点。我认为最好使用 hibernate 及其方法,或者使用本机查询。
    • 带有 Nativequery 的 JPA 工作正常。所以我明白这是 JPA rt 的主要缺点?我不确定休眠。
    猜你喜欢
    • 1970-01-01
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-08
    • 2015-11-06
    • 1970-01-01
    • 2020-10-25
    相关资源
    最近更新 更多