hibernate一对多,多对多映射

1.什么是关联?

关联指的是类之间的引用关系。如果类A与类B关联,那么被引用的类B将被定义为类A的属性。例如:

 

    public class A{
        private B b = new B;
        public A(){}
      }

1.2 关联的分类:


关联可以分为一对一、一对多/多对一、多对多关联  关联是有方向的

#关键点都在数据库中的外键上面,请好好理解下面这二句SQL和一对多及多对一的关系
#select * from Orders where cid=?   //这条SQL返回客户对应的0-n个订单
#select * from Customers where customerId=?  //这条SQL返回订单对应的1个客户
#通过这二条SQL不难看出,外键在这里有二个用途:查找客户的订单,查找订单对应的客户

2.那么如何建立一个一对多的关联呢


因为hibernate是通过实体类操作数据库的,这里就贴实体类的代码

订单类:(记得定义get and set)


public class Order {
 
    private int order_id;
    private String order_no;
 
    //变量属性一定要用接口接收
    //描述一个订单对应多个订单项
    private Set<OrderItem> orderitems = new HashSet<>();
    private Integer initorderitems = 0;//0懒加载 1强制加载
}

订单项类


public class OrderItem {
    private int order_item_id;
    private int product_id;
    private int quantity;
    private int oid;
//多个订单项对应一个订单
    private Order order;

}

然后这里普通的映射就不贴代码啦,请去看以前的博客

因为订单和订单项是一对多的关系

        <!--cascade:级联属性配置 建议不配置del可能会造成迭代删除-->
		<!--inverse:关联关系交给别人维护么?-->
		<set name="orderitems" inverse="true" cascade="save-update">
 
			<!--对应外键-->
			<key column="oid"></key>
			<one-to-many class="com.zking.three.OrderItem"></one-to-many>
		</set>
		

订单项是多对一 

<many-to-one insert="false" update="false" name="order" class="com.zking.three.Order" column="oid"></many-to-one>

在这里可能会报一个错Repeated column in mapping for entity: com.zking.three.OrderItem column: oid
解决方法 加上insert="false" update="false"  或者加在oid属性中或者在实体类中删除哦id属性都可一解决
 

 3.1 lazy:默认值为true,true延迟加载,false立即加载(一般设置为true,不使用立即加载,因为影响查询性能)查询的时候如果报错有很大的可能是因为懒加载的原因

Lazy=true介绍    查单个时存在问题
    Lazy=false介绍    查所有时存在问题

所以使用Hibernate.initialize()来强制加载某个属性来解决
 

   public Order get(Order order){
        Session session = SessionFactoryUtils.openSession();
        Transaction transaction = session.beginTransaction();
        Order o=session.get(order.getClass(),order.getOrder_id());
        if(o!=null&&order.getInitorderitems().equals(new Integer(1))){
            Hibernate.initialize(o.getOrderitems());
        }
        transaction.commit();
        session.close();
        return o;
    }

  3.2 outter-join:默认值为false,true使用左外联接查询关联的(但一般不用,因为当我们把该属性设置为true时,所有的查询语句  都会默认左外联,那样性能不高)
  3.3 inverse:默认值为false,true表示将对方设置为主控方(一对多双向关联中一般将多方设置为主控方,这样可以减少SQL语句的数量,减少多余的操作)
  3.4 cascade:用来控制如何操作关联的持久化对象的
    3.4.1 none:保存,更新或删除当前对象时,忽略其它关联的对象
    3.4.2 save-update:保存、更新时级联保存所有的临时对象,并且级联更新关联的游离对象
    3.4.3 delete:通过session的delete方法删除当前对象,级联删除关联的对象
 

4.多对多

举个例子一本书可以对应多个类别,一个类别也可以对应多本书这就是多对多

<!--name:指的是当前映射实体的属性-->
		<!--table:对应的是中间表-->
		<!--关联关系是否交给对方维护 只要有一方维护即可-->
		<!--inverse="true" cascade="save-update"只要一方维护就好-->
		<set name="categorys" table="t_hibernate_book_category" >
			<!--指的是中间表字段(与当前映射实体对应的表的主键相关联的id)-->
			<key column="bid"></key>
			<!-- class:多方的全类名
            cloumn:与多方主键相关联的字段
            -->
			<many-to-many class="com.zking.four.Category" column="cid"></many-to-many>
		</set>
	</class>
     <!--name:指的是当前映射实体的属性-->
      <!--table:对应的是中间表-->
      <!--关联关系是否交给对方维护-->
<set name="books" table="t_hibernate_book_category" inverse="true" cascade="save-update">
   <!--指的是中间表字段(与当前映射实体对应的表的主键相关联的id)-->
   <key column="cid"></key>
   <!-- class:多方的全类名
   cloumn:与多方主键相关联的字段
   -->
   <many-to-many class="com.zking.four.Book" column="bid"></many-to-many>
   </set>

 

4.3. 多对多关系注意事项
  4.3.1 一定要定义一个主控方
  4.3.2 多对多删除
    4.3.2.1 主控方直接删除
    4.3.2.2 被控方先通过主控方解除多对多关系,再删除被控方
    4.3.2.3 禁用级联删除
  4.3.3 关联关系编辑,不需要直接操作桥接表,hibernate的主控方会自动维护
 

 

其实用的最多的还是一对多的关系,多对多可以看成两个一对多

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值