前言
这次大创有个需求,在数据库建表时发现,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 复合主键的实现的详细内容...