SpringData JPA复合主键

上一篇博客简单介绍了SpringData JPA实现简单的CRUD,分页与多条件的排序,那里的主键类型是Long,有时我们会遇到主键不是一个的,复合主键,经过调研如下。确定一个人,不能只根据他的姓名来确定,因为会有重名,现在我们假设姓名、身份证号确定唯一一个人。

复合主键:一张表存在多个字段共同组成一个主键,这多个字段的组合不能重复,但是单独一个可以重复。

例子:姓名和省份证号共同组成了主键

二、采用@IdClass来注解复合主键

过程和@Embeddable差不多,这里直接贴例子。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

@Entity

@Table(name = "people")

@IdClass(PeopleKey.class)

public class People  implements Serializable {

 

//  @EmbeddedId

//  private PeopleKey id;

     

    @Id

    @Column(name = "name")

    private String name;

    @Id

    @Column(name = "idcardno")

    private String idcardno;

     

    @Column(name = "age")

    private int age;

     

    @Column(name = "address")

    private String address;

 

}

 

1

2

3

4

5

6

7

8

9

public class PeopleKey implements Serializable  {

//  @Id

//  @Column(name = "name")

    private String name;

//  @Id

//  @Column(name = "idcardno")

    private String idcardno;

 

}

采用这个方法的我参考博客里有一篇,写的比较详细,但是感觉这个方法不好,本身就已经在PeopleKey中把主键给封装了,但是在实体类People中还要把复合主键给加入进去,不够简介,采用第一种方法,就很简单,而且也体现了Java类封装的思想。

 一、Spring Data Jpa 复合主键  

1.1、编写一个复合主键类:PeopleKey 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

@Embeddable

public class PeopleKey implements Serializable  {

     

    @Column(name = "name")

    private String name;

     

    @Column(name = "idcardno")

    private String idcardno;

    // 省略setter,getter方法

 

    @Override

    public String toString() {

        return "PeopleKey [name=" + name + ", idcardno=" + idcardno + "]";

    }

} 

  注意:  

  1) 实现Serializable接口(否则会报错,错误会直接显示); 

  2)在复合主键的类上,使用注解@Embeddable

  3) 有默认的public无参数的构造方法(在我这个实例中,我没有添加有参构造方法,所以采用默认的构造方法)

  如果你在实体类里有有参构造方法,那么一定要有一个无参构造方法,否则运行的时候会报错

1

org.hibernate.InstantiationException: No default constructor for entity:  : com.my.model.People

这个就是没有默认的构造方法造成的,所以要在实体类中加入默认的无参构造方法。

  4) 重写equalshashCode方法。equals方法用于判断两个对象是否相同,EntityManger通过find方法来查找Entity时,是根据equals的返回值来判断的。hashCode方法返回当前对象的哈希码(我验证EntityManger,不重写也没事。);

1.2、编写实体类:People 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

package com.my.model;

 

import javax.persistence.*;

@Entity

@Table(name = "people")

//@IdClass(PeopleKey.class)

public class People extends PeopleKey{

    // 复合主键要用这个注解

    @EmbeddedId

    private PeopleKey id;

 

    @Column(name = "age")

    private int age;

     

    @Column(name = "address")

    private String address;

 

    // 省略setter,getter方法

    @Override

    public String toString() {

        return "People [id=" + id + ", age=" + age + ", address=" + address

                "]";

    }  

}

1.3 测试:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

@Service

public class PeopleService {

     

    @Resource

    private PeopleRepository peopleRepository;

 

    public People findOne() {

        PeopleKey peopleKey = new PeopleKey();

        peopleKey.setName("张三");

        peopleKey.setIdcardno("340123");

        People people = peopleRepository.findOne(peopleKey);

        return people;

    }

 

}

控制台上的输出结果:

1

People [id=PeopleKey [name=张三, idcardno=340123], age=3, address=分解分] 

 

 三、EntityManager的验证,直接上代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

package com.my.model;

 

import java.io.Serializable;

 

import javax.persistence.Column;

import javax.persistence.Embeddable;

import javax.persistence.Entity;

import javax.persistence.Id;

//@Embeddable

public class PeopleKey implements Serializable  {

//  @Id

//  @Column(name = "name")

    private String name;

//  @Id

//  @Column(name = "idcardno")

    private String idcardno;

     

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public String getIdcardno() {

        return idcardno;

    }

    public void setIdcardno(String idcardno) {

        this.idcardno = idcardno;

    }

 

    @Override

    public String toString() {

        return "PeopleKey [name=" + name + ", idcardno=" + idcardno + "]";

    }  

 

}

  

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

package com.my.model;

 

import java.io.Serializable;

 

import javax.persistence.*;

@Entity

@Table(name = "people")

@IdClass(PeopleKey.class)

public class People  {

 

//  @EmbeddedId

//  private PeopleKey id;

     

 

    @Column(name = "age")

    private int age;

     

    @Column(name = "address")

    private String address;

 

//  public PeopleKey getId() {

//      return id;

//  }

//

//  public void setId(PeopleKey id) {

//      this.id = id;

//  }

// 

    @Id

    @Column(name = "name")

    private String name;

    @Id

    @Column(name = "idcardno")

    private String idcardno;

     

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public String getIdcardno() {

        return idcardno;

    }

    public void setIdcardno(String idcardno) {

        this.idcardno = idcardno;

    }

    public int getAge() {

        return age;

    }

 

    public People() {

        super();

    }

 

    public void setAge(int age) {

        this.age = age;

    }

 

 

    public String getAddress() {

        return address;

    }

 

    public void setAddress(String address) {

        this.address = address;

    }

 

    @Override

    public String toString() {

        return "People [age=" + age + ", address=" + address + ", name=" + name

                ", idcardno=" + idcardno + "]";

    }

     

     

}<br><br>

测试:

1

2

3

4

5

6

7

8

9

@RequestMapping(value = "/useEntityManager")

public void findUseEntityManager() throws Exception

   {

       PeopleKey peopleKey = new PeopleKey();

       peopleKey.setName("张三");

       peopleKey.setIdcardno("340123");

        People people = entityManager.find(People.class,peopleKey);

        System.out.println(people.toString());

   } 

 结果:

1

People [age=3, address=分解分, name=张三, idcardno=340123]

 

参考网址:

1、https://www.cnblogs.com/linjiqin/archive/2011/03/09/1978680.html

2、http://blog.youkuaiyun.com/qq_35056292/article/details/77892012 

3. https://www.cnblogs.com/boywwj/p/8031106.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值