持久化API(JPA)系列(七)实体关系映射(ORM)之单表映射@IdClass

通过以前的文章,我们了解到@Table、@Column、@Id实现了单表的映射,并且书剑有一个@Id指定的唯一字段。有时我们的数据表也许是有多个主键联合组成的,因此对于单表映射的主键,还可以进行如下两种联合主键映射。 联合主键:使用@IdClass指定外部主键 联合主键:使用@EmbeddedId嵌入外部主键下面通过实例来看这两种主键的开发方法。Demo:设计一个家庭表Family的数据结构

======================================================================

(一)联合主键:使用@IdClass指定外部主键

步骤: 1、建立一个主键类:类中对应了主键字段 2、在实体Bean中通过@IdClass注释符引用该类

以实现外部主键的引用。

1)新建外部主键类FamilyPK.java由于Family中设置联合主键man和woman,因此外部主键类FamilyPK也需要定义两个同样的变量,并添加一个以这两个变量为输入的构造函数,同时添加getter/setter函数。作为外部主键需满足:1.必须实现Serializable接口2.必须有默认的public无参数的构造方法3.必须覆盖equals()和hashCode()方法。equals()方法用于判断两个对象是否相同,EntityManager通过find()方法来查找实体,是根据equals()的返回值来判断的。本例中,只有对象的man和woman值完全相同或属于同一个对象时才返回true,否则返回false。hashCode()方法返回当前对象的哈希码。生成的hashCode()相同的概率越小越好,,算法可以进行优化。package com.tgb.itoo.exam.entity;import java.io.Serializable;@SuppressWarnings("serial")public class FamilyPK implements Serializable {private String man;//丈夫private String woman;//妻子public String getMan() {return man;}public void setMan(String man) {this.man = man;}public String getWoman() {return woman;}public void setWoman(String woman) {this.woman = woman;}public FamilyPK() {}public FamilyPK(String man, String woman) {this.man = man;this.woman = woman;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + ((man == null) ? 0 : man.hashCode());result = prime * result + ((woman == null) ? 0 : woman.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;FamilyPK other = (FamilyPK) obj;if (man == null) {if (other.man != null)return false;} else if (!man.equals(other.man))return false;if (woman == null) {if (other.woman != null)return false;} else if (!woman.equals(other.woman))return false;return true;}}2)使用@IdClass在实体Bean类Family.java中指定外部主键。通过注释符来设置与表、字段的映射关系。注意,该实体中需要标注联合主键:1、在man和woman的getter函数前都添加@Id注释符,表示都是主键2、在类名钱使用@IdClass引用外部主键类package com.tgb.itoo.exam.entity;import java.io.Serializable;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.Id;import javax.persistence.IdClass;import javax.persistence.Table;@SuppressWarnings("serial")@Entity@Table(name="family")@IdClass(FamilyPK.class)public class Family implements Serializable {private String man;// 丈夫private String woman;// 棋子private String address;// 地址@Idpublic String getMan() {return man;}public void setMan(String man) {this.man = man;}@Idpublic String getWoman() {return woman;}public void setWoman(String woman) {this.woman = woman;}@Column(name="address" ,length=100)public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}}3)新建远程接口类FamilyDAORemote.java定义两个接口:新增、根据主键查询package com.tgb.itoo.exam.service;import javax.ejb.Remote;import com.tgb.itoo.exam.entity.Family;@Remotepublic interface FamilyDAORemote {// 新增public boolean insert(Family family);// 插入public Family selectByPK(String man, String woman);}4)开发实现类FamilyDAO.java1.首先构造一个主键对象FamilyPK2.后调用find()方法根据该主键对象进行查询package com.tgb.itoo.exam.papermanage.serviceimpl;import javax.ejb.Stateless;import javax.persistence.EntityManager;import com.tgb.itoo.exam.entity.Family;import com.tgb.itoo.exam.entity.FamilyPK;import com.tgb.itoo.exam.service.FamilyDAORemote;@Statelesspublic class FamilyDAO implements FamilyDAORemote {protected EntityManager em;@Overridepublic boolean insert(Family family) {try {em.persist(family);} catch (Exception e) {e.printStackTrace();return false;}return true;}@Overridepublic Family selectByPK(String man, String woman) {FamilyPK epk = new FamilyPK(man, woman);return em.find(Family.class, epk);}}

5)测试:客户端调用

不要因为世态变迁而埋怨,不要因为命运多舛而怨恨.

持久化API(JPA)系列(七)实体关系映射(ORM)之单表映射@IdClass

相关文章:

你感兴趣的文章:

标签云: