SpringData JPA復合主鍵


  上一篇博客簡單介紹了SpringData JPA實現簡單的CRUD,分頁與多條件的排序,那里的主鍵類型是Long,有時我們會遇到主鍵不是一個的,復合主鍵,經過調研如下。確定一個人,不能只根據他的姓名來確定,因為會有重名,現在我們假設姓名、身份證號確定唯一一個人。

復合主鍵:一張表存在多個字段共同組成一個主鍵,這多個字段的組合不能重復,但是單獨一個可以重復。

例子:姓名和省份證號共同組成了主鍵

 一、Spring Data Jpa 復合主鍵  

1.1、編寫一個復合主鍵類:PeopleKey 

@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無參數的構造方法(在我這個實例中,我沒有添加有參構造方法,所以采用默認的構造方法)

  如果你在實體類里有有參構造方法,那么一定要有一個無參構造方法,否則運行的時候會報錯

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

這個就是沒有默認的構造方法造成的,所以要在實體類中加入默認的無參構造方法。

  4) 重寫equalshashCode方法。equals方法用於判斷兩個對象是否相同,EntityManger通過find方法來查找Entity時,是根據equals的返回值來判斷的。hashCode方法返回當前對象的哈希碼(我驗證EntityManger,不重寫也沒事。);

1.2、編寫實體類:People 

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 測試:

@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;
	}

}

控制台上的輸出結果:

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

二、采用@IdClass來注解復合主鍵

過程和@Embeddable差不多,這里直接貼例子。

@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;

}

 

public class PeopleKey implements Serializable  {
//	@Id
//	@Column(name = "name")
	private String name;
//	@Id
//	@Column(name = "idcardno")
	private String idcardno;

}

采用這個方法的我參考博客里有一篇,寫的比較詳細,但是感覺這個方法不好,本身就已經在PeopleKey中把主鍵給封裝了,但是在實體類People中還要把復合主鍵給加入進去,不夠簡介,采用第一種方法,就很簡單,而且也體現了Java類封裝的思想。

 三、EntityManager的驗證,直接上代碼

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 + "]";
	}	

}

  

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 + "]";
	}
	
	
}

測試:

 
	 @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());
	    } 

 結果:

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

  

參考博客:

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

2、http://blog.csdn.net/qq_35056292/article/details/77892012 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM