Hibernate中的映射关系(一对多)

在数据库中表和表之间的关系有几种,下面就详细说一下在Hibernate中怎样映射一对多的关系

Hibernate映射一对多的关系,其实就是持久类之间的映射,那如何把持久类关联起来呢??那就用到.hbm.xml文件的<many-to-one>标签了

具体做法如下:

  新建一个customer类:
  

package com.jeremy.hibernate.app.example;

public class Customer {

    private Integer customerId;
    private String customerName;

    public Integer getCustomerId() {
        return customerId;
    }

    public void setCustomerId(Integer customerId) {
        this.customerId = customerId;
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

}

再新建一个订单表order表

package com.jeremy.hibernate.app.example;

public class Order {
    
    private Integer orderId;
    private String orderName;
    
    private Customer customer;

    public Integer getOrderId() {
        return orderId;
    }

    public void setOrderId(Integer orderId) {
        this.orderId = orderId;
    }

    public String getOrderName() {
        return orderName;
    }

    public void setOrderName(String orderName) {
        this.orderName = orderName;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
    
    
    
}

那这个两个类怎样关联起来呢??
那就需要通过那就用到.hbm.xml文件的<many-to-one>标签了
在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="com.atguigu.hibernate.entities.n21">

    <class name="Order" table="ORDERS">

        <id name="orderId" type="java.lang.Integer">
            <column name="ORDER_ID" />
            <generator class="native" />
        </id>
        
        <property name="orderName" type="java.lang.String">
            <column name="ORDER_NAME" />
        </property>
        
        <!-- 
            映射多对一的关联关系。 使用 many-to-one 来映射多对一的关联关系 
            name: 多这一端关联的一那一端的属性的名字
            class: 一那一端的属性对应的类名
            column: 一那一端在多的一端对应的数据表中的外键的名字
        -->
        <many-to-one name="customer" class="Customer" column="CUSTOMER_ID"></many-to-one>

    </class>
</hibernate-mapping>

customer.hbm.xml文件像普通的那样配置即可
example:

<?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>
    
    <class name="com.atguigu.hibernate.entities.n21.Customer" table="CUSTOMERS">
    
        <id name="customerId" type="java.lang.Integer">
            <column name="CUSTOMER_ID" />
            <generator class="native" />
        </id>
    
        <property name="customerName" type="java.lang.String">
            <column name="CUSTOMER_NAME" />
        </property>
        
    </class>
    
</hibernate-mapping>

这样就可以把表的一对多关系建立起来了,

建立起来后最重要的是访问,也就是我们怎么在Hibernate中进行多表增删改操作呢??这又是一个关键的问题

  增:

    

@Test
    public void testMany2OneSave(){
        Customer customer = new Customer();
        customer.setCustomerName("BB");
        
        Order order1 = new Order();
        order1.setOrderName("ORDER-3");
        
        Order order2 = new Order();
        order2.setOrderName("ORDER-4");
        
        //设定关联关系,比平常的要多一个设定关联关系的语句,因为外键必须得根据外键的,多以在插入的order表时要么新增一个customer要      么就查询一个customer,这个步骤尤为重要
        order1.setCustomer(customer);
        order2.setCustomer(customer);
        
        //执行  save 操作: 先插入 Customer, 再插入 Order, 3 条 INSERT
        //先插入 1 的一端, 再插入 n 的一端, 只有 INSERT 语句.(推荐使用注释的)
//        session.save(customer);
//        
//        session.save(order1);
//        session.save(order2);
        
        //先插入 Order, 再插入 Customer. 3 条 INSERT, 2 条 UPDATE
        //先插入 n 的一端, 再插入 1 的一端, 会多出 UPDATE 语句!
        //因为在插入多的一端时, 无法确定 1 的一端的外键值. 所以只能等 1 的一端插入后, 再额外发送 UPDATE 语句.
        //所以推荐先插入 1 的一端, 后插入 n 的一端(也就是注释的那部分)
        session.save(order1);
        session.save(order2);
        
        session.save(customer);
    }

  删delete:

@Test
    public void testDelete(){
        //在不设定级联关系的情况下, 且 1 这一端的对象有 n 的对象在引用, 不能直接删除 1 这一端的对象
        Customer customer = (Customer) session.get(Customer.class, 1);
        session.delete(customer); 
    }

  改update:

  

@Test
    public void testUpdate(){
        Order order = (Order) session.get(Order.class, 1);
        order.getCustomer().setCustomerName("AAA");
    }

  查select:

   

  @Test
    public void testSelect(){
        //1. 若查询多的一端的一个对象, 则默认情况下, 只查询了多的一端的对象. 而没有查询关联的1 的那一端的对象!
        Order order = (Order) session.get(Order.class, 1);
        System.out.println(order.getOrderName()); 
        
        System.out.println(order.getCustomer().getClass().getName());
        
        session.close();
        
        //2. 在需要使用到关联的对象时, 才发送对应的 SQL 语句. 
        Customer customer = order.getCustomer();
        System.out.println(customer.getCustomerName()); 
        
        //3. 在查询 Customer 对象时, 由多的一端导航到 1 的一端时, 
        //若此时 session 已被关闭, 则默认情况下
        //会发生 LazyInitializationException 异常
        
        //4. 获取 Order 对象时, 默认情况下, 其关联的 Customer 对象是一个代理对象!
        
    }

因为持久化对象的set()方法时可以触发Hibernate发送update语句,get()方法可以触发Hibernate发送select语句,我们可以通过外键表的get()和set()的方法对外键表进行更改和查询

 

 

  

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。