程序员人生 网站导航

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

栏目:php教程时间:2015-05-11 09:28:17
       通过之前的文章,我们了解到@Table、@Column、@Id实现了单表的映照,并且书剑有1个@Id指定的唯1字段。有时我们的数据表或许是有多个主键联合组成的,因此对单表映照的主键,还可以进行以下两种联合主键映照。
        联合主键:使用@IdClass指定外部主键
        联合主键:使用@EmbeddedId嵌入外部主键


下面通过实例来看这两种主键的开发方法。
Demo:设计1个家庭表Family的数据结构

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

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

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

以实现外部主键的援用。


1)新建外部主键类FamilyPK.java
由于Family中设置联合主键man和woman,因另外部主键类FamilyPK也需要定义两个一样的变量,并添加1个以这两个变量为输入的构造函数,同时添加getter/setter函数。
作为外部主键需满足:
1.必须实现Serializable接口
2.必须有默许的public无参数的构造方法
3.必须覆盖equals()和hashCode()方法。
equals()方法用于判断两个对象是不是相同,EntityManager通过find()方法来查找实体,是根据equals()的返回值来判断的。本例中,只有对象的man和woman值完全相同或属于同1个对象时才返回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; } @Override public 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; } @Override public 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;// 地址 @Id public String getMan() { return man; } public void setMan(String man) { this.man = man; } @Id public 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; @Remote public interface FamilyDAORemote { // 新增 public boolean insert(Family family); // 插入 public Family selectByPK(String man, String woman); }

4)开发实现类FamilyDAO.java
1.首先构造1个主键对象FamilyPK
2.后调用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; @Stateless public class FamilyDAO implements FamilyDAORemote { protected EntityManager em; @Override public boolean insert(Family family) { try { em.persist(family); } catch (Exception e) { e.printStackTrace(); return false; } return true; } @Override public Family selectByPK(String man, String woman) { FamilyPK epk = new FamilyPK(man, woman); return em.find(Family.class, epk); } }

5)测试:客户端调用

 

package com.tgb.itoo.exam.papermanage.serviceimpl; import java.util.Properties; import javax.naming.InitialContext; import javax.naming.NamingException; import com.tgb.itoo.exam.entity.Family; import com.tgb.itoo.exam.service.FamilyDAORemote; public class FamilyDAOClient { public static void main(String[] args) throws NamingException { //........ InitialContext ctx=new InitialContext(); FamilyDAORemote familyDAO=(FamilyDAORemote) ctx.lookup("FamilyDAO/remote"); //新增 Family family=new Family(); family.setMan("丈夫"); family.setWoman("妻子"); family.setAddress("地址"); familyDAO.insert(family); //查询 Family family2=familyDAO.selectByPK("丈夫的名称", "妻子的名称"); System.out.println(family2.getAddress()); } }

下文中将通过Demo演示《联合主键:使用@EmbeddedId嵌入外部主键


------分隔线----------------------------
------分隔线----------------------------

最新技术推荐