JPA 联结主键的配置

JPA 联合主键的配置

      两个或多个字段组成的主键,我们叫联合主键。在面向对象中,我们用JPA怎么定义这种情况呢?
      怎么定义联合主键?用面向对象的思想来思考的话,联合主键里的复合主键(字段),可以把它看成一个整体,然后采用一个主键类来描述这个复合主键的字段。

关于联合主键类,大家一定要遵守以下几点JPA规范:

  1. 必须提供一个public的无参数构造函数。
  2. 必须实现序列化接口。
  3. 必须重写hashCode()和equals()这两个方法。这两个方法应该采用复合主键的字段作为判断这个对象是否相等的。
  4. 联合主键类的类名结尾一般要加上PK两个字母代表一个主键类,不是要求而是一种命名风格。




ArtLinePK.java

Java代码 JPA      联结主键的配置
  1. package cn.itcast.bean;   
  2.   
  3. import java.io.Serializable;   
  4.   
  5. import javax.persistence.Column;   
  6. import javax.persistence.Embeddable;   
  7.   
  8. @Embeddable  
  9. //这个注解代表ArtLinePK这个类是用在实体里面,告诉JPA的实现产品:在实体类里面只是使用这个类定义的属性。   
  10. //简单的理解为:ArtLinePK里的属性可以看成是ArtLine类里的属性,好比ArtLinePK的属性就是在ArtLine里定义的。   
  11. public class ArtLinePK implements Serializable{   
  12.     private String startCity;   
  13.     private String endCity;   
  14.   
  15.     public ArtLinePK() {   
  16.     }   
  17.   
  18.     public ArtLinePK(String startCity, String endCity) {   
  19.         this.startCity = startCity;   
  20.         this.endCity = endCity;   
  21.     }   
  22.   
  23.     @Column(length=3)   
  24.     public String getStartCity() {   
  25.         return startCity;   
  26.     }   
  27.   
  28.     public void setStartCity(String startCity) {   
  29.         this.startCity = startCity;   
  30.     }   
  31.   
  32.     @Column(length=3)   
  33.     public String getEndCity() {   
  34.         return endCity;   
  35.     }   
  36.   
  37.     public void setEndCity(String endCity) {   
  38.         this.endCity = endCity;   
  39.     }   
  40.   
  41.     @Override  
  42.     public int hashCode() {   
  43.         final int prime = 31;   
  44.         int result = 1;   
  45.         result = prime * result + ((endCity == null) ? 0 : endCity.hashCode());   
  46.         result = prime * result   
  47.                 + ((startCity == null) ? 0 : startCity.hashCode());   
  48.         return result;   
  49.     }   
  50.   
  51.     @Override  
  52.     public boolean equals(Object obj) {   
  53.         if (this == obj)   
  54.             return true;   
  55.         if (obj == null)   
  56.             return false;   
  57.         if (getClass() != obj.getClass())   
  58.             return false;   
  59.         final ArtLinePK other = (ArtLinePK) obj;   
  60.         if (endCity == null) {   
  61.             if (other.endCity != null)   
  62.                 return false;   
  63.         } else if (!endCity.equals(other.endCity))   
  64.             return false;   
  65.         if (startCity == null) {   
  66.             if (other.startCity != null)   
  67.                 return false;   
  68.         } else if (!startCity.equals(other.startCity))   
  69.             return false;   
  70.         return true;   
  71.     }   
  72.   
  73. }   


    这个联合主键类,应该作为实体类的一个主键(实体标识符,id)。

ArtLine.java

Java代码 JPA      联结主键的配置
  1. package cn.itcast.bean;   
  2.   
  3. import javax.persistence.Column;   
  4. import javax.persistence.EmbeddedId;   
  5. import javax.persistence.Entity;   
  6.   
  7. @Entity  
  8. public class ArtLine {   
  9.     private ArtLinePK id;   //用面向对象的思想去思考的话,这个复合主键看成一个整体,由复合主键类ArtLinePK来描述。   
  10.     private String name;   
  11.   
  12.     public ArtLine() {   
  13.     }   
  14.   
  15.     public ArtLine(ArtLinePK id) {   
  16.         this.id = id;   
  17.     }   
  18.   
  19.     public ArtLine(String startCity, String endCity, String name) {   
  20.         this.id = new ArtLinePK(startCity, endCity);   
  21.         this.name = name;   
  22.     }   
  23.   
  24.     @EmbeddedId //按照JPA规范要求,我们并不是用@Id来标注它。   
  25.     //@EmbeddedId 这个注解用于标注id这个属性为实体的标识符,因为我们使用的是复合主键类,所以我们要用@EmbeddedId这个专门针对复合主键类的标志实体标识符的注解。   
  26.     public ArtLinePK getId() {   
  27.         return id;   
  28.     }   
  29.   
  30.     public void setId(ArtLinePK id) {   
  31.         this.id = id;   
  32.     }   
  33.   
  34.     @Column(length=20)   
  35.     public String getName() {   
  36.         return name;   
  37.     }   
  38.   
  39.     public void setName(String name) {   
  40.         this.name = name;   
  41.     }   
  42. }  
  43.  

我们的复合主键类,目前为止,已经定义好了。定义好了之后,接着我们就看它生成的数据库表是否满足复合主键这么一种情况。

ArtLineTest.java

Java代码 JPA      联结主键的配置
  1. package junit.test;   
  2.   
  3.   
  4. import javax.persistence.EntityManager;   
  5. import javax.persistence.EntityManagerFactory;   
  6. import javax.persistence.Persistence;   
  7.   
  8. import org.junit.BeforeClass;   
  9. import org.junit.Test;   
  10.   
  11. import cn.itcast.bean.ArtLine;   
  12.   
  13. public class ArtLineTest {   
  14.   
  15.     @BeforeClass  
  16.     public static void setUpBeforeClass() throws Exception {   
  17.     }   
  18.   
  19.     @Test public void save(){   
  20.         EntityManagerFactory factory = Persistence   
  21.         .createEntityManagerFactory("itcast");   
  22.         EntityManager em = factory.createEntityManager();   
  23.         em.getTransaction().begin();   
  24.   
  25.         em.persist(new ArtLine("PEK","SHA","北京到上海"));   
  26.   
  27.         em.getTransaction().commit();   
  28.         em.close();   
  29.         factory.close();   
  30.     }   
  31. }
  32.   测试成功后,可以去查询看一下对应表的结构.  想想其中的原理.