【问题标题】:Java Spring projection inside projectionJava Spring 投影内投影
【发布时间】:2018-08-06 08:05:02
【问题描述】:

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

例如,一个有Exam,它有List<Question>。我想请求一份考试列表(我有一个@projection),但我想为每个相关的Question定义要检索的属性

【问题讨论】:

  • 请阅读this并给出一些示例代码。

标签: java spring projection


【解决方案1】:

你可以这样做:

假设您的 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"
            }
        ]
    }
]

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-25
      • 2018-03-05
      • 2021-06-19
      • 2021-06-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多