持久化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()相同的概率越小越好,算法可以进行优化。
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.tgb.itoo.exam.entity;  
  2.   
  3. import java.io.Serializable;  
  4. @SuppressWarnings("serial")  
  5. public class FamilyPK implements Serializable {  
  6.   
  7.     private String man;//丈夫  
  8.     private String woman;//妻子  
  9.   
  10.     public String getMan() {  
  11.         return man;  
  12.     }  
  13.   
  14.     public void setMan(String man) {  
  15.         this.man = man;  
  16.     }  
  17.   
  18.     public String getWoman() {  
  19.         return woman;  
  20.     }  
  21.   
  22.     public void setWoman(String woman) {  
  23.         this.woman = woman;  
  24.     }  
  25.   
  26.     public FamilyPK() {  
  27.   
  28.     }  
  29.   
  30.     public FamilyPK(String man, String woman) {       
  31.         this.man = man;  
  32.         this.woman = woman;  
  33.     }  
  34.   
  35.     @Override  
  36.     public int hashCode() {  
  37.         final int prime = 31;  
  38.         int result = 1;  
  39.         result = prime * result + ((man == null) ? 0 : man.hashCode());  
  40.         result = prime * result + ((woman == null) ? 0 : woman.hashCode());  
  41.         return result;  
  42.     }  
  43.   
  44.     @Override  
  45.     public boolean equals(Object obj) {  
  46.         if (this == obj)  
  47.             return true;  
  48.         if (obj == null)  
  49.             return false;  
  50.         if (getClass() != obj.getClass())  
  51.             return false;  
  52.         FamilyPK other = (FamilyPK) obj;  
  53.         if (man == null) {  
  54.             if (other.man != null)  
  55.                 return false;  
  56.         } else if (!man.equals(other.man))  
  57.             return false;  
  58.         if (woman == null) {  
  59.             if (other.woman != null)  
  60.                 return false;  
  61.         } else if (!woman.equals(other.woman))  
  62.             return false;  
  63.         return true;  
  64.     }  
  65.   
  66. }  

2)使用@IdClass在实体Bean类Family.java中指定外部主键。

通过注释符来设置与表、字段的映射关系。
注意,该实体中需要标注联合主键:
1、在man和woman的getter函数前都添加@Id注释符,表示都是主键
2、在类名钱使用@IdClass引用外部主键类
 
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.tgb.itoo.exam.entity;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. import javax.persistence.Column;  
  6. import javax.persistence.Entity;  
  7. import javax.persistence.Id;  
  8. import javax.persistence.IdClass;  
  9. import javax.persistence.Table;  
  10.   
  11. @SuppressWarnings("serial")  
  12. @Entity  
  13. @Table(name="family")  
  14. @IdClass(FamilyPK.class)  
  15. public class Family implements Serializable {  
  16.   
  17.     private String man;// 丈夫  
  18.     private String woman;// 棋子  
  19.     private String address;// 地址  
  20.   
  21.     @Id  
  22.     public String getMan() {  
  23.         return man;  
  24.     }  
  25.   
  26.     public void setMan(String man) {  
  27.         this.man = man;  
  28.     }  
  29.   
  30.     @Id  
  31.     public String getWoman() {  
  32.         return woman;  
  33.     }  
  34.   
  35.     public void setWoman(String woman) {  
  36.         this.woman = woman;  
  37.     }  
  38.   
  39.     @Column(name="address" ,length=100)  
  40.     public String getAddress() {  
  41.         return address;  
  42.     }  
  43.   
  44.     public void setAddress(String address) {  
  45.         this.address = address;  
  46.     }  
  47.   
  48. }  

3)新建远程接口类FamilyDAORemote.java
定义两个接口:新增、根据主键查询
 
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.tgb.itoo.exam.service;  
  2.   
  3. import javax.ejb.Remote;  
  4.   
  5. import com.tgb.itoo.exam.entity.Family;  
  6.   
  7. @Remote  
  8. public interface FamilyDAORemote {  
  9.     // 新增  
  10.     public boolean insert(Family family);  
  11.   
  12.     // 插入  
  13.     public Family selectByPK(String man, String woman);  
  14.   
  15. }  

4)开发实现类FamilyDAO.java
1.首先构造一个主键对象FamilyPK
2.后调用find()方法根据该主键对象进行查询
 
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.tgb.itoo.exam.papermanage.serviceimpl;  
  2.   
  3. import javax.ejb.Stateless;  
  4. import javax.persistence.EntityManager;  
  5.   
  6. import com.tgb.itoo.exam.entity.Family;  
  7. import com.tgb.itoo.exam.entity.FamilyPK;  
  8. import com.tgb.itoo.exam.service.FamilyDAORemote;  
  9.   
  10. @Stateless  
  11. public class FamilyDAO implements FamilyDAORemote {  
  12.   
  13.     protected EntityManager em;  
  14.   
  15.     @Override  
  16.     public boolean insert(Family family) {  
  17.         try {  
  18.             em.persist(family);  
  19.         } catch (Exception e) {  
  20.             e.printStackTrace();  
  21.             return false;  
  22.         }  
  23.         return true;  
  24.     }  
  25.   
  26.     @Override  
  27.     public Family selectByPK(String man, String woman) {  
  28.         FamilyPK epk = new FamilyPK(man, woman);  
  29.         return em.find(Family.class, epk);  
  30.     }  
  31.   
  32. }  

5)测试:客户端调用

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.tgb.itoo.exam.papermanage.serviceimpl;  
  2.   
  3. import java.util.Properties;  
  4.   
  5. import javax.naming.InitialContext;  
  6. import javax.naming.NamingException;  
  7.   
  8. import com.tgb.itoo.exam.entity.Family;  
  9. import com.tgb.itoo.exam.service.FamilyDAORemote;  
  10.   
  11. public class FamilyDAOClient {  
  12.   
  13.     public static void main(String[] args) throws NamingException {  
  14.         //........  
  15.         InitialContext ctx=new InitialContext();  
  16.         FamilyDAORemote familyDAO=(FamilyDAORemote) ctx.lookup("FamilyDAO/remote");  
  17.           
  18.         //新增  
  19.         Family family=new Family();  
  20.         family.setMan("丈夫");  
  21.         family.setWoman("妻子");  
  22.         family.setAddress("地址");          
  23.         familyDAO.insert(family);  
  24.           
  25.         //查询  
  26.         Family family2=familyDAO.selectByPK("丈夫的名称""妻子的名称");  
  27.         System.out.println(family2.getAddress());  
  28.     }  
  29.   
  30. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值