Spring Data JPA設置表聯合主鍵

遇到了一個新的問題,就是如何使用 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 的操做應該就成功了!

相關文章
相關標籤/搜索