Hibernate中的映射关系(一对多)

在数据库中表和表之间的关系有几种,下面就详细说一下在Hibernate中怎样映射一对多的关系

Hibernate映射一对多的关系,其实就是持久类之间的映射,那如何把持久类关联起来呢??那就用到.hbm.xml文件的<many-to-one>标签了

具体做法如下:

  新建一个customer类:
  

package com.jeremy.hibernate.app.example;

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表

package com.jeremy.hibernate.app.example;

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;
    }

}

那这个两个类怎样关联起来呢??
那就需要通过那就用到.hbm.xml文件的<many-to-one>标签了
在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.atguigu.hibernate.entities.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>

        <!--
            映射多对一的关联关系。 使用 many-to-one 来映射多对一的关联关系
            name: 多这一端关联的一那一端的属性的名字
            class: 一那一端的属性对应的类名
            column: 一那一端在多的一端对应的数据表中的外键的名字
        -->
        <many-to-one name="customer" class="Customer" column="CUSTOMER_ID"></many-to-one>

    </class>
</hibernate-mapping>

customer.hbm.xml文件像普通的那样配置即可
example:

<?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.atguigu.hibernate.entities.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>

这样就可以把表的一对多关系建立起来了,

建立起来后最重要的是访问,也就是我们怎么在Hibernate中进行多表增删改操作呢??这又是一个关键的问题

  增:

    

@Test
    public void testMany2OneSave(){
        Customer customer = new Customer();
        customer.setCustomerName("BB");

        Order order1 = new Order();
        order1.setOrderName("ORDER-3");

        Order order2 = new Order();
        order2.setOrderName("ORDER-4");

        //设定关联关系,比平常的要多一个设定关联关系的语句,因为外键必须得根据外键的,多以在插入的order表时要么新增一个customer要      么就查询一个customer,这个步骤尤为重要
        order1.setCustomer(customer);
        order2.setCustomer(customer);

        //执行  save 操作: 先插入 Customer, 再插入 Order, 3 条 INSERT
        //先插入 1 的一端, 再插入 n 的一端, 只有 INSERT 语句.(推荐使用注释的)
//        session.save(customer);
//
//        session.save(order1);
//        session.save(order2);

        //先插入 Order, 再插入 Customer. 3 条 INSERT, 2 条 UPDATE
        //先插入 n 的一端, 再插入 1 的一端, 会多出 UPDATE 语句!
        //因为在插入多的一端时, 无法确定 1 的一端的外键值. 所以只能等 1 的一端插入后, 再额外发送 UPDATE 语句.
        //所以推荐先插入 1 的一端, 后插入 n 的一端(也就是注释的那部分)
        session.save(order1);
        session.save(order2);

        session.save(customer);
    }

  删delete:

@Test
    public void testDelete(){
        //在不设定级联关系的情况下, 且 1 这一端的对象有 n 的对象在引用, 不能直接删除 1 这一端的对象
        Customer customer = (Customer) session.get(Customer.class, 1);
        session.delete(customer);
    }

  改update:

  

@Test
    public void testUpdate(){
        Order order = (Order) session.get(Order.class, 1);
        order.getCustomer().setCustomerName("AAA");
    }

  查select:

   

  @Test
    public void testSelect(){
        //1. 若查询多的一端的一个对象, 则默认情况下, 只查询了多的一端的对象. 而没有查询关联的1 的那一端的对象!
        Order order = (Order) session.get(Order.class, 1);
        System.out.println(order.getOrderName()); 

        System.out.println(order.getCustomer().getClass().getName());

        session.close();

        //2. 在需要使用到关联的对象时, 才发送对应的 SQL 语句.
        Customer customer = order.getCustomer();
        System.out.println(customer.getCustomerName()); 

        //3. 在查询 Customer 对象时, 由多的一端导航到 1 的一端时,
        //若此时 session 已被关闭, 则默认情况下
        //会发生 LazyInitializationException 异常

        //4. 获取 Order 对象时, 默认情况下, 其关联的 Customer 对象是一个代理对象!

    }

因为持久化对象的set()方法时可以触发Hibernate发送update语句,get()方法可以触发Hibernate发送select语句,我们可以通过外键表的get()和set()的方法对外键表进行更改和查询

 

  

时间: 2024-12-24 09:05:25

Hibernate中的映射关系(一对多)的相关文章

hibernate中的继承关系

  1.       hibernate中的继承关系   代码:   <1>.POJO类:(Person类)   package qau.edu; import java.util.Date; public class Person { //  成员变量: private int id ; private String name ; private Date date ; //  相应的getter和setter方法: public int getId() { return id; } pub

Hibernate学习之映射关系

一.Hibernate多对一关联映射:就是在“多”的一端加外键,指向“一”的一端. 比如多个学生对应一个班级,多个用户对应一个级别等等,都是多对一关系. 1.“多”端实体加入引用“一”端实体的变量及getter,setter方法. 比如说多个学生对应一个班级,在学生实体类加入:private Grade grade; 2.“多”端配置文件,student.hbm.xml里的标签设置:<many-to-one name="grade" column="gradeId&qu

hibernate笔记--继承映射关系的三种实现方式

单表继承映射(一张表): 假设我们现在有三个类,关系如下: Person类有两个子类Student和Teacher,并且子类都具有自己独有的属性.这种实体关系在hibernate中可以使用单表的继承映射来建表,最后生成的表是这样的: 可以看到我们只需要建立一张表就可以维护这个关系,这种方式就是单表继承映射,下面介绍配置方法: 新建实体类Person ,Student,和Teacher : public class Person { private int id; private String n

hibernate中的映射文件xxx.hbm.xml详解总结

转自 http://blog.csdn.net/a9529lty/article/details/6454924 一.hibernate映射文件的作用: Hibernate映射文件是Hibernate与数据库进行持久化的桥梁   二,Hibernate映射文件主要内容:     (1).映射内容的定义: Hibernate映射文件由<hibernate-mapping package="JavaBean所在包的全路径">节点定义映射内容并指定所对应的JavaBean的位置(

关于hibernate中多对多关系

关于多对多关系 数据库:在使用多对多的关系时,我们可以使用复合主键.也可以不使用,直接引入外键同样可以实现. 在数据库中使用多对多关系时,需要一个中间表. 多对多关系中的数据库结构如下: 表:Orders 字段:orderid(主键)..... 表:Users 字段:usersid(主键),.... 中间表: cy_order_user 字段:cy_order_user主键id 外键:cy_orderid(引入Orders表) 外键:cy_usersid(引入Users表) 注意:中间表的外键是

Hibernate中多对多关系转换

问题来源 在运用SSH架构开发Web应用时,总会遇到表之间一对多.多对一.多对多等等的关系,而对于多对多的关系,在操作和性能方面都不太理想,所以多对多的映射使用较少,实际使用中最好转换成一对多的对象模型:hibernate会为我们创建中间关联表,转换成两个一对多. 问题解决 在此用开发OA项目时角色表和权限之间的多对多关系提供解决问题的建议 例子:角色与权限 (1)先看需求 (2)分析 第一,角色与权限:多对多 一个角色可以有多个权限,一个权限可以被多个角色使用 第二,在角色的增删改查中涉及到了

Hibernate多对多映射关系(5)

单向 n-n n-n 的关联必须使用连接表 与 1-n 映射类似,必须为 set 集合元素添加 key 子元素,指定 CATEGORIES_ITEMS 表中参照 CATEGORIES 表的外键为 CATEGORIY_ID. 与 1-n 关联映射不同的是,建立 n-n 关联时, 集合中的元素使用 many-to-many. many-to-many 子元素的 class 属性指定 items 集合中存放的是 Item 对象, column 属性指定 CATEGORIES_ITEMS 表中参照 IT

hibernate中继承映射保存

1 简单继承映射,在子类上进行映射配置,可以将父类属性直接配置在子类映射文件中. 简单例子如下:teacher类继承自Person类. public class Person { private int id; private String pname; public Person() { // TODO Auto-generated constructor stub } public int getId() { return id; } public void setId(int id) {

兔八哥笔记15(1):Hibernate中的父子关系

众所周知,数据科学是这几年才火起来的概念,而应运而生的数据科学家(data scientist)明显缺乏清晰的录取标准和工作内容.此次课程以<星际争霸II>回放文件分析为例,集中在IBM Cloud相关数据分析服务的应用.面对星际游戏爱好者希望提升技能的要求,我们使用IBM Data Science Experience中的jJupyter Notebooks来实现数据的可视化以及对数据进行深度分析,并最终存储到IBM Cloudant中.这是个介绍+动手实践的教程,参会者不仅将和讲师一起在线