java在使用转换器将实体映射到DTO时获取实体内的集合
我有一个实体叫做学生
@Entity
@Table(name = "students")
public class Student implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "STUDENT_ID")
private Integer studentId;
@Column(name = "STUDENT_NAME", nullable = false, length = 100)
private String studentName;
@OneToMany(fetch = FetchType.EAGER, mappedBy = "student", cascade = CascadeType.ALL)
private List<Note> studentNotes;
// Some other instance variables that are not relevant to this question
/* Getters and Setters */
}
还有一个叫做Note的实体
@Entity
@Table(name = "notes")
public class Note implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "NOTE_ID")
private Integer noteId;
@Column(name = "NOTE_CONTENT")
private String noteText;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "STUDENT_ID")
private Student student;
/* Getters and Setters */
}
正如你所见,这种关系决定了一个学生可以有多张笔记
为了在特定页面上显示有关该学生的一些信息,我只需要studentName、笔记计数和所有笔记。 我为此创建了一个StudentDTO,它看起来像这样:
public class StudentDTO {
private Long count;
private String name;
private List<Note> notes;
/* Getters and setters */
}
我使用以下代码将从DB返回的Student和Notes映射到StudentDTO
private static void testDTO() {
Session session = getSessionFactory().openSession();
String queryString = "SELECT count(n) as count, s.studentName as name, s.studentNotes as notes " +
"from Student s join s.studentNotes n where s.id = 3";
Query query = session.createQuery(queryString);
List<StudentDTO> list = query.setResultTransformer(Transformers.aliasToBean(StudentDTO.class)).list();
for (StudentDTO u : list) {
System.out.println(u.getName());
System.out.println(u.getCount());
System.out.println(u.getNotes().size());
}
}
当在查询中获取注释时,上面的代码会失败,但是如果我删除注释并只获取名称和计数,它就可以正常工作
当查询中包含notes时,这是Hibernate触发的错误:
select
count(studentnot2_.NOTE_ID) as col_0_0_,
. as col_3_0_,
studentnot3_.NOTE_ID as NOTE_ID1_2_,
studentnot3_.NOTE_CONTENT as NOTE_CON2_2_,
studentnot3_.STUDENT_ID as STUDENT_3_2_
from
students studentx0_
inner join
notes studentnot2_
on studentx0_.STUDENT_ID=studentnot2_.STUDENT_ID
inner join
notes studentnot3_
on studentx0_.STUDENT_ID=studentnot3_.STUDENT_ID
where
studentx0_.STUDENT_ID=3;
这是我得到的错误信息:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as col_3_0_, studentnot3_.NOTE_ID as NOTE_ID1_2_, studentnot3_.NOTE_CONTENT as N' at line 1
现在我可以看到查询哪里出错了,但它是由Hibernate生成的,而不是我可以控制的。在我的查询字符串中是否有我需要更改的内容,以获得我需要的结果
我不想手动将结果映射到我的DTO,是否有一种方法可以直接将我的studentNotes映射到Student中。java到StudentDTO中的notes。爪哇
# 1 楼答案
您的查询是错误的,因为还需要两个联接来选择notes的计数,但这甚至不是必需的,因为您可以通过使用notes集合的大小来确定计数
我为这个用例创建了Blaze-Persistence Entity Views。实际上,您将JPA实体的DTO定义为接口,并将其应用于查询。它支持映射嵌套的DTO、集合等,基本上是您所期望的一切,而且最重要的是,它将提高您的查询性能,因为它将生成只获取DTO实际需要的数据的查询
示例中的实体视图可能如下所示
查询可能是这样的
# 2 楼答案
看起来这个查询是错误的。更好的方法是只找学生。你总能从学生那里得到一系列笔记
而且,我从未在SELECT子句中以这种方式检索集合;所以,不确定,但你真的需要吗
在你的询问中?我不确定我的回答是否有用