hibernate之表关系中的一对多

来源:互联网 发布:制冷系统仿真软件 编辑:程序博客网 时间:2024/05/16 10:48

数据库表与表的三种关系:

1. 一对一:一张表中的一条数据对应了另一张表中的一条数据,外键可以在任意一张表中

2. 一对多:一张表中的一条数据对应了另一张表中的多条数据,外键创建在多的一方中

3. 多对多:一张表中的多条数据对应了另一张表中的多条数据,建立中间表保存两张表的外键

一对多示例:

一方javabean:Customer.java

public class Customer {

private Long cust_id;

private String cust_name;

private String cust_source;

//使用set集合,表达一对多关系

private Set<LinkMan>linkMens = new HashSet<LinkMan>();

    //省略了所有setget方法...

}

一方映射文件Customer.hbm.xml:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC 

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.example.domain" >

<class name="Customer" table="cst_customer" >

<id name="cust_id"  >

<generator class="native"></generator>

</id>

<property name="cust_name" column="cust_name" ></property>

<property name="cust_source" column="cust_source" ></property>

name属性:集合属性名 column属性: 外键列名 class属性: 与我关联的对象完整类名

cascade save-update: 级联保存更新 delete:级联删除 all:save-update+delete

    <set name="linkMens" cascade="save-update" >

<key column="lkm_cust_id" ></key>

<one-to-many class="LinkMan" />

</set>

</class>

</hibernate-mapping>

 

多方javabean:LinkMan.java

public class LinkMan {

private Long lkm_id;

private Character lkm_gender;

private String lkm_name;

private Customer customer ;//维护多对一关系

//getset方法省略...

}

多方映射文件:LinkMan.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC 

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.example.domain" >

<class name="LinkMan" table="cst_linkman" >

<id name="lkm_id"  >

<generator class="native"></generator>

</id>

<property name="lkm_gender"  ></property>

<property name="lkm_name"  ></property>

name:属性名 column属性: 外键列名 class属性: 与我关联的对象完整类名

    多的一方: 不能放弃维护关系的.外键字段就在多的一方

<many-to-one name="customer" column="lkm_cust_id" cascade="save-update"  class="Customer"  >

</many-to-one>

</class>

</hibernate-mapping>

测试代码:

public class Demo {

@Test

//创建客户和联系人级联保存

public void fun1(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

Customer c = new Customer();

c.setCust_name("客户");

LinkMan lm1 = new LinkMan();

lm1.setLkm_name("联系人1");

LinkMan lm2 = new LinkMan();

lm2.setLkm_name("联系人2");

//1.一方(Customer)关联多方(联系人)级联保存

    //c.getLinkMens().add(lm1);

    //c.getLinkMens().add(lm2);

//session.save(c);//执行五条sql语句:三条insert语句和两条update更新外键语句

 

//2.多方(LinkMan)关联一方(Customer)级联保存

lm1.setCustomer(c);

lm2.setCustomer(c);

session.save(lm1);//两条insert语句语句

session.save(lm2);//两条insert语句语句

//第二次insert Customer时候因为一级缓存,不会再执行,故一共只有三条insert语句

tx.commit();

session.close();

}

@Test

public void fun2(){//给客户增加联系人级联保存

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

Customer customer = session.get(Customer.class,8l);

LinkMan linkMan = new LinkMan();

linkMan.setLkm_name("联系人3");

//1.多方关联一方,保存多方对象

//linkMan.setCustomer(customer);

//session.save(linkMan);//执行两条sql语句:一条select语句 一条insert语句

//2.一方关联多方,保存一方对象

customer.getLinkMens().add(linkMan);

session.save(customer);//执行四条sql语句:两条select 一条insert 一条update

tx.commit();

session.close();

}

@Test

//为客户删除联系人关系(实质是删除一对多关系中多方联系人保存的外键),联系人不删除

public void fun3(){

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();

Customer c = session.get(Customer.class,3l);

LinkMan lm = session.get(LinkMan.class, 11l);

//如果Customer不维护外键即设置了set标签的inverse="true",则不能移除关系(不会发出update语句把外键设置为null)

//1.Customer解除外键关系:执行4条sql语句:3条select语句 1条update语句

c.getLinkMens().remove(lm);

 

//一对多中多方LinkMan没有set标签,不能设置inverse属性,默认维护

//2.LinkMan解除外键关系:执行3条sql语句:2条select 1条update

//lm.setCustomer(null);

tx.commit();

session.close();

}

}

Hibernate中一对多的级联保存修改:

Hibernate中一对多的级联保存修改,由多方级联一方,由于外键在多方的原因,sql执行语句会大大减少

 

Hibernate中一对多的级联删除:

一方级联删除多方:

Customer c = session.get(Customer.class,1l);

session.delete(c);

多方级联删除一方:

LinkMan linkMan  = session.get(LinkMan .class,1l);

session.delete(linkMan);

1.多方级联删除一方,如果一的一方还关联了其他数据 则不能删除成功:3次select,1次update设置外键为null 2次delete

2.一方级联删除多方,可以级联删除关联的所有多方数据:sql执行顺序是:1.两次select查询一方和多方 2.一次update设置外键为null 3.N次delete(n=1+多方关联数据数目)


原创粉丝点击