一对一主键双向关联(在数据库层控制级联删除)

especialjie 2010-05-12

--数据库oracle

在数据库设计里,one-to-one模型可以用2种方法来实现。

1,主键关联:这时候要保证2个表的主键具有完全相同的值。

2,外键关联:其中一个表使用外键关联另一个表。

模型:person vs idcard (人:身份证)

--这是带主外键关联的两张表。

--删除表

DROPTABLEidcard;

DROP TABLE person ;

-- 创建表

CREATETABLEperson

(

idVARCHAR2(32)PRIMARYKEY,

nameVARCHAR2(20)NOTNULL,

ageNUMBER

);

CREATETABLEidcard

(

idVARCHAR2(32)REFERENCESperson(id)ONDELETECASCADE,

serialVARCHAR2(18)NOTNULL,

expiryNUMBER

) ;

2、pojo类

publicclassPerson{

privateStringid;//perosn的id

privateStringname;//名字

privateintage;//年龄

privateIdCardidcard;

}

public class IdCard {

privateStringid;//卡号

privateStringserial;//卡的号码

privateintexpiry;//可以使用年限

}

3、添加和删除的测试类。

publicclassPersonIdCardOperation{

 private Session session = null;

 public PersonIdCardOperation() {

this.session=newConfiguration().configure().buildSessionFactory()

.openSession();

 }

 // 先插入一个用户

publicvoidinsert(Personper){

this.session.save(per);

this.session.beginTransaction().commit();

session.close();

}

publicvoiddelete(Stringid)

{

Stringhql="DELETEFROMPersonWHEREid=?";

Queryq=this.session.createQuery(hql);

q.setString(0,id);

q.executeUpdate();

this.session.beginTransaction().commit();

 }

 /**

*@paramargs

*/

publicstaticvoidmain(String[]args){

PersonIdCardOperationpo=newPersonIdCardOperation();

Personper=newPerson();

per.setName("jack");

  per.setAge(25);

//         准备好一张身份证

IdCardic=newIdCard();

ic.setSerial("888888888888888");

ic.setExpiry(12);

per.setIdcard(ic);

  ic.setPerson(per);

//  po.insert(per) ;

po.delete("ff8080812887f59c012887f59d080001");

 }

}

4、person配置文件

<hibernate-mapping>

<classname="org.onetoone.com.Person"table="person">

<idname="id"type="java.lang.String">

<columnname="id"length="32"/>

<generatorclass="uuid.hex"></generator>

</id>

<propertyname="name"type="java.lang.String">

<columnname="name"length="20"not-null="true"/>

</property>

<propertyname="age"type="java.lang.Integer">

<columnname="age"/>

</property>

<!--下面中的cascade="all",级联保存person对象关联的idcard对象。-->

<one-to-onename="idcard"

class="org.onetoone.com.IdCard"

cascade="all"

outer-join="true">

</one-to-one>

</class>

</hibernate-mapping>

5、idCard配置文件

<hibernate-mapping>

<classname="org.onetoone.com.IdCard"table="idcard">

<!--引用Person的主键作为idCard的主键和外键-->

<idname="id"column="id"type="java.lang.String">

<generatorclass="foreign">

<paramname="property">person</param>

</generator>

  </id>

  <one-to-one name="person"

class="org.onetoone.com.Person"

constrained="true">

  </one-to-one>

  <property name="serial" type="java.lang.String">

<columnname="serial"length="18"not-null="true"/>

</property>

<propertyname="expiry"type="java.lang.Integer">

<columnname="expiry"not-null="true"/>

</property>

</class>

</hibernate-mapping>

6、总结一些属性的用法。

person配置文件中的一些属性:

1、class="uuid.hex"用uuid.hex会自动生成的一个32位值。

2、cascade="all"解释一下cascade的用法:

all:所有情况下均进行关联操作,all的意思是save-update+delete。

none:所有情况下均不进行关联操作。这是默认值。

save-update:在执行save/update/saveOrUpdate时进行关联操作。

delete:在执行delete时进行关联操作。

      all-delete-orphan 的意思是当对象图中产生孤儿节点时,在数据库中删除该节点

      all比较好理解,举个例子说一下all-delete-orphan:

Category与Item是一对多的关系,也就是说Category类中有个Set类型的变量items.

举个例子,现items中存两个Item,item1,item2,如果定义关系为all-delete-orphan

当items中删除掉一个item(比如用remove()方法删除item1),那么被删除的Item类实例

将变成孤儿节点,当执行category.update(),或session.flush()时

hibernate同步缓存和数据库,会把数据库中item1对应的记录删掉

3、outer-join="true":解释一下outer-join的用法:

outer-join参数允许下列三个不同值:

auto:(默认)使用外连接抓取关联(对象),如果被关联的对象没有代理(proxy)

true:一直使用外连接来抓取关联

false:永远不使用外连接来抓取关联

   4、因为是双向关联,所以每个配置文件里面都要配<one-to-one>的关联关系

   idCard配置文件中的一些属性:

constrained="true":解释一下constrained的用法。(这个属性的说明是个难点吧)

1、constrained的默认值是false。

2、级联删除我是在数据库层设置的。这里的constrained就没有什么用了。

3、要是不在数据库中控制级联删除。设个属性还是有用的。

hibernate中constrained主要是在one-to-one的foreign主键生成策略的映射中使用。手册上说:

  constrained(约束) (可选) 表明该类对应的表对应的数据库表,和被关联的对象所对应的数据库表之间,通过一个外键引用对 

 主键进行约束。这个选项影响save()和delete()在级联执行时的先后顺序以及 决定该关联能否被委托(也在schema export tool 

中被使用).  如果constrained=true,则表明存在外键与关联表对应,并且关联表中肯定存在对应的键与其对应。hibernate生成的sql将使用

  inner join. 另外该选项最关键的是影响save和delete的先后顺序。例如增加的时候,如果constainted=true,则会先增加关联 

表,然后增加本表。删除的时候反之

7、本程序的级联删除是在数据库层控制的。

    

 

相关推荐