Java Spring 投影内投影
Java Spring projection inside projection
是否可以使用投影并在一些相关对象中使用它自己的投影?
例如,一个有 Exam
,那个有 List<Question>
。我想请求一份考试列表(我有一个 @projection
),但我想为每个相关 Question
定义要检索的属性
如果我理解正确的话,您想使用 Projection 作为 Projection 的子项。如果是这样,是的,你可以。您可以创建一个 QuestionProjection 并在 ExamProjection 中使用。
示例:
@Projection(name = "questionProjection", types = { Question.class })
public interface QuestionProjection {
// Getters
}
@Projection(name = "examProjection", types = { Exam.class })
public interface ExamProjection {
List<QuestionProjection> getQuestionList();
// Other Getters
}
你可以这样做:
假设您的 Exam
实体可能是:
@Entity
@Table(name = "EXAM")
public class Exam implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
@Column(name = "DESCR")
private String descr;
@OneToMany(mappedBy = "exam")
private List<Question> questions;
// Getters and Setters
和您的 Question
实体
@Entity
@Table(name = "QUESTION")
public class Question implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
@Column(name = "DESCR")
private String descr;
@Column(name = "CONT")
private String cont;
@ManyToOne
@JoinColumn(name = "EXAM_ID")
@JsonIgnoreProperties("questions")
private Exam exam;
所以,创建投影
public interface ExamProjection {
Long getId();
String getDescr();
List<QuestionProjection> getQuestions();
}
和
public interface QuestionProjection {
Long getId();
String getDescr();
}
您的存储库
@Repository
public interface ExamRepository extends JpaRepository<Exam, Long> {
List<Exam> findAll();
@Query("SELECT e FROM Exam e")
List<ExamProjection> findAllProjection();
}
观察到使用 findAll()
方法并将列表类型作为 ExamProjection 传递时,出于某种原因,会导致不兼容的 return 类型错误。为避免这种情况,请创建一个自定义方法,在本例中为 findAllProjection()
.
服务
@Service
public class ExamService {
@Autowired
ExamRepository examRepository;
public List<ExamProjection> findAllProjection() {
return examRepository.findAllProjection();
}
}
最后,资源
@RestController
@RequestMapping(value = "/exam")
public class ExamResource {
@Autowired
ExamService examService;
@GetMapping
public ResponseEntity<List<ExamProjection>> findAll() {
return ResponseEntity.ok().body(examService.findAllProjection());
}
}
使用上面的方法,json returned 不包含字段 cont
,因为 de QuestionProjection
没有方法 getCont()
.
[
{
"id": 1,
"descr": "First Exam",
"questions": [
{
"id": 1,
"descr": "First Question"
},
{
"id": 2,
"descr": "Second Question"
}
]
}
]
如果 QuestionProjection
更改为
public interface QuestionProjection {
Long getId();
String getCont();
}
json returned 更改为
[
{
"id": 1,
"descr": "First Exam",
"questions": [
{
"id": 1,
"cont": "First Question Content"
},
{
"id": 2,
"cont": "Second Question Content"
}
]
}
]
是否可以使用投影并在一些相关对象中使用它自己的投影?
例如,一个有 Exam
,那个有 List<Question>
。我想请求一份考试列表(我有一个 @projection
),但我想为每个相关 Question
如果我理解正确的话,您想使用 Projection 作为 Projection 的子项。如果是这样,是的,你可以。您可以创建一个 QuestionProjection 并在 ExamProjection 中使用。
示例:
@Projection(name = "questionProjection", types = { Question.class })
public interface QuestionProjection {
// Getters
}
@Projection(name = "examProjection", types = { Exam.class })
public interface ExamProjection {
List<QuestionProjection> getQuestionList();
// Other Getters
}
你可以这样做:
假设您的 Exam
实体可能是:
@Entity
@Table(name = "EXAM")
public class Exam implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
@Column(name = "DESCR")
private String descr;
@OneToMany(mappedBy = "exam")
private List<Question> questions;
// Getters and Setters
和您的 Question
实体
@Entity
@Table(name = "QUESTION")
public class Question implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Long id;
@Column(name = "DESCR")
private String descr;
@Column(name = "CONT")
private String cont;
@ManyToOne
@JoinColumn(name = "EXAM_ID")
@JsonIgnoreProperties("questions")
private Exam exam;
所以,创建投影
public interface ExamProjection {
Long getId();
String getDescr();
List<QuestionProjection> getQuestions();
}
和
public interface QuestionProjection {
Long getId();
String getDescr();
}
您的存储库
@Repository
public interface ExamRepository extends JpaRepository<Exam, Long> {
List<Exam> findAll();
@Query("SELECT e FROM Exam e")
List<ExamProjection> findAllProjection();
}
观察到使用 findAll()
方法并将列表类型作为 ExamProjection 传递时,出于某种原因,会导致不兼容的 return 类型错误。为避免这种情况,请创建一个自定义方法,在本例中为 findAllProjection()
.
服务
@Service
public class ExamService {
@Autowired
ExamRepository examRepository;
public List<ExamProjection> findAllProjection() {
return examRepository.findAllProjection();
}
}
最后,资源
@RestController
@RequestMapping(value = "/exam")
public class ExamResource {
@Autowired
ExamService examService;
@GetMapping
public ResponseEntity<List<ExamProjection>> findAll() {
return ResponseEntity.ok().body(examService.findAllProjection());
}
}
使用上面的方法,json returned 不包含字段 cont
,因为 de QuestionProjection
没有方法 getCont()
.
[
{
"id": 1,
"descr": "First Exam",
"questions": [
{
"id": 1,
"descr": "First Question"
},
{
"id": 2,
"descr": "Second Question"
}
]
}
]
如果 QuestionProjection
更改为
public interface QuestionProjection {
Long getId();
String getCont();
}
json returned 更改为
[
{
"id": 1,
"descr": "First Exam",
"questions": [
{
"id": 1,
"cont": "First Question Content"
},
{
"id": 2,
"cont": "Second Question Content"
}
]
}
]