我正在开发一个基于 Spring Boot 的应用程序,我想利用基于接口的投影,因为我想从 mysql 数据库中选择部分列。
我有一个 CourseEntity.java 类,与 ModuleEntity.java 具有一对多关系
@Entity
@Table(name = "course")
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class CourseEntity extends BaseEntity {
private String title;
private String subTitle;
private String longDescription;
private String shortDescription;
@OneToMany(mappedBy = "course", cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, orphanRemoval = true)
private List<ModuleEntity> modules = new ArrayList<>();
...
...
...
// 100 More Fields
}
@Entity
@Table(name = "module")
@Builder
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class ModuleEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long id;
private String name;
private String shortDescription;
private String longDescription;
private String thumbnailPath;
@Column(name = "course_id", insertable = false, updatable = false)
private Long courseId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "course_id", updatable = false)
private CourseEntity course;
...
...
// 50 more fields
}
我的班级有很多字段,您可以在课程表中看到 100 个字段,在模块表中看到 50 个字段。甚至还有数据类型为 JSON 的列,其中仅包含大量静态数据。我想创建一个简单的 API,它应该只返回课程 id、标题、子标题,包括仅包含模块 id 名称的模块数据。对于这个API,我不想选择整个课程和模块实体,因为网络上会有大量数据传输未被使用。
为此,我创建了 2 个用于投影目的的界面
public interface CourseLookup {
Long getId();
String getTitle();
String getSubTitle();
List<ModuleLookup> getModules();
}
public interface ModuleLookup {
Long getId();
String getName();
}
现在我不知道如何将模块相关数据映射到“getModules()”方法。在 JPQL 中,我无法使用模块的别名。当我尝试使用以下查询时,我得到的 getModules() 为 null
@Query("Select distinct c.id as id, c.title as title, c.subTitle as subTitle, m.id as moduleId, m.name as moduleName From CourseEntity Left Join c.modules m Where id = :id")
Optional<CourseLookup> getData(Long id);
当我尝试使用这样的别名进行映射时,休眠会从数据库中选择模块的所有列
@Query("Select distinct c.id as id, c.title as title, c.subTitle as subTitle, m as modules From CourseEntity Left Join c.modules m Where id = :id")
Optional<CourseLookup> getData(Long id);
此外,当使用第二种方法时,尽管使用了 unique 关键字,我还是得到了重复的记录。我无法映射嵌套投影
一些想法(没有可用的IDEA/DB):
.... c.id = :id
。m.id
上进行区分。