zoukankan      html  css  js  c++  java
  • Hibernate -- 一对多的双向关联关系

    示例代码: 

    Customer.java

    package cn.itcast.many2onedouble;
    
    import java.util.HashSet;
    import java.util.Set;
    /**
     * 一的一端
     */
    @SuppressWarnings("serial")
    public class Customer implements java.io.Serializable {
    	
    	private Integer id;
    	private String name;
    	//一个客户对应多个订单
    	private Set<Order> orderes=new HashSet<Order>(0);
    	
    	public Integer getId() {
    		return id;
    	}
    	public void setId(Integer id) {
    		this.id = id;
    	}
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public Set<Order> getOrderes() {
    		return orderes;
    	}
    	public void setOrderes(Set<Order> orderes) {
    		this.orderes = orderes;
    	}
    
    }
    

    Order.java

    package cn.itcast.many2onedouble;
    
    /**
     * 多的一端
     */
    public class Order {
    	private Integer id;
    	private String orderNumber;
    	private Double price;
    	
    	//建立订单到客户的多一关联 
    	private Customer customer;
    
    	public Integer getId() {
    		return id;
    	}
    
    	public void setId(Integer id) {
    		this.id = id;
    	}
    
    	public String getOrderNumber() {
    		return orderNumber;
    	}
    
    	public void setOrderNumber(String orderNumber) {
    		this.orderNumber = orderNumber;
    	}
    
    	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;
    	}
    
    }
    


    App.java

    package cn.itcast.many2onedouble;
    
    import java.util.Iterator;
    import java.util.Set;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.Transaction;
    import org.hibernate.cfg.Configuration;
    import org.junit.Test;
    
    public class App {
    	private static  SessionFactory sf=null;
    	
    	static{
    		   Configuration config=new Configuration();
    	       config.configure("cn/itcast/many2onedouble/hibernate.cfg.xml");
    	       config.addClass(Customer.class);
    	       config.addClass(Order.class);
    	       sf=config.buildSessionFactory();
    	}
    	
          
    		
    		//知识点6:保存客户和订单(客户和订单建立双向关联)
    		@Test
    		public  void saveCustomerAndOrder(){
    			   Session session=sf.openSession();
    			   Transaction tx=session.beginTransaction();
    			   
    			   Customer c=new Customer();
    			   c.setName("关羽");
    			   
    			   Order o=new Order();
    			   o.setOrderNumber("NO1");
    			   o.setPrice(12d);
    			   
    			   //建立订单和客户的双向关联
    			   
    			   //建立订单和客户的关联
    			   o.setCustomer(c);
    			   
    			   //建立客户和订单的关联
    			   c.getOrderes().add(o); 
    			   
    			   //保存客户
    			   session.save(c);
    			   
    			   //保存订单
    			   session.save(o);
    			   
    			   tx.commit();
    			   session.close();
    		}
    		
    		//知识点7:保存客户和不保存订单
    		@Test
    		public  void saveCustomerAndOrderCase(){
    			   Session session=sf.openSession();
    			   Transaction tx=session.beginTransaction();
    			   
    			   Customer c=new Customer();
    			   c.setName("飞");
    			   
    			   Order o=new Order();
    			   o.setOrderNumber("NO2");
    			   o.setPrice(12d);
    			   
    			   //建立订单和客户的双向关联
    			   
    			   //建立订单和客户的关联
    			   o.setCustomer(c);
    			   
    			   //建立客户和订单的关联
    			   c.getOrderes().add(o); 
    			   
    			   //保存客户
    			   session.save(c);
    			   
    			   //保存订单
    			   //session.save(o);
    			   
    			   tx.commit();
    			   session.close();
    		}
    		
    		
    		//知识点8:查询客户和订单
    		@Test
    		public  void getCustomer(){
    			   Session session=sf.openSession();
    			   Transaction tx=session.beginTransaction();
    			   
    			   //从一的一端开始查询
    			   Customer c=(Customer)session.get(Customer.class, 2);
    			   System.out.println(c.getId()+"  "+c.getName());
    			   
    			   Set<Order> set=c.getOrderes();
    			   Iterator<Order>  it=set.iterator();
    			   while(it.hasNext()){
    				   Order o=it.next();
    				   System.out.println(o.getId()+"   "+o.getOrderNumber()+"   "+o.getPrice());
    			   }
    		
    			   tx.commit();
    			   session.close();
    		}
    		
    		
    		//知识点9:对象导航
    		@Test
    		public  void objectRelation(){
    			   Session session=sf.openSession();
    			   Transaction tx=session.beginTransaction();
    			   
    			   Order o1=new Order();
    			   o1.setOrderNumber("NO1");
    			   o1.setPrice(23d);
    			   
    			   Order o2=new Order();
    			   o2.setOrderNumber("NO2");
    			   o2.setPrice(23d);
    			   
    			   
    			   Order o3=new Order();
    			   o3.setOrderNumber("NO3");
    			   o3.setPrice(23d);
    			   
    			   
    			   Customer c=new Customer();
    			   c.setName("关羽");
    			   
    			   //order1关联到customer 而customer没有关联到order1 --单向关联
    			   o1.setCustomer(c);
    			   
    			   
    			   //customer关联到order2 order3   而order2 order3 没有关联到customer  单向关联
    			   c.getOrderes().add(o2);
    			   c.getOrderes().add(o3);
    			   
    			   //保存o1
    			   session.save(o1);
    			   //保存c
    			   //session.save(c);
    		
    			   //保存o2
    			   //session.save(o2);
    			   
    			   tx.commit();
    			   session.close();
    		}
    		
    		/*
    		 * 知识点10:保持程序的健壮性
    		 */
    		@Test
    		public  void testDouleRaletion(){
    			   Session session=sf.openSession();
    			   Transaction tx=session.beginTransaction();
    			   
    			   Customer c=new Customer();
    			   c.setName("飞");
    			   
    			   Order o=new Order();
    			   o.setOrderNumber("NO2");
    			   o.setPrice(12d);
    /************************************************************************************************************/			   
    			   //建立订单和客户的双向关联
    			   //建立订单和客户的关联
    			   o.setCustomer(c);
    			   
    			   //建立客户和订单的关联
    			   c.getOrderes().add(o); 
    /************************************************************************************************************/			   
    			   //保存客户
    			   session.save(c);
    			   
    			   //保存订单
    			   session.save(o);
    			   
    			   tx.commit();
    			   session.close();
    		}
    
    /************************************************************************************************************/		
    		
    		//知识点11:订单变更客户
    		//更改订单表id=6的customer_id=3更改为4
    		@Test
    		public  void changeOrderHander(){
    			   Session session=sf.openSession();
    			   Transaction tx=session.beginTransaction();
    			   
    			   //获取id=6号的订单,查询的订单和订单关联的客户放置在sessioln的一级缓存中,同时还产生一份快照
    			   Order o6=(Order)session.get(Order.class, 6);
    			   
    			   //获取id=4客户
    			   Customer c4=(Customer)session.get(Customer.class, 4);
    			/**************************************************************************************/   
    			   //建立关联关系
    			   /*
    			    * 在set标签中配置inverse="true",则多的一端说了算,一的一端说了不算
    			    *     当缓存中的数据发生变化时
    			    *       * 如果多的一端关联的客户发生变化,此时执行update语句
    			    *       * 如果一的一端对应的订单集合中的订单发生变化时,
    			    *         因为一的一端说了不算,所以不会按照订单集合中订单的变化执行update语句
    			    */
    			   
    			   //让6号订单和4号客户关联
    			   o6.setCustomer(c4);  //有update语句
    			   
    			   //在4号客户对应的订单集合中加入6号订单  
    			   c4.getOrderes().add(o6);   //没有update语句,加和不加没有影响,但建议还是加上
    			/**************************************************************************************/   
    			   
    			   tx.commit();
    			   session.close();
    		}	
    		
    		
    		/*
    		 * 知识点12:解除关联关系
             *     解除6号订单和3号客户的关联
    		 */
    		@Test
    		public  void removeRelation(){
    			   Session session=sf.openSession();
    			   Transaction tx=session.beginTransaction();
    			   
    			   //获取id=6号的订单,查询的订单和订单关联的客户放置在sessioln的一级缓存中,同时还产生一份快照
    			   Order o6=(Order)session.get(Order.class, 6);
    			   
    			   //获取id=3客户
    			   Customer c3=(Customer)session.get(Customer.class, 3);
    			   
    			   //解除双方的关联关系
                   o6.setCustomer(null);
                   c3.getOrderes().remove(o6);
    			   
    			   tx.commit();
    			   session.close();
    		}	
    		
    		/*
    		 * 知识点13:级联删除删除1号客户的同时,删除1号客户所关联的订单
    		 */
    		@Test
    		public  void deleteCustomerCaseOrder(){
    			   Session session=sf.openSession();
    			   Transaction tx=session.beginTransaction();
    			   
    			   //获取id=1客户
    			   Customer c1=(Customer)session.get(Customer.class, 1);
    			   
                   session.delete(c1);
    			   
    			   tx.commit();
    			   session.close();
    		}
    		
    		
    		/*
    		 * 知识点14:解除关联关系 ---父子关系
             *         解除6号订单和3号客户的关联,同时删除6号订单
    		 */
    		@Test
    		public  void deleteOrderOrphan(){
    			   Session session=sf.openSession();
    			   Transaction tx=session.beginTransaction();
    			   
    			  
    			   
    			   //获取id=6订单
    			   Order o6=(Order)session.get(Order.class, 6);
    			   
    			   //获取id=3客户
    			   Customer c3=(Customer)session.get(Customer.class, 3);
    			   
    			   //解除关联关系
    			   o6.setCustomer(null);
    			   c3.getOrderes().remove(o6);
                  
    			   
    			   tx.commit();
    			   session.close();
    		}
    	
    }
    


    Customer.hbm.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     <hibernate-mapping>
       <class name="cn.itcast.many2onedouble.Customer" table="customers">
          <id name="id" type="integer">
            <column name="id"/>
            <generator class="increment"/>
          </id>
          <property name="name" type="string">
              <column name="name"/>
          </property>
          
          <!-- 配置set集合 
               set:使用set标签配置客户对应的订单集合
               table:订单集合中的订单对应的表,可以不加
               cascade="save-update":级联保存和更新:当保存customer对象时,同时要保存customer对象所关联的订单集合orderes集合
                        "delete":级联删除
                        
               inverse="true":表示多的一端(Order端)为主控方法(谁是主控方,谁就说算,多的一端说了算)      (全国人民)
                                     一的一端(Customer端)不是主控方法  (国家主席)
               
          -->
          <set name="orderes" table="orders" cascade="delete-orphan" inverse="true">
             <key>
               <!-- 对应的是orders表的外键,可以理解为, orderes集合中的订单对象是通过orders表的外键customer_id查询出来的
                    select * from orders where cutomer_id=客户id  结构是多条记录
               -->
               <column name="customer_id"/>
             </key>
              <!-- 
                one-to-many:表示一对多,class表示集合中存放的对象是Order对象
               -->
              <one-to-many class="cn.itcast.many2onedouble.Order"/>
          </set>
          
       </class>
     </hibernate-mapping>    


    Order.hbm.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     <hibernate-mapping>
       <class name="cn.itcast.many2onedouble.Order" table="orders">
          <id name="id" type="integer">
            <column name="id"/>
            <generator class="increment"/>
          </id>
          <property name="orderNumber" type="string">
              <column name="orderNumber"/>
          </property>
          <property name="price" type="double">
              <column name="price"/>
          </property>
          
          <!--
               customer要获取的是Customer对象,
                 该Customer对象通过orders表的外键customer_id来查询customers表
               select * from customes where id=customer_id
               many-to-one:使用该标签来映射多对一关联:
                    name:映射的持久化类中的属性
                    class:映射的持久化类中的属性的类型
                    
               cascade="save-update":级联保存和更新
                     * 就是将order对象所关联的临时对象Customer变成持久对象(就在session的一级缓存中,就能插入到数据库中)     
          -->
          <many-to-one  name="customer" class="cn.itcast.many2onedouble.Customer" cascade="save-update">
               <!-- 映射的表中的列 -->
               <column name="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="hibernate.connection.username">root</property>
          <property name="hibernate.connection.password">root</property>
          <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
          <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
          
          <!-- 配置数据库的方言,让hibernate知道连接的是哪个数据库-->
          <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
       
          <!-- 配置利用javaBean和映射文件生成数据库中的表
               hibernate.hbm2ddl.auto值
                  * create:执行时,先查找该表是否存在,如存在先删除表,在创建表
                  * none:不能创建表,只能往表中插入数据,如表不存在抛出异常,默认值
                  * update:执行时,
                              情况一:
                                    先查找该表是否存在,如果表存在,直接插入,如果表不存在,先创建表,再插入数据.
                              情况二:
                                    先查找该表是否存在,如果表存在,但表的结构不一样,要修改表的结构
           -->
          <property name="hibernate.hbm2ddl.auto">update</property>
          
          <!-- 显示hibernate生成的sql语句 -->
          <property name="hibernate.show_sql">true</property>
       
          <!-- 显示格式化得sql语句 -->
          <property name="hibernate.format_sql">false</property>
          
       </session-factory>
    </hibernate-configuration>	


     

  • 相关阅读:
    算法15 《啊哈算法》第四章 盒子装扑克-DFS深度优先搜索 递归
    算法14 leetcode28 实现 strStr() kmp
    markdown一些有用笔记
    算法11 leetcode274 有效的字母异位词
    Quantity? Quality!
    算法 10 leetcode344. 反转字符串
    JavaWeb —— JDBC Driver驱动及连接问题
    Python —— 4 习题练习
    Python —— 变量的作用域
    JavaWeb —— 文件上传
  • 原文地址:https://www.cnblogs.com/xj626852095/p/3648004.html
Copyright © 2011-2022 走看看