hibernate(3)关联关系映射

本文深入解析了一对多、多对多及一对一的关联关系映射原理,通过具体实体类和配置文件示例,阐述了Hibernate中关系型数据库与对象之间的映射机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

关联关系映射分为

    1. 一对多关系映射

    2. 多对多关系映射

    3. 一对一关系映射

hibernate中关联关系映射有分单向和双向,单向映射则为一方来维护关系,双向映射则为一起维护关系(简单来说就是由老婆保管财产或者由双方一起保管财产的区别)下方例子均为双向,单向只需要把一方的映射删除就OK。

 

一、一对多关系映射

实体类

public class Customer {

 

private Integer cid;

private String cname;

 

//一对多:一个客户(当前客户) 拥有 【多个订单】

// * 需要容器存放多个值,一般建议Set (不重复、无序)

// * 参考集合:List、Map、Array等

// ** 建议实例化--使用方便

private Set<Order> orderSet = new HashSet<Order>();

public class Order {

private Integer xid;

private String price;

 

//多对一:多个订单属于【一个客户】

private Customer customer;

 

 

配置文件

Customer.hbm.xml

<class name="com.itheima.b_onetomany.Customer" table="t_customer">

<id name="cid">

<generator class="native"></generator>

</id>

<property name="cname"></property>

 

<!-- 一对多:一个客户(当前客户) 拥有 【多个订单】

1 确定容器  set <set>

2 name确定对象属性名

3 确定从表外键的名称

4 确定关系,及另一个对象的类型

注意:

hibernate中可以只进行单向配置

每一个配置项都可以完整的描述彼此关系。

一般情况采用双向配置,双方都可以完成描述表与表之间关系。

 -->

<!-- 一对多:一个客户(当前客户) 拥有 【多个订单】 -->

<set name="orderSet" cascade="delete-orphan">

<key column="customer_id"></key>

<one-to-many class="com.itheima.b_onetomany.Order"/>

</set>

</class>

 Order.hbm.xml

<class name="com.itheima.b_onetomany.Order" table="t_order">

<id name="xid">

<generator class="native"></generator>

</id>

<property name="price"></property>

 

<!-- 多对一:多个订单属于【一个客户】

* name 确定属性名称

* class 确定自定义类型

* column 确定从表的外键名称

-->

<many-to-one name="customer" class="com.itheima.b_onetomany.Customer" column="customer_id"></many-to-one>

 

</class>

 

一对多操作

     保存客户

@Test

public void demo01(){

// 1 创建客户,并保存客户--成功

Session session = factory.openSession();

session.beginTransaction();

 

Customer customer = new Customer();

customer.setCname("田志成");

 

session.save(customer);

 

session.getTransaction().commit();

session.close();

}

 

    保存订单

@Test

public void demo02(){

// 2 创建订单,保存订单--成功,外键为null

Session session = factory.openSession();

session.beginTransaction();

 

Order order = new Order();

order.setPrice("998");

 

session.save(order);

 

session.getTransaction().commit();

session.close();

}

 

客户关联订单,只保存客户

@Test

public void demo03(){

// 3 创建客户和订单,客户关联订单,保存客户?

Session session = factory.openSession();

session.beginTransaction();

 

//1 客户和订单

Customer customer = new Customer();

customer.setCname("成成");

 

Order order = new Order();

order.setPrice("998");

 

//2 客户关联订单

customer.getOrderSet().add(order);

 

//3 保存客户

session.save(customer);

 

session.getTransaction().commit();

session.close();

}

 

 

 

二、多对多关系映射

实体类

//Student实体类

public class Student {

  private Integer sid;

  private String sname;

  //用set集合来保存选的多个课程

  private Set<Course> courseSet = new HashSet<Course>();

 

set、get.....  

//Course实体类

public class Course {

  private int cid;

  private String cname;

  private Set<Student> studentSet = new HashSet<Student>();

...  

 

 

配置文件

Student.hbm.xml

<class name="domain.Student" table="student">

        <id name="sid" column="sid">

            <!-- 主键生成策略 -->

            <generator class="increment"></generator>

        </id>

        <!-- 一些常规属性 -->

        <property name="sname"></property>

 

<!-- 关键的地方就在这里了。一定要搞清楚两个column分别指的是什么意思 脑袋中要有哪个数据库关系图-->

 

<!--要查询到所有的course,就需要通过连接表,所以申明连接表的名称-->

    <set name="courseSet" table="student_course">

    <!-- 本实体类在连接表中的外键名称,过程我们上面分析的很清楚了,为什么需要这个呢?让hibernate知道连接表中有一个外键名为s_id的指向本实体类 -->

        <key column="s_id"></key>

        <!-- 多对多映射关系,映射类和其映射类在连接表中的外键名称 这个的意思跟上面的一样,也是声明让hibernate知道,这样一来,hibernate就知道如何查询了-->

        <many-to-many class="domain.Course" column="c_id"></many-to-many>

    </set>

    </class>

 Course.hbm.xml

<class name="domain.Course" table="course">

        <id name="cid" column="cid">

            <!-- 主键生成策略 -->

            <generator class="increment"></generator>

        </id>

        <!-- 一些常规属性 -->

        <property name="cname"></property>

        <set name="studentSet" table="student_course">

            <!-- 本类在连接表中外键的名称, -->

            <key column="c_id"></key>

<!--多对多映射关系,映射类和其映射类在连接表中的外键名称-->

            <many-to-many class="domain.Student" column="s_id"></many-to-many>

        </set>

    </class>

测试类

@Test

public void demo01(){

// 1 创建客户,并保存客户--成功

Session session = factory.openSession();

session.beginTransaction();

 

Course course = new Course();

course.setCname("化学");

 

Student student = new Student();

student.setSname("qqq");

 

course.getStudentSet().add(student);

//student.getCourseSet().add(course);

 

session.save(course);

session.save(student);

 

session.getTransaction().commit();

session.close();

}

 

 

三、一对一关系映射

实体类

//Person实体类

public class Person {

    private int id;

    private String name;

    private IdCard idCard;//体现一对一的关系。保存映射类的实例对象。

//。。。

//Course实体类

public class IdCard {

    private int id;

    private String cardNo;

    private Person person;//多了这个

//...

}

 

 

配置文件

Person.hbm.xml

<class name="domain1.Person" table="person">

        <id name="id" column="id">

            <!-- 重点在这里。主键生成策略 因为主键跟外键是同一个,所以直接在这里申明该主键就是外键,并且指向了idCard这个类 -->

            <generator class="foreign">

            <param name="property">idCard</param>

            </generator>        

        </id>

        <!-- 一些常规属性 -->

        <property name="name"></property>

        <!--由于在申明主键的时候已经将关系写清楚了,所以在这里没有column这个属性。按平常的习惯,我们会在这里写上column="数据库中外键字段属性名称。"-->

<!--constrained属性:就是表明我们的主键当外键使用了。 这个属性两个作用,一是通知这种对应关系在上面已经写过了,所以这里才不需要写column,二是表明这种关系是什么,也就是主键当外键。

      其实还有一个级联关系的作用,这里不做多说明,具体会在这章之后一起讲解,不然会让人感觉很混乱。-->

        <one-to-one name="idCard" constrained="true"></one-to-one>

 

    </class>   

 IdCard.hbm.xml

    <class name="domain1.IdCard" table="idcard">

        <id name="id" column="id">

            <!-- 主键生成策略 -->

            <generator class="native">

            </generator>        

        </id>

        <!-- 一些常规属性 -->

        <property name="cardNo"></property>

        <!-- 这里只需要写这些就足够了,因为one-to-one默认使用的就是用主键跟关联类的主键进行比较,本来就是主键关系,通过主键跟主键比较,就能达到目的,所以这个中没有column这个属性,

 

     但是可以配置一些别的属性,不需要写column, -->

        <one-to-one name="person"></one-to-one>

    </class>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值