好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Spring Data Jpa 复合主键的实现

前言

这次大创有个需求,在数据库建表时发现,user表与project表的关系表 user_project的主键为 复合主键 :

?

1

2

3

4

5

6

7

create table user_project(

  user_id      int ( 20 ),

  project_id     int ( 20 ),

  timestamp     varchar ( 50 ),

  donate_money    double ( 10 , 2 ),

  primary key (user_id,project_id)

);

在网上看了几篇博客,以及在spring boot干货群咨询(感谢夜升额耐心解答)过后总算是做出来了。这里做个总结,方便日后查阅。

正文

这里采用@idclass注解的方式来实现复合主键;

思路

编写一个复合主键类userprojectmultikeysclass; 通过@idclass注释在实体中标注复合主键; 可以通过entitymanager获取数据,或者是直接在repository 里写方法;

实现

复合主键类

?

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

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

package com.hzy.model;

 

import java.io.serializable;

 

/**

  * created by huangzhenyang on 2017/9/7.

  * userproject的复合主键类

  *

  * @param userid

  * @param projectid

  * @param timestamp

  * 由这三个共同组成复合主键

  */

public class userprojectmultikeysclass implements serializable {

   private integer userid;

   private integer projectid;

   private string timestamp;

 

   //constructor

   public userprojectmultikeysclass() {

   }

 

   public userprojectmultikeysclass(integer userid, integer projectid, string timestamp) {

     this .userid = userid;

     this .projectid = projectid;

     this .timestamp = timestamp;

   }

 

   //setter and getter

   public integer getuserid() {

     return userid;

   }

 

   public void setuserid(integer userid) {

     this .userid = userid;

   }

 

   public integer getprojectid() {

     return projectid;

   }

 

   public void setprojectid(integer projectid) {

     this .projectid = projectid;

   }

 

   public string gettimestamp() {

     return timestamp;

   }

 

   public void settimestamp(string timestamp) {

     this .timestamp = timestamp;

   }

 

   // ***重写hashcode与equals方法*** 划重点!

   @override

   public int hashcode() {

     final int prime = 31 ;

     int result = 1 ;

     result = prime * result + ((userid == null ) ? 0 : userid.hashcode());

     result = prime * result + ((projectid == null ) ? 0 : projectid.hashcode());

     result = prime * result + ((timestamp == null ) ? 0 : timestamp.hashcode());

     return result;

   }

 

   @override

   public boolean equals(object obj){

     if ( this == obj){

       return true ;

     }

     if (obj == null ){

       return false ;

     }

     if (getclass() != obj.getclass()){

       return false ;

     }

 

     final userprojectmultikeysclass other = (userprojectmultikeysclass)obj;

     if (userid == null ){

       if (other.userid != null ){

         return false ;

       }

     } else if (!userid.equals(other.userid)){

       return false ;

     }

     if (projectid == null ){

       if (other.projectid != null ){

         return false ;

       }

     } else if (!projectid.equals(other.projectid)){

       return false ;

     }

     if (timestamp == null ){

       if (other.timestamp != null ){

         return false ;

       }

     } else if (!timestamp.equals(other.timestamp)){

       return false ;

     }

 

     return true ;

   }

}

注意:

复合主键类必须满足:
1. 实现serializable接口;
2. 有默认的public无参数的构造方法;
3. 重写equals和hashcode方法。equals方法用于判断两个对象是否相同,entitymanger通过find方法来查找entity时,是根据equals的返回值来判断的。hashcode方法返回当前对象的哈希码;

实体类

?

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

package com.hzy.model;

 

import javax.persistence.entity;

import javax.persistence.id;

import javax.persistence.idclass;

import javax.persistence.table;

import java.io.serializable;

 

/**

  * created by huangzhenyang on 2017/9/7.

  *

  */

@entity

@table (name = "user_project" )

@idclass (userprojectmultikeysclass. class )

public class userproject implements serializable {

   private double donatemoney;

   private integer userid;

   private integer projectid;

   private string timestamp;

 

   @id

   public integer getuserid(){

     return this .userid;

   }

 

   @id

   public integer getprojectid(){

     return this .projectid;

   }

 

   @id

   public string gettimestamp(){

     return this .timestamp;

   }

 

   //getter and setter

   public double getdonatemoney() {

     return donatemoney;

   }

 

   public void setdonatemoney( double donatemoney) {

     this .donatemoney = donatemoney;

   }

 

   public void setuserid(integer userid) {

     this .userid = userid;

   }

 

   public void setprojectid(integer projectid) {

     this .projectid = projectid;

   }

 

   public void settimestamp(string timestamp) {

     this .timestamp = timestamp;

   }

 

   @override

   public string tostring() {

     return "userproject{" +

         "donatemoney=" + donatemoney +

         ", userid=" + userid +

         ", projectid=" + projectid +

         ", timestamp='" + timestamp + '\ '' +

         '}' ;

   }

}

注意:
1. @idclass标注用于标注实体所使用主键规则的类;
2. 在实体中同时标注主键的属性,比如这段代码中的userid,projectid以及timestamp ;

获取数据

方法一: 通过entitymanager获取,比如方法testuserprojectrepository()

方法二:通过repository获取;这里记得在extends jparepository<userproject,userprojectmultikeysclass>时把id的主键类指定为复合主键类userprojectmultikeysclass

?

1

2

3

4

5

6

7

8

9

10

11

12

13

public interface userprojectrepository extends jparepository<userproject,userprojectmultikeysclass>{

   // 根据用户id,找出用户参与的所有userproject

   // test pass

   list<userproject> findbyuserid(integer userid);

 

   // 根据项目id,找出参与项目的所有userproject

   // test pass

   list<userproject> findbyprojectid(integer projectid);

 

   // 根据用户id和项目id 找出所有的userproject

   // test pass

   list<userproject> findbyuseridandprojectid(integer userid,integer projectid);

}

单元测试的代码

?

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

package com.hzy;

 

import com.hzy.model.userproject;

import com.hzy.model.userprojectmultikeysclass;

import com.hzy.repository.userprojectrepository;

import com.hzy.service.userprojectservice;

import com.hzy.service.userservice;

import org.junit.test;

import org.junit.runner.runwith;

import org.springframework.beans.factory.annotation.autowired;

import org.springframework.boot.test.context.springboottest;

import org.springframework.test.context.junit4.springrunner;

 

import javax.persistence.entitymanager;

import javax.persistence.persistencecontext;

import javax.transaction.transactional;

import java.util.list;

 

/**

  * created by huangzhenyang on 2017/9/8.

  */

@runwith (springrunner. class )

@springboottest

public class userproejctrepositorytest {

   @autowired

   @persistencecontext

   private entitymanager entitymanager;

 

   @autowired

   private userprojectrepository userprojectrepository;

 

   @test

   public void testuserprojectrepository(){

     userprojectmultikeysclass userprojectmultikeysclass =

         new userprojectmultikeysclass( 1 , 1 , "2017-09-08" );

     userproject userproject = entitymanager.find(userproject. class ,userprojectmultikeysclass);

     system.out.println(userproject.tostring());

   }

 

 

   @test

   public void testfindbyuserid(){

     list<userproject> userprojects = userprojectrepository.findbyuserid( 1 );

     for (userproject userproject:userprojects){

       system.out.println(userproject.tostring());

     }

   }

 

   @test

   public void testfindbyprojectid(){

     list<userproject> userprojects = userprojectrepository.findbyprojectid( 1 );

     for (userproject userproject:userprojects){

       system.out.println(userproject.tostring());

     }

   }

 

   @test

   public void testfindbyuseridandprojectid(){

     list<userproject> userprojects = userprojectrepository.findbyuseridandprojectid( 1 , 1 );

     for (userproject userproject:userprojects){

       system.out.println(userproject.tostring());

     }

   }

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

原文链接:https://blog.csdn.net/qq_35056292/article/details/77892012

查看更多关于Spring Data Jpa 复合主键的实现的详细内容...

  阅读:14次