双向一对多外联关系(外键)

首先是两个Bean类,Customer用户类,Order订单类,其中Order订单中添加了外键,引用Customer的字段

Customer类

//用户
public  class Customer {

    //用户ID
    private Integer customerId;
    //用户名
    private String customerName;

    /**
     * 1:声明集合类型时,需使用接口类型,因为Hibernate在获取
     * 集合类型时,返回的是Hibernate内置的集合类型,而不是Java SE一个标准的
     * 集合实现
     * 2:需要把集合初始化,防止空指针异常
     */
    private Set<Order> orders = new HashSet<Order>();




    public Set<Order> getOrders() {
        return orders;
    }

    public void setOrders(Set<Order> orders) {
        this.orders = orders;
    }

    public Customer() {
        super();
    }

    public Customer(Integer customerId, String customerName) {
        super();
        this.customerId = customerId;
        this.customerName = 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;
    }

    @Override
    public String toString() {
        return "Customer [customerId=" + customerId + ", customerName="
                + customerName + "]";
    }
}

Order类

//订单类
public class Order {
    //订单ID
    private Integer orderId;
    //订单名
    private String orderName;
    //外键,引用Customer
    private Customer customer;

    public Order() {
        super();
    }
    public Order(Integer orderId, String orderName, Customer customer) {
        super();
        this.orderId = orderId;
        this.orderName = orderName;
        this.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;
    }
    @Override
    public String toString() {
        return "Order [orderId=" + orderId + ", orderName=" + orderName
                + ", customer=" + customer + "]";
    }


}

然后是XML配置文件

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 package="entity2">

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

        <!-- id:表中的主键,name:类中的属性名 -->
        <id name="customerId" type="java.lang.Integer">
            <!-- name:表中的序列名 -->
            <column name="customer_id"/>
            <!-- 指定主键的生成方式,native:使用数据库本地的方式 -->
            <generator class="native"/>
        </id>

        <!-- property一般字段 -->
        <property name="customerName" type="java.lang.String">
            <column name="customer_name"/>
        </property>

        <!-- 
            table:与Order的表名对应
            key的column:与Order的外键字段名对应
            inverse:true,Customer放弃维护Order的外键引用
                    可以减少UPDATE语句
         -->
        <set name="orders" table="orders" inverse="true">
            <key column="customer_id"></key>
            <one-to-many class="Order"/>
        </set>

    </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="entity2">
    <class name="Order" table="orders">

        <!-- id:表中的主键,name:类中的属性名 -->
        <id name="orderId" type="java.lang.Integer">
            <!-- name:表中的序列名 -->
            <column name="order_id"/>
            <!-- 指定主键的生成方式,native:使用数据库本地的方式 -->
            <generator class="native"/>
        </id>

        <!-- property一般字段 -->
        <property name="orderName" type="java.lang.String">
            <column name="order_name"/>
        </property>

        <!-- 映射多对一的关联关系 -->
        <many-to-one name="customer" class="Customer" column="customer_id"></many-to-one>

    </class>
</hibernate-mapping>

hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?> 
     <!DOCTYPE hibernate-configuration PUBLIC 
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <!-- 配置连接数据库的基本信息 -->
        <property name="connection.username">root</property>
        <property name="connection.password">1234</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>

        <!-- 配置Hibernate的基本信息 -->
        <!-- Hibernate所使用的数据库方言 -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- 执行操作时是否在控制台打印SQL -->
        <property name="show_sql">true</property>

        <!-- 是否对SQL进行格式化 -->
        <property name="format_sql">true</property>

        <!-- 指定自动生成数据表的策略 -->
        <property name="hbm2ddl.auto">update</property>

        <!-- 指定   关联的关系/映射   文件,引入Bean的xml文件 -->
        <!-- 注:不是打.  用/ -->
        <!-- <mapping resource="entity1/Customer.hbm.xml"/>
        <mapping resource="entity1/Order.hbm.xml"/> -->

        <mapping resource="entity2/Customer.hbm.xml"/>
        <mapping resource="entity2/Order.hbm.xml"/>

    </session-factory>
</hibernate-configuration> 

HibernateTest测试类

public class HibernateTest {
    private SessionFactory sessionFactory;
    private Session session;
    private Transaction transaction;

    @Before
    public void init() {
        // 1.创建一个SessionFactory 对象
        sessionFactory = null;
            // 1.创建Configuration对象:对应Hibernate的基本配置信息和对象关系映射信息
            // configure();读取配置文件,无参默认读取hibernate.cfg.xml
            Configuration configuration = new Configuration().configure();

            /**
             * new Configuration 的几个方法
             * 
             * 读取的是hibernate.properties配置文件
             * 1:Configuration configuration = new Configuration();
             * 
             * 读取配置文件,无参默认读取hibernate.cfg.xml
             * 2:Configuration configuration = new Configuration().configure();
             * 
             * 读取配置文件,读取指定xml,传入一个File
             * 3:Configuration configuration = new Configuration().configure(file);
             */

            // 2.创建一个ServiceRegistry对象
            // Hibernate 的任何配置和服务都需要在该对象中注册后才有效
            ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
                .applySettings(configuration.getProperties())
                .buildServiceRegistry();
            // 3.创建一个SessionFactory
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
        // 2.创建一个Session对象
        session = sessionFactory.openSession();

        // 3.开启事物
        transaction = session.beginTransaction();
    }

    @After
    public void distroy() {
        // 5.提交事物
        transaction.commit();

        // 6.关闭Session对象
        session.close();

        // 7.关闭SessionFactory对象
        sessionFactory.close();
    }

    @Test 
    public void test1(){

        Customer customer = new Customer();
        customer.setCustomerName("1");

        Order order1 = new Order();
        Order order2 = new Order();

        order1.setOrderName("1");
        order2.setOrderName("2");

        //设置外键关系
        order1.setCustomer(customer);
        order2.setCustomer(customer);

        //在customer中添加引用该外键的Order订单
        customer.getOrders().add(order1);
        customer.getOrders().add(order2);

        /**
         * 先插入Customer,在插入Order
         * 3条INSERT,2条UPDATE
         * 因为Customer和Order都维护关联关系,所以
         * Order插入后,Customer会更新(UPDATE)Order的外键
         * 
         * 可以在Customer的配置文件Set中指定节点inverse="true"
         * 放弃维护Order的外键引用,会只有3条INSERT
         */
        session.save(customer);
        session.save(order1);
        session.save(order2);



        /**
         * 先插入Order,在插入Customer
         * 3条INSERT,4条UPDATE
         * 因为Customer和Order都维护关联关系
         * 
         * 可以在Customer的配置文件Set中指定节点inverse="true"
         *  放弃维护Order的外键引用,会只有3条INSERT,2条UPDATE
         */
        //Order负责更新order1记录
        session.save(order1);
        //Order负责更新order2记录
        session.save(order2);
        //Customer负责更新order1,order2记录
        session.save(customer);
    }

    //查
    @Test
    public void test2(){
        /**
         * 对customer里的orders List集合使用延迟加载
         * 如果不使用orders的List集合,则不发生SQL查询Order语句
         */
        Customer customer = (Customer) session.get(Customer.class,1);

        /**
         * 返回的集合为Hibernate内置的集合类型
         * 该类型具有延迟加载和存放代理对象的功能
         */
        Set<Order> orders = customer.getOrders();
    }

    //查
    @Test
    public void test3(){
        Customer customer = (Customer) session.get(Customer.class,1);
        /**
         * 可能会抛出LazyInitializationException异常
         * 如果customer还没有使用orders集合
         * 且session.close()
         * 则抛异常
         */
        session.close();
        System.out.println(customer.getOrders().size());
    }


    //改
    @Test
    public void test4(){
        //可以利用customer里的orders Set集合更改order
        Customer customer = (Customer) session.get(Customer.class,1);
        //但是更改的哪个order是不确定的,因为Set集合特性:无序
        customer.getOrders().iterator().next().setOrderName("GGG");
    }

    //删
    @Test
    public void test5(){
        /**
         * 在不设置级联关系的情况下,并且被引用的外键(Customer用户表)
         * 有被Order(订单表)引用外键,不能直接删除customer
         */
        Customer customer = (Customer) session.get(Customer.class,1);
        session.delete(customer);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值