0

所以我有4张桌子

雇主

 @Entity

 @EqualsAndHashCode(callSuper = false)
 @Table(name = "employers")

 @NoArgsConstructor
 @AllArgsConstructor
 @JsonIgnoreProperties({"hibernateLazyInitializer", "handler", "jobPostings"})
 @PrimaryKeyJoinColumn(name="employer_id", referencedColumnName = "id")
 public class Employer extends User {
  
  @Column(name = "company_name")
  private String companyName;

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

  @Column(name = "phone_number")
  private String phoneNumber;
  
  @OneToMany(mappedBy="employer")
  private List<JobPosting> jobPostings;
  }

一座城市

@Data
@Entity
@Table(name="cities")
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler", "jobPostings"})
public class City {

    @Id
    @Column(name="id")
    private int id;
    
    @Column(name="city_name")
    private String cityName;
    
    @OneToMany(mappedBy="city")
    private List<JobPosting> jobPostings;
}

工作职位

@AllArgsConstructor
@Data
@Entity
@Table(name="job_positions")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler", "jobPostings"})
public class JobPosition {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="job_position_id")
    private int id;
    
    @Column(name="title")
    private String title;
    
    @OneToMany(mappedBy="jobPosition")
    private List<JobPosting> jobPostings;
    
    
}

还有一个 JobPosting(如招聘广告)

@Entity
@Table(name="job_postings")
@Data
@NoArgsConstructor
@AllArgsConstructor
//@JsonIgnoreProperties({"hibernateLazyInitializer", "handler", "city", "jobPosition","employer"})

public class JobPosting {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    private int id;
    
    
    
    @Column(name="job_requirements")
    private String jobRequirements;
    
    @Column(name="salary_min")
    private int salaryMin;
    
    @Column(name="salary_max")
    private int salaryMax;
    
    @Column(name="application_deadline")
    private LocalDate applicationDeadline;
    
    @Column(name="number_of_openings")
    private int numberOfOpenings;
    
    @Column(name="stream_date")
    private LocalDate streamDate;
    
    
    @ManyToOne()
    @JoinColumn(name="city_id")
    private City city;
    
    
    @ManyToOne()
    @JoinColumn(name="job_position_id")
    private JobPosition jobPosition;
    
    @ManyToOne()
    @JoinColumn(name= "employer_id")
    private Employer employer;
        
}

我已经为所有这些实现了必要的映射,并且工作正常。但是,我想将他们加入 DTO,例如:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class JobPostingWithJobPositionCityEmployerDto {

    private int id;
    
    private String jobRequirements;

    private int salaryMin;

    private int salaryMax;

    private LocalDate applicationDeadline;

    private int numberOfOpenings;

    private LocalDate streamDate;

    private String cityName;

    private String title;

    private String companyName;
}

为了以更干净的方式获取我想要的字段,我正在尝试使用 springframework.jpa 的 @Query 注释,但由于我刚刚了解到这一点,所以我无法完全管理它,我正在使用的查询是:

@Query(value ="Select new kodlamaio.hrms.entities.dtos.JobPostingWithJobPositionCityEmployerDto"
            + "(j.id, j.jobRequirements, j.salaryMin, j.salaryMax, j.numberOfOpenings, j.streamDate, j.applicationDeadline, c.cityName, p.title, e.companyName)"
            + " From Employer e Inner Join e.jobPostings j, "
            + "From City c Inner Join c.jobPostings j, "
            + "From JobPosition p Inner Join p.jobPostings j", nativeQuery = true)
    List<JobPostingWithJobPositionCityEmployerDto> getJobPostings();

我什至不知道这是否是正确的方法,我不断收到语法错误,我查找了答案但无法完全理解他们在说什么,有很多不同的场景。因此,如果有人可以帮助我处理这个查询并推荐一些资源来了解不同的命令,我将非常感激,在此先感谢。

4

2 回答 2

0

一般来说,这被命名为Projection,我相信您已经创建JobPostingWithJobPositionCityEmployerDto了一个 10 个参数的构造函数,当然还有它们各自的数据类型。而且由于它是 jpa 的自定义,因此您不能使用nativeQuery = true. 这些修改应该没问题。

@vlad-mihalcea 救援 https://vladmihalcea.com/the-best-way-to-map-a-projection-query-to-a-dto-with-jpa-and-hibernate/

于 2021-06-10T06:05:03.403 回答
0

使用查询中的关键字将查询结果与 DTO 映射new仅适用于 JPQL,它不适用于 SQL(这是您正在使用的)。

如果您尝试编写一个过于复杂的查询,它也会在我看来,因为所有内容都可以通过JobPosting该类实现/达到,这将在使用 JPQL 时隐式执行连接。

因此,与其编写原生 SQL,不如编写 JPQL 来修复它。

就像是

@Query(value ="Select new kodlamaio.hrms.entities.dtos.JobPostingWithJobPositionCityEmployerDto"
            + "(jp.id, jp.jobRequirements, jp.salaryMin, jp.salaryMax, jp.numberOfOpenings, jp.streamDate, jp.applicationDeadline, jp.city.cityName, jp.jobPosition.title, jp. employer.companyName)"
            + " From JobPosting jp)

哪个应该可以解决问题。您的 JPA 提供者应该足够聪明,能够弄清楚要加入和检索的内容。

于 2021-06-10T05:46:24.783 回答