【问题标题】:How to construct a model instance from multiple column with JPA如何使用 JPA 从多列构造模型实例
【发布时间】:2020-02-14 16:22:41
【问题描述】:

我有这种情况,其中有三个实体,每个实体大约有 20 列,假设都是唯一名称,20*3 是 60 个唯一列名称。然后我需要通过加入所有 3 个字段来从中获取一些特定字段,例如 30 个字段。所以我在每个实体中都有映射。然后只选择这 30 个字段,我知道我应该只选择它们,使用多选。但是有没有一种有效的方法来做到这一点?就像不是在我的代码中编写 30 个列名一样,我是否可以有一个定义所有这些字段的模型,然后 在 select 子句中传递这个模型,以便它选择字段或类似的东西。

然后是实体 1:-

public class CourseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
long id;

String name;

String descr;

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "univ_id")
UniversityEntity university;

实体 2:-

public class StudentEntity {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;

@Column(name = "first_name")
private String firstName;

@Column(name = "last_name")
private String lastName;

@Column(name = "grad_year")
private int gradYear;

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "course_id")
CourseEntity courses;

实体 3:-

public class UniversityEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
long id;

String name;

String desrc;

@OneToOne(mappedBy = "university")
CourseEntity courses;
}

我想要的模型对象:-

public class StudentModel {

private int disbursementId;
private String payeeId;
private String courseName;
private String offeredBy;

}

但我担心的地方是, 选择查询:-

    CriteriaQuery<StudentModel> criteriaQuery = cb.createQuery(StudentModel.class);

    Root<StudentEntity> root = criteriaQuery.from(StudentEntity.class);
    Join<StudentEntity, CourseEntity> student_course = root.join("courses");
    Join<CourseEntity, UniversityEntity> university_course = student_course.join("university"); 
    criteriaQuery.multiselect(
            root.get("id").alias("disbursement_id")
            , root.get("firstName").alias("payee_id")
            , student_course.get("name").alias("course_name")
            , university_course.get("name").alias("offered_by")
            )
            .where(cb.equal(root.get("gradYear"), 2015));

    TypedQuery<StudentModel> query = em.createQuery(criteriaQuery);
    List<StudentModel> results = query.getResultList();

我们真的可以通过吗,

    CriteriaQuery<StudentModel> criteriaQuery = cb.createQuery(StudentModel.class);

    Root<StudentEntity> root = criteriaQuery.from(StudentEntity.class);
    Join<StudentEntity, CourseEntity> student_course = root.join("courses");
    Join<CourseEntity, UniversityEntity> university_course = student_course.join("university"); 
    criteriaQuery.multiselect(
            **StudentModel**
            )
            .where(cb.equal(root.get("gradYear"), 2015));

    TypedQuery<StudentModel> query = em.createQuery(criteriaQuery);
    List<StudentModel> results = query.getResultList();

【问题讨论】:

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


    【解决方案1】:

    您可以使用CriteriaBuild#construct 而不是multiselect 来构造模型实例。

    您的模型类必须有一个将所有字段作为参数的构造函数:

    public StudentModel(int disbursementId, String payeeId /**...**/) {/**...**/}
    

    那么你可以这样使用:

    criteriaQuery.select(cb.construct(StudentModel.class, root.get("id"), root.get("firstName") /**...**/));
    

    【讨论】:

    • 用TypedQuery获取是一样的吧?我希望在 select 语句中完全省略 root.get("id"), root.get("firstName"),而是在 StudentModel 本身中有该定义,例如 StudentModel { @Referes("StudentEntity.id") int disbursement_id; } 并让模型定义要从连接表中选择的列
    猜你喜欢
    • 1970-01-01
    • 2020-09-03
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2018-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多