【发布时间】:2018-08-06 08:05:02
【问题描述】:
是否可以使用投影并在某些相关对象中使用它自己的投影?
例如,一个有Exam,它有List<Question>。我想请求一份考试列表(我有一个@projection),但我想为每个相关的Question定义要检索的属性
【问题讨论】:
-
请阅读this并给出一些示例代码。
标签: java spring projection
是否可以使用投影并在某些相关对象中使用它自己的投影?
例如,一个有Exam,它有List<Question>。我想请求一份考试列表(我有一个@projection),但我想为每个相关的Question定义要检索的属性
【问题讨论】:
标签: java spring projection
你可以这样做:
假设您的 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 传递会导致不兼容的返回类型错误。为避免这种情况,请创建一个自定义方法,在本例中为 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不包含cont字段,因为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 将更改返回到
[
{
"id": 1,
"descr": "First Exam",
"questions": [
{
"id": 1,
"cont": "First Question Content"
},
{
"id": 2,
"cont": "Second Question Content"
}
]
}
]
【讨论】:
如果我理解正确,您想将 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
}
【讨论】: