Implementation of Spring Data Jpa Compound Primary Key
- 2021-07-18 08:04:04
- OfStack
Preface
There is a requirement in this big creation. When building tables in the database, it is found that the primary key of the relational table user_project between user table and project table is a composite primary key:
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)
);
After reading several blogs on the Internet and consulting the dry goods group of spring boot (thanks for the patient answer of the night increase), it was finally made. Here is a summary for future reference.
Text
Here, @ IdClass annotation is used to realize compound primary key.
Train of thought
Realization
Compound primary key class
package com.hzy.Model;
import java.io.Serializable;
/**
* Created by huangzhenyang on 2017/9/7.
* UserProject Compound primary key class of
*
* @Param userId
* @Param projectId
* @Param timestamp
* By this 3 Together, they form a composite primary key
*/
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;
}
// *** Rewrite hashCode And equals Method *** Focus!
@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;
}
}
Note:
The composite primary key class must satisfy:
1. Implement Serializable interface;
2. There is a default construction method of public without parameters;
3. Override the equals and hashCode methods. equals method is used to judge whether two objects are the same. When EntityManger searches for Entity by find method, it is judged according to the return value of equals. The hashCode method returns the hash code of the current object;
Entity class
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 + '\'' +
'}';
}
}
Note:
1. @ IdClass annotates the class used to annotate the primary key rules used by entities;
2. Mark the attributes of the primary key in the entity at the same time, such as userId, projectId and timestamp in this code;
Get data
Method 1: Get through EntityManager, such as method testUserProjectRepository ()
Method 2: Obtain through Repository; Remember here in extends JpaRepository
<
UserProject,UserProjectMultiKeysClass
>
The primary key class of id is specified as the composite primary key class UserProjectMultiKeysClass when
public interface UserProjectRepository extends JpaRepository<UserProject,UserProjectMultiKeysClass>{
// According to the user Id, Find out all the users participated in UserProject
// TEST PASS
List<UserProject> findByUserId(Integer userId);
// According to the project id, Find out all the participating projects UserProject
// TEST PASS
List<UserProject> findByProjectId(Integer projectId);
// According to the user id And projects id Find out all the UserProject
// TEST PASS
List<UserProject> findByUserIdAndProjectId(Integer userId,Integer projectId);
}
Code for unit tests
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());
}
}
}