Hibernate关系映射

1.数据对象三种关系

Hibernate框架基于ORM设计思想,它将关系型数据库中的表与我们JAVA中的类进行映射,一个对象就对应着表中的一条记录,而表中的字段对应类的属性。数据库中表与表之间存在着三种关系,也就是系统设计中三种实体关系。

 - 一对一
原则有两种:
1.唯一外键对应:在任意一方来添加一个外键描述对应关系。
2.主键对应。
class Employee{

    private Archives archives;
}
class Archives{
    private Employee employee;
}

 - 一对多:我们在建表时原则:在多的一方添加外键来描述他们的对应关系。
 class Customer{
    Private Set<order> orders;
}
 Class Order{
    private Customer c;
}

 - 多对多:对于多对多关系,在描述时会通过一张中间表来描述其对应关系。
Class student{
    private Set<Techer> ts;
}

Class Techer{
    Set<student> ss;
}

2.一对多、多对一

1.Customer
public class Customer {
    private Integer id;
    private String name;

//  描述客户可以有多个订单
    private Set<Order> orders = new HashSet<Order>();
<hibernate-mapping>

    <class name="oneToMany.Customer" table="t_customer">
        <id name="id" column="c_id">
            <generator class="identity"></generator>
        </id>

        <property name="name" column="c_name" length="20" not-null="true"></property>
        <!-- 一个客户关联多个订单 -->
        <set name="orders">
        <key column="c_customer_id" />

            <one-to-many class="cn.itheima.onrToMany.Order"/>
        </set>
        <!-- 

        使用set来描述在一的一方中关联的多 set<Order>, 它的name属性就是set集合的名称。
        key:主要是描述关联的多的一方产生的外键的名称,注意要与多的一方定义的外键名称相同
        one-to-many 描述集合中的类型。

         -->
    </class>

</hibernate-mapping>

2.Order
public class Order {
    private Integer id;
    private Double money;
    private String receiverInfo;

    private Customer customer;//描述订单属于某一个客户。

 <hibernate-mapping>

    <class name="oneToMany.Order" table="t_order">
        <id name="id" column="c_id">
            <generator class="identity"></generator>
        </id>

        <property name="money" column="c_name" ></property>
        <property name="receiverInfo" column="c_receiverInfo" length="50"></property>
        <!-- 多对一 -->
        <many-to-one name="customer" class="cn.itheima.oneToMany.Customer" column="c_customer_id"></many-to-one>
        <!-- 
        name属性它描述的是Order类中的一方的属性名称 Customer customer
        class代表一的一方的类型
        column描述的是一对多或者多对一的外键的名称c_customer_id
         -->

    </class>

</hibernate-mapping>

2.一对多测试

    @Test
    public void test01(){
        Session session = hibernateUtils.openSession();
        session.beginTransaction();

//      创建一个用户
        Customer customer = new Customer();
        customer.setName("hans");

//      创建两个订单
        Order order = new Order();
        order.setMoney(1000d);
        order.setReceiverInfo("china");

        Order order2 = new Order();
        order.setMoney(5000d);
        order.setReceiverInfo("shanghai");
//      建立关系
//      订单关系客户
        order.setCustomer(customer);
        order2.setCustomer(customer);

//      客户关联订单
        customer.getOrders().add(order);
        customer.getOrders().add(order2);

        session.save(order);
        session.save(order2);
        session.save(customer);
//      事务提交和关闭
        session.getTransaction().commit();
        session.close();
    }

3.单向关联:

问题:我们可不可以只保存订单或者只保存客户完成保存操作?
报异常:org.hibernate.TransientObjectException:
一个持久化对象关联了一个瞬时态对象。
## 我们可以使用级联操作来解决上述问题,我们现在要做的是保存订单时保存客户,需要在订单的hbm配置文件中修改 ##
设置cascade=save-update,那么在保存订单时就可以自动将客户保存。
<many-to-one name="customer" class="cn.itheima.oneToMany.Customer" column="c_customer_id" cascade="save-update"></many-to-one>

如果要完成保存客户时,保存订单
    <set name="orders" cascade="save-update">

4.双向关联配置

配置中,可以进行双向关联配置。--可以通过任意一方来操作对方
在操作中,避免双向操作。尽量进行单向关联。--减少资源浪费。
在双向关联中,会存在多于的Update语句。
我们可以使用inverse属性来设置,双线关联时由哪一方来维护表与表之间的关系。
<set name="orders" inverse="true">
inverse的值如果为true,由对方来维护外键。
inverse的值如果为false,由本方来进行维护外键。
关于inverse的取值:
*外键在哪一个表中,我们就让哪一方来维护外键。

5.级联删除。

我们在删除客户时,也要删除订单,如果没有做级联,那么这个操作时不允许的。
为了维护是数据完整性。
想要完成操作:我们可以在客户中添加cascade=”delete“
<set name="Customer" inverse="true" cascade="delete">



    @Test
    public void test03(){
        Session session = hibernateUtils.openSession();
        session.beginTransaction();

        Customer customer = session.get(Customer.class, 1);
        session.delete(customer);
//      事务提交和关闭
        session.getTransaction().commit();
        session.close();
    }
    @Test
    public void test04(){
        Session session = hibernateUtils.openSession();
        session.beginTransaction();

        Customer customer = session.get(Customer.class, 1);
        Order order = session.get(Order.class, 2);
        customer.getOrders().remove(order);
//      事务提交和关闭
        session.getTransaction().commit();
        session.close();
    }

6.cascade总结

使用cascade可以完成级联操作。
它可常用取值:
none:这是一个默认值
save-update:当我们配置它时,底层使用save update 或save-update完成操作,级联保存临时对象,如果是托管对象,会执行updatedelete:级联删除
delete-ophan:删除与当前对象解决关系的对象;
All:包含了save-update delete操作
All-delete-orphan:它包含了delete-orphan与All操作

Casscade与inverse的区别?
Cascade完成级联操作。
Inverse只有在双向关联情况下有作用,它来指定由哪一方来维护。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值