2.0、Hibernate-级联关系

2.0、Hibernate-级联关系

级联关系 中 最为常见的就是 ->

1、一对多关系 :一个消费者可以购买多个商品 -> 生成多个订单; 消费者是1,订单是多

        那么在数据库中,1 的一方是主表,多的一方是从表,通过主外键关系去维护;

        在Java的面向对象中就是用pojo实体类属性去表示;

2、多对多关系:大学生选课,一个学生可以选择多门课程,一门课程也可以被多个学生选择;

        数据库中是通过两个一对多关系来维护的,学生和课程都是主表,额外增加一张中间表作为从表,两张主表和中间表都是一对多的关系;

        Java 和 数据库 对于这两种关系的体现完全是两种不同的方式,Hibernate 框架的作用就是将这两种方式进行转换和映射;

接下来看看一对多代码演示【环境配置在 1.0、Hibernate-快速入门初体验中介绍过了】:

第一步:数据库中创建两张表 customer 和 orders,如下所示 ->

第二步:在 com.hkl.pojo 文件夹下创建两个 pojo 实体类 Java 文件,customer.java 和 order.java,如下所示->

package com.hkl.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Set;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Customer {
    private Integer id;
    private String name;
//    一个消费者对应多个订单
    private Set<Order> orders;
}
package com.hkl.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order {
    private Integer id;
    private String name;
    //一个订单对应一个消费者
    private Customer customer;
}

第三步:在 com.hkl.pojo 文件夹下创建两个xml配置文件,Customer.hbm.xml 和 Order.hbm.xml,如下所示->

Customer.hbm.xml ->

<?xml version="1.0"?>
<!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.hkl.pojo.Customer" table="customer">
<!--        主键映射,数据库表中的主键字段用 id 配置,而 name = "id" 这个 id 指的是 Customer 实体类中的 id 属性名-->
        <id name="id" type="java.lang.Integer">
<!--            数据库表 id 主键字段配置-->
            <column name="id"></column>
<!--            设置主键自增方式 -> identity-->
            <generator class="identity"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

<!--        orders是实体类Customer中的属性名,该属性是一个Order类的集合,所以对应表 order-->
        <set name="orders" table="orders">
<!--            这里配置一下主外键 cid -->
            <key column="cid"></key>
<!--            消费者和订单的关系是一对多,所以这里是 one-to-many,然后给set类型加一个对象,对象类型是Order-->
            <one-to-many class="com.hkl.pojo.Order"></one-to-many>
        </set>
    </class>

</hibernate-mapping>

Order.hbm.xml -> 

<?xml version="1.0"?>
<!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.hkl.pojo.Order" table="orders">
        <!--        主键映射,数据库表中的主键字段用 id 配置,而 name = "id" 这个 id 指的是 Customer 实体类中的 id 属性名-->
        <id name="id" type="java.lang.Integer">
            <!--            数据库表 id 主键字段配置-->
            <column name="id"></column>
            <!--            设置主键自增方式 -> identity-->
            <generator class="identity"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

<!--        这里订单和消费者是多对一的关系,所以 order 是从表,外键依旧是 cid-->
        <many-to-one name="customer" class="com.hkl.pojo.Customer" column="cid"></many-to-one>
    </class>

</hibernate-mapping>

 说明一下 标签 含义 ->

        set 标签来配置实体类中的集合属性orders;

        name 实体类属性名;

        table 表名;

        key 外键

        one-to-many 与集合泛型的实体类对应;

        many-to-one 配置实体类对应的对象属性;

        name 属性名;

        class 属性对应的类;

        column 外键;

        到这里其实就可以看出来 hibernate 和 mybatis 的区别了,首先 mybatis 是一个半自动的 ORM 框架,而 hibernate 是一个全自动的 ORM 框架;

        hibernate 是将 数据库表 和 pojo实体类 直接映射,而 mybatis 是将 sql结果集 和 pojo实体类 映射起来;

第四步:将这两个映射配置文件 注册 到 hibernate 配置文件中去,代码如下 ->

<!--注册实体关系映射文件-->        
<mapping resource="com/hkl/pojo/Customer.hbm.xml"></mapping>
<mapping resource="com/hkl/pojo/Order.hbm.xml"></mapping>

第五步:用 hibernate API 去调用,在 test 文件夹下创建 Test2.java 文件,如下所示->

import com.hkl.pojo.Customer;
import com.hkl.pojo.Order;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class Test2 {
    public static void main(String[] args) {
//        创建configuration
        Configuration configuration = new Configuration().configure();
//        获取sessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
//        获取Session
        Session session = sessionFactory.openSession();
//        创建Customer
        Customer customer = new Customer();
        customer.setName("小澜");
//        创建 order
        Order order = new Order();
        order.setName("订单1");
//        建立关联关系
        order.setCustomer(customer);
//        保存
        session.save(customer);
        session.save(order);
//        提交事务
        session.beginTransaction().commit();
//        关闭session
        session.close();

    }
}

运行后可以看到数据添加成功->

 

        记录一下这里我遇到的一个问题,一直报错说我的 sql 语句有问题,找了很久才发现数据库的表名是 order,而这个名字是一个sql关键字,所以不能使用,如下所示->

 

多对多代码演示->

第一步:创建数据库表 account 和 course 和 account_course 三张表,如下所示->

 第二步:在 com.hkl.pojo 文件夹下创建对应的 pojo 实体类文件,Account.java 和 Course.java 文件,如下所示->

Account.java

package com.hkl.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Set;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Account {
    private Integer id;
    private String name;
    private Set<Course> courses;
}

 Course.java

package com.hkl.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Set;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Course {
    private Integer id;
    private String name;
    private Set<Account> accounts;
}

 

第三步:在 com.hkl.pojo文件夹下创建两个对应的映射文件,Account.hbm.xml 和 Course.hbm.xml ,如下所示->

Account.hbm.xml

<?xml version="1.0"?>
<!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.hkl.pojo.Account" table="t_account">
        <!--        主键映射,数据库表中的主键字段用 id 配置,而 name = "id" 这个 id 指的是 Course 实体类中的 id 属性名-->
        <id name="id" type="java.lang.Integer">
            <!--            数据库表 id 主键字段配置-->
            <column name="id"></column>
            <!--            设置主键自增方式 -> identity-->
            <generator class="identity"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

        <!--courses是实体类Course中的属性名,该属性是一个 Course 类的集合,所以对应表 account_course-->
        <set name="courses" table="account_course">
            <!--这里配置一下主外键 cid -->
            <key column="aid"></key>
            <!--学生和选课的关系是多对多,所以这里是 many-to-many,然后给set类型加一个对象,对象类型是Account , column是account在这个中间表中的外键aid-->
            <many-to-many class="com.hkl.pojo.Course" column="cid"></many-to-many>
        </set>
    </class>

</hibernate-mapping>

Course.hbm.xml

<?xml version="1.0"?>
<!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.hkl.pojo.Course" table="t_course">
        <!--        主键映射,数据库表中的主键字段用 id 配置,而 name = "id" 这个 id 指的是 Account 实体类中的 id 属性名-->
        <id name="id" type="java.lang.Integer">
            <!--            数据库表 id 主键字段配置-->
            <column name="id"></column>
            <!--            设置主键自增方式 -> identity-->
            <generator class="identity"></generator>
        </id>
        <property name="name" type="java.lang.String">
            <column name="name"></column>
        </property>

        <!--courses是实体类Course中的属性名,该属性是一个 Course 类的集合,所以对应表 account_course-->
        <set name="accounts" table="account_course">
            <!--这里配置一下主外键 aid -->
            <key column="cid"></key>
            <!--学生和选课的关系是多对多,所以这里是 many-to-many,然后给set类型加一个对象,对象类型是Course , column是course在这个中间表中的外键cid-->
            <many-to-many class="com.hkl.pojo.Account" column="aid"></many-to-many>
        </set>
    </class>

</hibernate-mapping>

 

第四步:将映射文件注册到 hibernate.cfg.xml 配置文件中,如下所示->

<mapping resource="com/hkl/pojo/Account.hbm.xml"></mapping>
<mapping resource="com/hkl/pojo/Course.hbm.xml"></mapping>

 

第五步:在test文件夹下创建 test3.java 文件,调用 Hibernate API 去测试一下,如下所示->

import com.hkl.pojo.Account;
import com.hkl.pojo.Course;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import java.util.HashSet;
import java.util.Set;

public class Test3 {
    public static void main(String[] args) {
        //        创建configuration
        Configuration configuration = new Configuration().configure();
//        获取sessionFactory
        SessionFactory sessionFactory = configuration.buildSessionFactory();
//        获取Session
        Session session = sessionFactory.openSession();
        //创建course
        Course course = new Course();
        course.setName("Java编程与设计");
        //创建account
        Account account = new Account();
        account.setName("小澜");
        //将封装好的course放到set集合中去
        Set<Course> courses = new HashSet<Course>();
        courses.add(course);
        //将封装好的set集合与account建立联系
        account.setCourses(courses);
        //提交事务
        session.save(course);
        session.save(account);
        //提交事务
        session.beginTransaction().commit();
        //关闭session
        session.close();
    }
}

可以看到我这里运行了三次都成功的添加了数据~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值