码迷,mamicode.com
首页 > Windows程序 > 详细

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

时间:2015-04-30 18:25:14      阅读:273      评论:0      收藏:0      [点我收藏+]

标签:embeddedid   idclass   ssh   

       通过以前的文章,我们了解到@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;
	}

	@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.首先构造一个主键对象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嵌入外部主键


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

标签:embeddedid   idclass   ssh   

原文地址:http://blog.csdn.net/zhaolijing2012/article/details/45396151

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!