Java Spring投影内部投影

时间:2018-02-26 19:28:42

标签: java spring projection

是否可以使用投影,在某些相关对象中使用它自己的投影?

例如,有ExamList<Question>。我想要一份考试清单(我有一个@projection),但我想为每个相关Question

定义要检索的属性

2 个答案:

答案 0 :(得分:2)

您可以执行以下操作:

假设您的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,因为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返回的更改为

[
    {
        "id": 1,
        "descr": "First Exam",
        "questions": [
            {
                "id": 1,
                "cont": "First Question Content"
            },
            {
                "id": 2,
                "cont": "Second Question Content"
            }
        ]
    }
]

答案 1 :(得分:1)

如果我理解正确,您希望将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
}