Hibernate-映射关系- n->1(单向)

来源:互联网 发布:战网获取数据索引很慢 编辑:程序博客网 时间:2024/05/10 13:18
前言:
        在领域模型中, 类与类之间最普遍的关系就是关联关系. 
        在 UML 中, 关联是有方向的. 
        以 Customer 和 Order 为例: 一个用户能发出多个订单, 而一个订单只能属于一个客户. 从 Order 到 Customer 的关联是多对一关联; 而从 Customer 到 Order 是一对多关联
详细介绍:
单向关联:单向 n-1
单向 n-1 关联只需从 n 的一端可以访问 1 的一端
域模型: 从 Order 到 Customer 的多对一单向关联需要在Order 类中定义一个 Customer 属性, 而在 Customer 类中无需定义存放 Order 对象的集合属性
关系数据模型:ORDERS 表中的 CUSTOMER_ID 参照 CUSTOMER 表的主键
Hibernate 使用 <many-to-one> 元素来映射多对一关联关系
<many-to-one> 元素来映射组成关系
name: 设定待映射的持久化类的属性的名字
column: 设定和持久化类的属性对应的表的外键
class:设定待映射的持久化类的属性的类型

实现代码:

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>        <class name="com.cgc.hibernate.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>
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.cgc.hibernate.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> <!-- 映射多对一的关联关系 --> <!--  name:多这一端 关联的一那一端的属性名字; class:一那一端的属性对应的类型; column:一那一端在多的一端对应的数据表中的外键的名字;  -->        <many-to-one name="customer" class="Customer" column="CUSTOMER_ID"></many-to-one>    </class></hibernate-mapping>
Customer.java

/* * 文件名:Customer.java * 版权:Copyright by www.huawei.com * 描述: * 修改人:Cuigaochong * 修改时间:2015-10-23 * 跟踪单号: * 修改单号: * 修改内容: */package com.cgc.hibernate.n21;/** * <一句话功能简述> * <功能详细描述> *  * @author  姓名 工号 * @version  [版本号, 2015-10-23] * @see  [相关类/方法] * @since  [产品/模块版本] */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.java

/* * 文件名:Order.java * 版权:Copyright by www.huawei.com * 描述: * 修改人:Cuigaochong * 修改时间:2015-10-23 * 跟踪单号: * 修改单号: * 修改内容: */package com.cgc.hibernate.n21;/** * <一句话功能简述> <功能详细描述> *  * @author 姓名 工号 * @version [版本号, 2015-10-23] * @see [相关类/方法] * @since [产品/模块版本] */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;    }    }
调测类

/* * 文件名:HibernateTest.java * 版权:Copyright by www.huawei.com * 描述: * 修改人:Cuigaochong * 修改时间:2015-10-22 * 跟踪单号: * 修改单号: * 修改内容: */package com.cgc.hibernate.n21;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.cfg.Configuration;import org.hibernate.service.ServiceRegistry;import org.hibernate.service.ServiceRegistryBuilder;import org.junit.After;import org.junit.Before;import org.junit.Test;/** * <一句话功能简述> <功能详细描述> *  * @author 姓名 工号 * @version [版本号, 2015-10-22] * @see [相关类/方法] * @since [产品/模块版本] */public class HibernateTest{    private SessionFactory sessionFactory;        private Session session;        private Transaction transaction;        @Before    public void init()    {        Configuration configuration = new Configuration().configure();        // 创建一个ServiceRegisttry对象:hibernate 4.x,新添加的对象,hibernate的任何配置和服务器都需要        // 在该配置中注册后才能生效        ServiceRegistry serviceRegistry =            new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();        sessionFactory = configuration.buildSessionFactory(serviceRegistry);                session = sessionFactory.openSession();        // 开启事物        transaction = session.beginTransaction();    }        @After    public void detory()    {        transaction.commit();        session.close();        sessionFactory.close();    }        @Test    public void test()    {        Customer customer = new Customer();        customer.setCustomerName("Cui01");                Order order00 = new Order();        order00.setOrderName("order02");                Order order01 = new Order();        order01.setOrderName("order03");        // 设定关联关系        order00.setCustomer(customer);        order01.setCustomer(customer);        // 执行save 先插入Customer,在插入order,执行了三条inserts        // 先插一的一端,在插n的一端只有insert,除了序列化        // session.save(customer);        // session.save(order00);        // session.save(order01);                // 先插入order,在插入customer 执行3条insert 2条update        // 先插入N的一端 在插入1的一端,会执行三条insert 2条update,执行效率会底。因为在插入N的时候,不能确定1的一端的外键值        // 只能在1插入后 后执行更新。        session.save(order00);        session.save(order01);        session.save(customer);            }        @Test    public void testGet()    {        // 若查询多的一端的对象,则默认情况下,只查询多的一端的对象 而没有查询关联的一的一端的对象        Order order = (Order)session.get(Order.class, 41);        System.out.println(order);                session.close();                Customer customer = order.getCustomer();        // 在需要使用关联对象的时候才会发送对应的sql        System.out.println(customer);                // 在查询customer对象时,由多的一端导航到1的一端时,可能会发生懒加载异常LazyInitializationException                // 获取Order对象时,默认情况下,其关联的Customer对象是一个代理对象            }        @Test    public void testUpdate()    {        Order order = (Order)session.get(Order.class, 41);        order.getCustomer().setCustomerName("QWE");    }        @Test    public void testDelete()    {        // 在不设定级联关系的情况下,且1这一端的对象有n的对象在引用,不能直接删除1这一端的对象        Customer c = (Customer)session.get(Customer.class, 43);        session.delete(c);    }    }

1 0