如何使用 JPA 从多列构造模型实例

Posted

技术标签:

【中文标题】如何使用 JPA 从多列构造模型实例【英文标题】:How to construct a model instance from multiple column with 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();

【问题讨论】:

【参考方案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; 并让模型定义要从连接表中选择的列

以上是关于如何使用 JPA 从多列构造模型实例的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JPA 从 1 自动生成 id?

JPA,实体管理器,选择多列并获取结果列表自定义对象

如何使用 JPA 1.0 构建一个 JPQL 查询,从多个表中获取数据以克服延迟初始化?

如何在 UWP 中实例化具有构造函数的页面?

如何使用 JPA/Hibernate 注释将 MySQL char(n) 列映射到实例变量?

如何使用JPA实现Spring 授权服务器的核心服务