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

来源:互联网 发布:如何在淘宝上买学分 编辑:程序博客网 时间:2024/06/06 15:03

一个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