Java笔记:Hibernate关联の继承与联合主键

一个IT专业的学生记录日常中的点滴,当作笔记把。
自己本身也比较懒,写SSH的一个项目时,用到了继承和联合主键,以前没怎么关注,就去度娘了下,自己写的过程中遇到了不少问题,花了一整天让我很不爽,记下来以防再犯。


继承关联:
继承关联分为几种情况:
一:整个继承树映射到一张表;
二:父类建立一张表存放公共属性,每个子类一张表,存独立属性。
三:父类子类都各一张表(这种情况效率较低)。
首先用的PD建的数据库,先E-R,再逻辑模型再关系模型。建立三个实体:People、Seller、Customer。

public class People {
private int p_id;//人员信息表主键
private String name;//姓名
private String gender;//性别
private int age;//年龄
private String phone_number;//电话号码
    getter...setter...
}

public class Seller extends People{
private String address;//门店地址
        ...
}
public class Customer extends People{
private String id_code;//身份证
        ...
}

第一种情况配置在People.hb.xml

<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.test.hbm">
	<class name="People" table="people">
		<id name="p_id" >
			<generator class="native" />
		</id>
		<property name="name" />
		<property name="gender" />
		<property name="age" />
		<property name="phone_number" />
		<subclass name="Seller" discriminator-value="1">  
            		<property name="p_id"/>  
        	</subclass>
		<subclass name="Customer" discriminator-value="2">  
            		<property name="p_id"/>  
        	</subclass>
	</class>
</hibernate-mapping>


第二种情况也配置在People.hb.xml

<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.test.hbm">
	<class name="People" table="people">
		<id name="p_id" >
			<generator class="native" />
		</id>
		<property name="name" />
		<property name="gender" />
		<property name="age" />
		<property name="phone_number" />
		<joined-subclass name="Seller"
			table="seller">
			<key column="p_id" foreign-key="p_id"/>
			<property name="adress" />
		</joined-subclass>
		<joined-subclass name="Customer"
			table="customer">
			<key column="p_id" foreign-key="p_id"/>
			<property name="id_code" />
		</joined-subclass>
	</class>
</hibernate-mapping>


第三种情况各写一个配置文件,例:Customer.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.test.hbm">
	<class name="Customer" table="customer<span style="font-family: Arial, Helvetica, sans-serif;">"></span>
		<id name="p_id" >
			<generator class="identity" /><!-- 子表不能自增 否则ID会错乱 -->
		</id>
		<property name="name" />
		<property name="gender" />
		<property name="age" />
		<property name="phone_number" />
		<property name="id_code" />
	</class>
</hibernate-mapping>

我使用的第二种。在其中我碰到了一个状况让我很无语,查了很久也没找到错误,后来自己认真看这错误信息摸索了很久才发现。Hibernate是可以建立表和关系映射的,我使用PD建表时已经建立了映射,然后在测试时始终操作不了数据,总是报错外键建立失败,后来我把PD已经建立的联系删了,让Hibernate自动建立就OK了,希望大家注意这点。



联合主键

联合主键本来我想写成两个多对一,可是我又想自己写写看,然后还是碰到了和上面一样的问题。


联合主键即多对多关系中生成的那个关系表,关系表中会有两个主键也是外键,即联合主键。关系表中可以有其他的属性,我写的就是这样。

我写的是Car N-N Customer. 关系表:Order

写联合主键,需要在关系表Order配置,Order.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.test.hbm">
	<class name="Order" table="order">
		<composite-id name="pk"
			class="UnionPK">
			<!-- 联合主键,设置时数据库不需设置关联,让Hibernate
			自动生成,否则无法操作数据 -->
			<key-property name="b_id" column="b_id" />
			<key-property name="p_id" column="p_id" />
		</composite-id>
		<property name="buy_time" />
		<property name="cost" />
	</class>
</hibernate-mapping>

使用联合主键时,需单独建立一个联合主键实体类 UnionPK.class 还需要实现序列化接口,并重写hascode()、equals()函数.网上很多是String型的主键,我的主键一般是Int或Long型。

public class UnionPK implements Serializable{

private static final long serialVersionUID = 1L;
	
	private int p_id;
	private int b_id;
	
	public int getP_id() {
		return p_id;
	}
	public void setP_id(int p_id) {
		this.p_id = p_id;
	}
	public int getB_id() {
		return b_id;
	}
	public void setB_id(int b_id) {
		this.b_id = b_id;
	}
	

	 @Override  
	    public boolean equals(Object obj) {  
	        if(obj instanceof UnionPK){  
	        	UnionPK pk = (UnionPK)obj;  
	            if(this.p_id == pk.getP_id()&&this.b_id == pk.getB_id())  
	                return true;  
	            System.out.println("UnionPK -- true");
	        }  
	        return false;  
	    }  
	  
	    @Override  
	    public int hashCode() {
	    	return super.hashCode();
	    }
	
}

还需Order类,这才是数据库对应的表:

public class RentInfo {

	
	private UnionPK pk ;//联合主键
	private Timestamp buy_time;//购买时间
	private float cost;//费用
	public int getPk() {
		return pk;
	}
	public void setPk( UnionPK pk ) {
		this.pk = pk;
	}
}

 

这样配置就可以了,还是需要注意那一点,让Hibernate自动生成关联,否则一直报错,就这个错误害我找了好久,工具多了虽然方便问题也多了。

今天就写到这。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值