JPA中的联合主键

两个或多个字段组成的主键,我们叫联合主键。在面向对象中,我们用JPA怎么定义这种情况呢?

怎么定义JPA 联合主键?用面向对象的思想来思考的话,联合主键里的复合主键(字段),可以把它看成一个整体,然后采用一个主键类来描述这个复合主键的字段

关于联合主键类,大家一定要遵守以下几点JPA规范:
1. 必须提供一个public的无参数构造函数。
2. 必须实现序列化接口
3. 必须重写hashCode()和equals()这两个方法。这两个方法应该采用复合主键的字段作为判断这个对象是否相等的


ArtLinePK.java

 
package cn.itcast.bean; 
 
import java.io.Serializable; 
 
import javax.persistence.Column; 
import javax.persistence.Embeddable; 
 
    @Embeddable 
    //这个注解代表ArtLinePK这个类是用在实体里面,告诉JPA的实现产品:在实体类里面只是使用这类定义的属性 
    //简单的理解为:ArtLinePK里的属性可以看成是ArtLine类里的属性,好比ArtLinePK的属性就是在ArtLine里定义的 
    public class ArtLinePK implements Serializable{ 
    private String startCity; 
    private String endCity; 
 
    public ArtLinePK() { 
    } 
 
    public ArtLinePK(String startCity, String endCity) { 
        this.startCity = startCity; 
        this.endCity = endCity; 
    } 
 
    @Column(length=3) 
    public String getStartCity() { 
        return startCity; 
    } 
 
    public void setStartCity(String startCity) { 
        this.startCity = startCity; 
    } 
 
    @Column(length=3) 
    public String getEndCity() { 
        return endCity; 
    } 
 
    public void setEndCity(String endCity) { 
        this.endCity = endCity; 
    } 
 
    @Override 
    public int hashCode() { 
        final int prime = 31; 
        int result = 1; 
        result = prime * result + ((endCity == null) ? 0 : endCity.hashCode()); 
        result = prime * result    + ((startCity == null) ? 0 : startCity.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 ArtLinePK other = (ArtLinePK) obj; 
        if (endCity == null) { 
            if (other.endCity != null) 
                return false; 
        } else if (!endCity.equals(other.endCity)) 
            return false; 
            if (startCity == null) { 
                if (other.startCity != null) 
                    return false; 
            } else if (!startCity.equals(other.startCity)) 
                return false; 
        return true; 
    } 
 
}


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

ArtLine.java

package cn.itcast.bean; 
 
import javax.persistence.Column; 
import javax.persistence.EmbeddedId; 
import javax.persistence.Entity; 
 
@Entity 
public class ArtLine { 
    private ArtLinePK id;//用面向对象的思想去思考的话,这个复合主键看成一个整体,由复合主键类ArtLinePK来描述 
    private String name; 
 
    public ArtLine() { 
    } 
 
    public ArtLine(ArtLinePK id) { 
        this.id = id; 
    } 
 
    public ArtLine(String startCity, String endCity, String name) { 
        this.id = new ArtLinePK(startCity, endCity); 
        this.name = name; 
    } 
 
    @EmbeddedId //按照JPA规范要求,我们并不是用@Id来标注它 
    //@EmbeddedId 这个注解用于标注id这个属性为实体的标识符,因为我们使用的是复合主键类, 
    //所以我们要用@EmbeddedId这个专门针对复合主键类的 用于标志实体标识符的注解 
    public ArtLinePK getId() { 
        return id; 
    } 
 
    public void setId(ArtLinePK id) { 
        this.id = id; 
    } 
 
    @Column(length=20) 
    public String getName() { 
        return name; 
    } 
 
    public void setName(String name) { 
        this.name = name; 
    } 
}


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

ArtLineTest.java

 
package junit.test; 
 
 
import javax.persistence.EntityManager; 
import javax.persistence.EntityManagerFactory; 
import javax.persistence.Persistence; 
 
import org.junit.BeforeClass; 
import org.junit.Test; 
 
import cn.itcast.bean.ArtLine; 
 
public class ArtLineTest { 
 
    @BeforeClass 
    public static void setUpBeforeClass() throws Exception { 
    } 
 
    @Test public void save(){ 
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("itcast"); 
        EntityManager em = factory.createEntityManager(); 
        em.getTransaction().begin(); 
 
        em.persist(new ArtLine("PEK","SHA","北京飞上海")); 
 
        em.getTransaction().commit(); 
        em.close(); 
        factory.close(); 
    } 
}


你可能感兴趣的:(联合主键)