一个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自动生成关联,否则一直报错,就这个错误害我找了好久,工具多了虽然方便问题也多了。
今天就写到这。