遇到了一个新的问题,就是如何使用 Spring Data JPA 创建表的联合主键?网上找了不少答案,本身也踩了一些坑,总结出了三种方式,记录一下。java
第一种方式:
第一种方式是直接使用 @Id 这个注解,来设置联合主键,例以下面这样,我要在 stu_no 和 stu_name 上创建联合主键:函数
@Entity @Table(name = "student") public class Student { @Id @Column(name = "stu_no", nullable = false, length = 11) private Integer stuNo; @Id @Column(name = "stu_name", nullable = false, length = 128) private String stuName; @Column(name = "stu_age", nullable = false, length = 3) private Integer stuAge; @Column(name = "class_id", nullable = false, length = 8) private String classId; }
这种方式很简单,可是问题也是存在的。例如我想把 stu_no 设置为自动递增,加上 @GeneratedValue ,就是不生效,而是做用于 stu_name 这个字段上面,实在是很邪门!测试
第二种方式:
使用 @IdClass 这个注解来实现,咱们须要新建一个主键类,这个类须要实现 Serializable 接口,而且须要无惨构造函数,还须要重写 equals 和 hashCode 方法,具体内容以下:ui
@Data @Builder @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode public class StudentUPK implements Serializable { private Integer stuNo; private String stuName; }
这里我是使用 lombok 插件来简化代码的,固然你能够本身手写构造函数和重写方法。而后实体类 Student 的内容以下:插件
@Entity @IdClass(StudentUPK.class) @Table(name = "student") public class Student { @Id @Column(name = "stu_no", nullable = false, length = 11) private Integer stuNo; @Id @Column(name = "stu_name", nullable = false, length = 128) private String stuName; @Column(name = "stu_age", nullable = false, length = 3) private Integer stuAge; @Column(name = "class_id", nullable = false, length = 8) private String classId; }
这种方式也是存在问题的,在使用 JpaRepository 的时候,这样写:public interface StudentRepository extends JpaRepository<Student, StudentUPK>
,ID 写成这主键类,本觉得是能够的,但一执行 CRUD 总是会报错,到如今还没找到缘由。code
3. 第三种方式:
第三种方式是使用 @Embeddable 和 @EmbeddedId 注解来实现,一样是须要一个主键类,内容以下:接口
@Builder @Data @NoArgsConstructor @AllArgsConstructor @Embeddable @EqualsAndHashCode public class StudentUPK implements Serializable { @Column(name = "stu_no", nullable = false, length = 11) private Integer stuNo; @Column(name = "stu_name", nullable = false, length = 128) private String stuName; }
主键类也是须要实现 Serializable 接口,而且须要无惨构造函数,还须要重写 equals 和 hashCode 方法。实体类 Student 的内容以下:hash
@Entity @Table(name = "student") public class Student { @EmbeddedId private StudentUPK studentUPK; @Column(name = "stu_age", nullable = false, length = 3) private Integer stuAge; @Column(name = "class_id", nullable = false, length = 8) private String classId; }
这里使用了 @EmbeddedId 这个注解。这种方式使用 JpaRepository 是能够的,例如写成这样:`public interface StudentRepository extends JpaRepository<Student, StudentUPK> {
}`it
而后再新建一个测试方法:class
@SpringBootTest @RunWith(SpringRunner.class) public class StudentRepositoryTest { @Resource private StudentRepository studentRepository; @Test public void testInsert(){ StudentUPK upk = StudentUPK.builder().stuNo(132).stuName("Rose Duan").build(); Student student = Student.builder().studentUPK(upk).stuAge(14).classId("12312323").build(); studentRepository.save(student); } }
CRUD 的操做应该就成功了!