【发布时间】:2018-04-23 20:11:50
【问题描述】:
我希望这个问题不是基于意见的,但我们开始吧。 我正在开发一个使用 spring boot、spring data jpa 和 JWT Token 作为身份验证系统的小型 API。 API 非常简单,是一个考试生成器,您可以在其中注册教授、课程、问题、选择等。
例如: [13/11/2017 - 编辑以包含 AbstractEntity]
@MappedSuperclass
public class AbstractEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;
protected boolean enabled = true;
//equals, hashcode...
}
public class Professor extends AbstractEntity{
private String email;
}
public class Course extends AbstractEntity {
@ManyToOne(optional = false)
private Professor professor;
}
public class Question extends AbstractEntity {
@ManyToOne(optional = false)
private Course course;
}
因为身份验证系统是所有查询的 JWT 令牌,所以我必须包含教授的信息。
例如
public interface CourseRepository extends PagingAndSortingRepository<Course, Long> {
@Query("select c from Course c where c.id = ?1 and c.professor = ?#{principal.professor} and c.enabled = true")
Course findOne(Long id);
}
问题在于,由于教授的信息以及启用的字段,对于每个 crud 查询,我都必须编写自己的自定义查询。
我知道有一种方法可以扩展 PagingAndSortingRepository 并编写您自己的自定义查询,如下所示:
public interface CustomPagingAndSortRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> {
@Override
@Query("select e from #{#entityName} e where e.id = ?1 and e.professor = ?#{principal.professor} and e.enabled = true")
T findOne(ID id);
//More fields overrided here
}
如果我只启用担心,这个 CustomPagingAndSortRepository 将完美地适用于所有类。这门课非常适合 Course,因为 e.professor = ?#{principal.professor} 会在那里找到教授。但它不适用于问题,例如,因为我需要加入课程班级才能获得教授,例如e.course.professor = ?#{principal.professor}
关键是如果我在所有课程中都与教授建立关联,我可以使通用代码工作,节省大量代码但牺牲数据库设计的规范化。 问题是:还有其他方法吗?或者这样做是否有效?
PS:问题,课程等永远不会改变所有者,这意味着只有创建的教授才能使用它。
【问题讨论】:
-
principal.professor是登录用户吗? -
您是否在问题和课程中为所有具有外键关系的对象设置了 id 列? AA你是依靠休眠来创建表和列,还是你在使用flyway,或者你是依靠手动SQL脚本?
-
@AyoK 是的。
-
@Pytry,我将 Spring Data JPA 用于所有内容,包括表生成,所以是的,我有,没有写在这里以使其更短。但是所有实体类都从具有
id和enabled字段的抽象实体扩展而来。
标签: java spring spring-boot spring-data-jpa