Hibernate之一对多(多对一)

一、双向关联级联保存客户订单

1、搭建环境,项目结构如下

2、代码及配置如下(数据库里订单表不能用order,因为order是数据库关键字)(客户外键cid和订单表外键cid要在配置中写一致)

package com.hjp.onetomany;

import java.util.HashSet;
import java.util.Set;

/**
 * Created by JiaPeng on 2016/1/2.
 */
public class Customer {
    private int id;
    private String name;
    private Set<Order> orderSet=new HashSet<Order>() ;

    public Set<Order> getOrderSet() {
        return orderSet;
    }

    public void setOrderSet(Set<Order> orderSet) {
        this.orderSet = orderSet;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Customer{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", orderSet=" + orderSet +
                '}';
    }
}
Customer
<?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>
  <class name="com.hjp.onetomany.Customer" table="customer">
      <id name="id">
          <generator class="native"></generator>
      </id>
      <property name="name"></property>
      <set name="orderSet">
          <key column="cid"></key>
          <one-to-many class="com.hjp.onetomany.Order"></one-to-many>
      </set>
  </class>
</hibernate-mapping>
customer.hbm.xml
package com.hjp.onetomany;

/**
 * Created by JiaPeng on 2016/1/2.
 */
public class Order {
    private int id;
    private double price;
    private Customer customer=new Customer();

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public Customer getCustomer() {
        return customer;
    }

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

    @Override
    public String toString() {
        return "Order{" +
                "price=" + price +
                ", id=" + id +
                '}';
    }
}
Order
<?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>
   <class name="com.hjp.onetomany.Order" table="orders">
       <id name="id">
           <generator class="native"></generator>
       </id>
       <property name="price"></property>
       <many-to-one name="customer" class="com.hjp.onetomany.Customer" column="cid"></many-to-one>
   </class>
</hibernate-mapping>
order.hbm.xml
package com.hjp.utils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * Created by JiaPeng on 2016/1/2.
 */
public class HibernateUtils {
private static final SessionFactory sessionFactory;
    static {
        Configuration configuration=new Configuration().configure();
        sessionFactory=configuration.buildSessionFactory();
    }
    public static Session getSession(){
        return sessionFactory.openSession();
    }
}
HibernateUtils
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/h1</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">hjp123</property>
        <!--设置c3p0-->
        <property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
        <!--c3p0连接池配置信息-->
        <property name="c3p0.min_size">5</property>
        <property name="c3p0.max_size">20</property>
        <property name="c3p0.timeout">120</property>
        <property name="c3p0.idle_test_period">3000</property>
        <!--显示SQL并格式化-->
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <!--ddl生成策略,后面可以改为update-->
        <property name="hibernate.hbm2ddl.auto">create</property>
        <!--导入映射文件-->
        <!--<mapping resource="com/hjp/hbm/customer.hbm.xml"></mapping>-->
        <mapping resource="com/hjp/onetomany/customer.hbm.xml"></mapping>
        <mapping resource="com/hjp/onetomany/order.hbm.xml"></mapping>
    </session-factory>
</hibernate-configuration>
hibernate.cfg.xml
  @Test
    public void func2() {
        Session session = HibernateUtils.getSession();
        session.beginTransaction();
        //创建客户
        Customer customer = new Customer();
        customer.setName("张三");
        //创建两个订单
        Order order1 = new Order();
        order1.setPrice(121);
        Order order2 = new Order();
        order2.setPrice(122);
        //客户关联订单
        customer.getOrderSet().add(order1);
        customer.getOrderSet().add(order2);
        //订单关联客户
        order1.setCustomer(customer);
        order2.setCustomer(customer);
        session.save(customer);
        session.save(order1);
        session.save(order2);
        session.getTransaction().commit();
        session.close();
    }
测试类中测试方法

 二、配置中使用cascade,优化代码,单向关联完成客户和订单保存

注意:一般情况下配置上cascade后,只做单向关联即可,但是当我删除订单关联客户和保存订单的代码后总是报错save the transient instance before flushing,经各种检查后,无意间将上述Order类中的Customer类实例化方式删除后就好了

一般不需要在持久化类中实例化字段,订单类中也不需要,此处是为了方便使用

1、单向关联,只保存客户

在customer.hbm.xml中的set节点下配置cascade="save-update"即可

 

修改上述Order类

为:,即删除new Customer()

注释测试类中订单关联客户,和保存订单的代码,进行测试

 

2、单向关联,只保存订单

与单向关联,只保存客户相对

在order.hbm.xml 中的many-to-one节点设置cascade="save-update"即可

然后注释测试类中客户关联订单,和保存客户代码测试即可

三、cascade和inverse

cascade还有all-delete-orphan(all指save-update;delete-orphan级联删除和当前对象解除关系的对象)

inverse设置在set节点中,为true时表示由对方控制外键,为false时表示由自己控制外键

没有更多推荐了,返回首页