如何通过JPA从联接的第二张表中检索特定行

时间:2019-05-25 10:13:11

标签: java spring-boot jpa spring-data-jpa

我有两个表,一个是customer,另一个是customerDepartment。客户与customerDepartment有一对多的关系。

我有一个特定的搜索条件,我需要搜索部门名称,如果等于,则需要检索所有客户部门行,包括客户。

这就是我试图得到的结果

public interface CustomerRepository extends JpaRepository<Customer,Integer>{


    @Query(value="select DISTINCT c from Customer c left join c.custDept cd where cd.deptName like %?1% ")
    Page<Customer> findByName(String name, Pageable pageable);

}

客户

@Entity
@Table(name="customer")
public class Customer implements Serializable{


    private static final long serialVersionUID = 1L;

    @Id
    @Column(name= "customer_no",updatable = false, nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private int customerNo;

    @Column(name= "customer_name")
    private String customerName;

    @Column(name= "industry")
    private String industry;

     @JsonManagedReference
     @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, 
     fetch=FetchType.LAZY)
     private Set<CustomerDepartment> custDept;

}

客户部门:

@Entity
@Table(name = "customer_department")
public class CustomerDepartment implements Serializable{

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "dept_id",updatable = false, nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private int depId;

    @Column(name = "dept_name")
    private String deptName;

    @Column(name = "primary_contact")
    private String primaryContact;

      @JsonBackReference
      @ManyToOne(fetch=FetchType.LAZY)
      @JoinColumn(name = "customer_no", nullable = false)
      private Customer customer;

}

当我搜索DepartmentName = it时,上述JPA查询返回以下结果

{
    "content": [
        {
            "customerNo": 33,
            "customerName": "Test1",
            "industry": "High-Tech",
            "country": "Australia",
            "state": "Sa-Jose",
            "city": "Sydney",
            "custDept": [
                {
                    "depId": 34,
                    "deptName": "It",
                    "primaryContact": "Banglore,Kormangala",
                },
                {
                    "depId": 35,
                    "deptName": "sales",
                    "primaryContact": "Banglore,Kormangala",

                }
            ]
        }
    ]
}   

我期望的更像是

{
    "content": [
        {
            "customerNo": 33,
            "customerName": "Test1",
            "industry": "High-Tech",
            "country": "Australia",
            "state": "Sa-Jose",
            "city": "Sydney",
            "custDept": [
                {
                    "depId": 34,
                    "deptName": "It",
                    "primaryContact": "Banglore,Kormangala",
                }
            ]
        }
    ]
}   

如果这在JPA中是不可能的,有什么办法可以做到这一点。 感谢您的帮助

1 个答案:

答案 0 :(得分:0)

是的,我是这样认为的。我评论说:“我认为您的查询是可以的,但是当将结果编组为JSON时,将检索所有关联部门。您应在编组之前查看sql输出并调试并检查查询结果,以了解是否案子。”我继续研究它,我或多或少是正确的。

问题是您没有获取查询的custDept集合,因此当客户被编组以获取其余响应时,将执行附加查询以获取值,附加查询仅查询所有内容。

  
    

2019-05-25 14:29:35.566调试63900 --- [nio-8080-exec-2] org.hibernate.SQL:选择不同的customer0_.customer_no作为customer1_0_,customer0_.customer_name作为customer2_0_,customer0_.industry作为来自客户customer0_的行业3_0_,从左外部加入了customer0_.customer_no = custdept1_.customer_no上的customer_department custdept1_,其中custdept1_.dept_name喜欢吗?限制?

         

2019-05-25 14:29:35.653调试63900 --- [nio-8080-exec-2] org.hibernate.SQL:选择custdept0_.customer_no作为customer4_1_0_,custdept0_.dept_id作为dept_id1_1_0_0,custdept0_.dept_id作为customer4_1_0_ dept_id1_1_1_1,custdept0_.customer_no作为customer4_1_1_,custdept0_.dept_name作为dept_nam2_1_1_,custdept0_.primary_contact作为primary_3_1_1_来自customer_department custdept0_,其中custdept0_.customer_no =?

  

如果仅需要查询提供的内容,则需要进行提取,以便custDept集在被编组之前被初始化。您的查询还存在其他问题。您应该使用sql参数:deptName并声明它,并且应该提供countQuery,因为您要返回Page

public interface CustomerRepository extends JpaRepository<Customer,Integer>{
    @Query(value="select DISTINCT c from Customer c left join fetch c.custDept cd where cd.deptName like %:deptName% ", 
            countQuery = "select count ( DISTINCT c ) from Customer c left join c.custDept cd where cd.deptName like %:deptName% ")
    public Page<Customer> findByName(@Param("deptName") String deptName, Pageable pageable);

为我工作。现在只执行原始查询,结果正确。

{
"content": [
    {
        "customerNo": 1,
        "custDept": [
            {
                "deptName": "it"
            }
        ]
    }
],

最后请注意,根据春季文档,最好将Integer用于实体中的@Id