Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 需要帮助将标准SQL查询转换为JPA条件查询吗_Java_Mysql_Jpa_Criteria Api - Fatal编程技术网

Java 需要帮助将标准SQL查询转换为JPA条件查询吗

Java 需要帮助将标准SQL查询转换为JPA条件查询吗,java,mysql,jpa,criteria-api,Java,Mysql,Jpa,Criteria Api,我有两张桌子: 员工 id firstName lastName . . . 培训 id employeeId trainingName trainingSuspsnseDate trainingComplete 在MySQL Workbench中执行标准SQL查询时,如下所示: SELECT e.id, e.firstName, e.lastName, t.trainingName, t.trainingSuspenseDate, t.trainingComplete FROM Emplo

我有两张桌子:

员工

id
firstName
lastName
.
.
.
培训

id
employeeId
trainingName
trainingSuspsnseDate
trainingComplete
在MySQL Workbench中执行标准SQL查询时,如下所示:

SELECT e.id, e.firstName, e.lastName, t.trainingName, t.trainingSuspenseDate, t.trainingComplete
FROM Employee e
JOIN Training t on t.employeeId = e.id
WHERE t.trainingSuspenseDate < CURDATE()
order by t.trainingSuspenseDate;


编辑:添加了我的模型类 Employee.java

@Entity
@Table(name = "employee")
@XmlRootElement
@NamedQueries(
        {
            @NamedQuery(name = "Employee.findAll", query = "SELECT e FROM Employee e"),
            @NamedQuery(name = "Employee.deleteAll", query = "DELETE FROM Employee e"),
            @NamedQuery(name = "Employee.countAll", query = "SELECT COUNT(e.ID) FROM Employee e")
        })
public class Employee implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @GeneratedValue
    @Column(name = "id")
    private Integer ID;

    @Basic(optional = true)
    @Column(name = "name_first")
    private String firstName;

    @Basic(optional = true)
    @Column(name = "name_last")
    private String lastName;

    @Basic(optional = true)
    @Column(name = "created_date")
    private String employeeDate;

    @Basic(optional = true)
    @Column(name = "personal_type")
    private String personnelType;

    public Employee() {
        ID = 0;
    }

    public Employee(Integer id) {
        this.ID = id;
    }

    public Integer getID() {
        return ID;
    }

    public void setID(Integer id) {
        this.ID = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmployeeDate() {
        return employeeDate;
    }

    public void setEmployeeDate(String employeeDate) {
        this.employeeDate = employeeDate;
    }

    public String getPersonnelType() {
        return personnelType;
    }

    public void setPersonnelType(String personnelType) {
        this.personnelType = personnelType;
    }

}
@Entity
@Table(name = "training")
@XmlRootElement
@NamedQueries(
        {
            @NamedQuery(name = "Training.findAll", query = "SELECT t FROM Training t"),
            @NamedQuery(name = "Training.deleteAll", query = "DELETE FROM Training t"),
            @NamedQuery(name = "Training.countAll", query = "SELECT COUNT(t.ID) FROM Training t")
        })
public class Training implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @GeneratedValue
    @Column(name = "ID")
    private Integer ID;

    @Basic(optional = false)
    @Column(name = "employee_id")
    private String employeeId;

    @Basic(optional = false)
    @Column(name = "training_name")
    private String trainingName;

    @Basic(optional = false)
    @Column(name = "training_suspense_date")
    private Date trainingSuspenseDate;

    @Basic(optional = false)
    @Column(name = "training_complete")
    private Boolean trainingComplete;

    public Integer getID() {
        return ID;
    }

    public void setID(Integer ID) {
        this.ID = ID;
    }

    public String getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(String employeeId) {
        this.employeeId = employeeId;
    }

    public void setTrainingName(String trainingName) {
        this.trainingName = trainingName;
    }

    public String getTrainingName() {
        return trainingName;
    }

    public void setTrainingSuspenseDate(Date trainingSuspsenseDate) {
        this.trainingSuspsenseDate = trainingSuspsenseDate;
    }

    public Date getTrainingSuspenseDate() {
        return trainingSuspsenseDate;
    }

    public void setTrainingComplete(Boolean trainingComplete) {
        this.trainingComplete = trainingComplete;
    }

    public Boolean getTrainingComplete() {
        return trainingComplete;
    }
}
Training.java

@Entity
@Table(name = "employee")
@XmlRootElement
@NamedQueries(
        {
            @NamedQuery(name = "Employee.findAll", query = "SELECT e FROM Employee e"),
            @NamedQuery(name = "Employee.deleteAll", query = "DELETE FROM Employee e"),
            @NamedQuery(name = "Employee.countAll", query = "SELECT COUNT(e.ID) FROM Employee e")
        })
public class Employee implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @GeneratedValue
    @Column(name = "id")
    private Integer ID;

    @Basic(optional = true)
    @Column(name = "name_first")
    private String firstName;

    @Basic(optional = true)
    @Column(name = "name_last")
    private String lastName;

    @Basic(optional = true)
    @Column(name = "created_date")
    private String employeeDate;

    @Basic(optional = true)
    @Column(name = "personal_type")
    private String personnelType;

    public Employee() {
        ID = 0;
    }

    public Employee(Integer id) {
        this.ID = id;
    }

    public Integer getID() {
        return ID;
    }

    public void setID(Integer id) {
        this.ID = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmployeeDate() {
        return employeeDate;
    }

    public void setEmployeeDate(String employeeDate) {
        this.employeeDate = employeeDate;
    }

    public String getPersonnelType() {
        return personnelType;
    }

    public void setPersonnelType(String personnelType) {
        this.personnelType = personnelType;
    }

}
@Entity
@Table(name = "training")
@XmlRootElement
@NamedQueries(
        {
            @NamedQuery(name = "Training.findAll", query = "SELECT t FROM Training t"),
            @NamedQuery(name = "Training.deleteAll", query = "DELETE FROM Training t"),
            @NamedQuery(name = "Training.countAll", query = "SELECT COUNT(t.ID) FROM Training t")
        })
public class Training implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @Basic(optional = false)
    @GeneratedValue
    @Column(name = "ID")
    private Integer ID;

    @Basic(optional = false)
    @Column(name = "employee_id")
    private String employeeId;

    @Basic(optional = false)
    @Column(name = "training_name")
    private String trainingName;

    @Basic(optional = false)
    @Column(name = "training_suspense_date")
    private Date trainingSuspenseDate;

    @Basic(optional = false)
    @Column(name = "training_complete")
    private Boolean trainingComplete;

    public Integer getID() {
        return ID;
    }

    public void setID(Integer ID) {
        this.ID = ID;
    }

    public String getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(String employeeId) {
        this.employeeId = employeeId;
    }

    public void setTrainingName(String trainingName) {
        this.trainingName = trainingName;
    }

    public String getTrainingName() {
        return trainingName;
    }

    public void setTrainingSuspenseDate(Date trainingSuspsenseDate) {
        this.trainingSuspsenseDate = trainingSuspsenseDate;
    }

    public Date getTrainingSuspenseDate() {
        return trainingSuspsenseDate;
    }

    public void setTrainingComplete(Boolean trainingComplete) {
        this.trainingComplete = trainingComplete;
    }

    public Boolean getTrainingComplete() {
        return trainingComplete;
    }
}

我可以看出,您已经为您的查询生成了一个元模型。 因此,最好的方法是扩展实体定义,如下所示:

您必须在
培训
课程中添加映射:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "employeeId")
private Employee employee;
然后在您的
Employee
类中添加站点引用:

@OneToMany(mappedBy = "employee")
private Set<Training> trainings = new HashSet<>();
@OneToMany(mappedBy=“employee”)
私有集=新HashSet();
然后将条件查询更改为:

Join<Employee, Training> training = employee.join(Employee_.trainings);
Join training=employee.Join(员工培训);

您可以尝试
交叉连接
。本机sql有点不同,但结果与预期的一样

CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Employee> employeeQuery = builder.createQuery(Employee.class);
Root<Employee> employee = employeeQuery.from(Employee.class);
Root<Employee> training= employeeQuery.from(Training.class);

employeeQuery.select(builder.construct(Employee.class,
    employee.get(Employee_.ID),
    employee.get(Employee_.firstName),
    employee.get(Employee_.lastName),
    training.get(Training_.trainingName),
    training.get(Training_.trainingSuspsnseDate),
    training.get(Training_.trainingComplete)))
.where(builder.equal(employee.get(Employee_.ID), training.get(Training_.employeeId)));
CriteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery employeeQuery=builder.createQuery(Employee.class);
Root employee=employeeQuery.from(employee.class);
Root training=employeeQuery.from(training.class);
employeeQuery.select(builder.construct(Employee.class、,
employee.get(employee.ID),
employee.get(employee.firstName),
employee.get(employee.lastName),
training.get(training\uu.trainingName),
培训。获取(培训\培训USPSN镇静),
培训。获取(培训完成)
.where(builder.equal(employee.get(employee.ID)),training.get(training.employeeId));

查看您的模型类,实体没有直接关联(即使
培训中的
employeeId
应该是外键,但在实体关系中没有定义为外键。因此,如果您希望在不更改现有实体的情况下使用现有实体,您需要以下内容-

  • 根据select子句映射属性的POJO(例如EmpRes)。应将此POJO上的criteriaQuery初始化为-
  • CriteriaQuery CriteriaQuery=builder
    .createQuery(EmpRes.class);

  • 由于实体是不相关的,因此生成的查询将具有交叉连接
  • 代码看起来像-

            criteriaQuery.select(builder.construct(EmpRes.class, employee
            .get(Employee_.getAttribute("ID").getName()), employee
            .get(Employee_.getAttribute("firstName").getName()), employee
            .get(Employee_.getAttribute("lastName").getName()), training
            .get(Training_.getAttribute("trainingName").getName()),
            training.get(Training_.getAttribute("trainingSuspenseDate")
                    .getName()), training.get(Training_.getAttribute(
                    "trainingComplete").getName())));
    
            criteriaQuery.where(builder.equal(employee.get("ID"), training.get("employeeId")));
            List<EmpRes> employees = entityManager.createQuery(criteriaQuery).getResultList();
    
    然后,您可以根据自己的需求添加额外的where子句。
    标准API的一个很好的参考是。

    此错误消息-不兼容类型:推理变量Y具有不兼容的等式约束-表明您需要仔细检查要加入的列的数据类型。在=的两侧,数据类型应该是相同的,以便进行性能和高速比较。

    是否可以w员工和培训实体?@SB我已经添加了我的模型类。谢谢。只有一名员工需要培训的培训?什么是
    私有集
    ?我没有用户类。应该是Training@Brian您是否发现数据类型存在差异并提高了性能?
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "employeeId")
    private Employee employee;
    
    @OneToMany(mappedBy = "employee")
    private Set<Training> trainings = new HashSet<>();
    
    Join<Employee, Training> training = employee.join(Employee_.trainings);
    
    CriteriaBuilder builder = entityManager.getCriteriaBuilder();
    CriteriaQuery<Employee> employeeQuery = builder.createQuery(Employee.class);
    Root<Employee> employee = employeeQuery.from(Employee.class);
    Root<Employee> training= employeeQuery.from(Training.class);
    
    employeeQuery.select(builder.construct(Employee.class,
        employee.get(Employee_.ID),
        employee.get(Employee_.firstName),
        employee.get(Employee_.lastName),
        training.get(Training_.trainingName),
        training.get(Training_.trainingSuspsnseDate),
        training.get(Training_.trainingComplete)))
    .where(builder.equal(employee.get(Employee_.ID), training.get(Training_.employeeId)));
    
            criteriaQuery.select(builder.construct(EmpRes.class, employee
            .get(Employee_.getAttribute("ID").getName()), employee
            .get(Employee_.getAttribute("firstName").getName()), employee
            .get(Employee_.getAttribute("lastName").getName()), training
            .get(Training_.getAttribute("trainingName").getName()),
            training.get(Training_.getAttribute("trainingSuspenseDate")
                    .getName()), training.get(Training_.getAttribute(
                    "trainingComplete").getName())));
    
            criteriaQuery.where(builder.equal(employee.get("ID"), training.get("employeeId")));
            List<EmpRes> employees = entityManager.createQuery(criteriaQuery).getResultList();
    
    Join<Employee, Training> trainingJoin = employee.join(Employee_.getAttribute("trainings").getName());
    criteriaQuery.select(builder.construct(EmpRes.class, employee
            .get(Employee_.getAttribute("ID").getName()), employee
            .get(Employee_.getAttribute("firstName").getName()), employee
            .get(Employee_.getAttribute("lastName").getName()),
            trainingJoin.get(Training_.getAttribute("trainingName")
                    .getName()), trainingJoin.get(Training_.getAttribute(
                    "trainingSuspenseDate").getName()), trainingJoin
                    .get(Training_.getAttribute("trainingComplete")
                            .getName())));