Hibernate的单向一对多


Hibernate关系映射-单向一对多

单向一对多会多执行update语句,效率不如多对一。

一、学生表和年级表

                                                          Student表

idnameagegrade_id
1 张三 20 1
2 李四 22 1
3 王五 22 2

                                                           Grade表

idname
1 基础
2 中级

二、Student类和Grade类

  1. 先创建一个Student类

public class Student implements Serializable {
    private Integer id;
    private String name;
    private Integer age;
//    private Grade grade;
?
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
//                ", grade=" + grade +
                '}';
    }
?
    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 Integer getAge() {
        return age;
    }
?
    public void setAge(Integer age) {
        this.age = age;
    }
?
//    public Grade getGrade() {
//        return grade;
//    }
//
//    public void setGrade(Grade grade) {
//        this.grade = grade;
//    }
}
  1. 创建一个Grade类,用的是set集合。

public class Grade implements Serializable {
    private Integer id;
    private String name;
    private Set students = new HashSet<>();
?
    @Override
    public String toString() {
        return "Grade{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", students=" + students +
                '}';
    }
?
    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 getStudents() {
        return students;
    }
?
    public void setStudents(Set students) {
        this.students = students;
    }
}
  1. 创建Student.hbm.xml

<?xml version="1.0" encoding="UTF-8" ?>
DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
?
<hibernate-mapping package="com.uestc">
    <class name="Student">
        <id name="id">
            <generator class="native"/>
        id>
        <property name="name"/>
        <property name="age"/>
        


    class>
hibernate-mapping>
  1. 创建Grade.hbm.xml

<?xml version="1.0" encoding="UTF-8" ?>
DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
?
<hibernate-mapping package="com.uestc">
    <class name="Grade">
        <id name="id">
            <generator class="native"/>
        id>
        <property name="name"/>
        
        <set name="students">
            <key foreign-key="fk_grade" column="grade_id" not-null="true">key>
            <one-to-many class="Student"/>
        set>
    class>
hibernate-mapping>
  1. 在src和test下面的resources下面创建hibernate.cfg.xml

<?xml version="1.0" encoding="utf-8" ?>
DOCTYPE hibernate-configuration PUBLIC
      "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
      "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
?
<hibernate-configuration>
   <session-factory>
      
      <property name="connection.driver_class">com.mysql.jdbc.Driverproperty>
      <property name="connection.url">jdbc:mysql:///hibernateproperty>
      <property name="connection.username">rootproperty>
      <property name="connection.password">rootproperty>
      
      <property name="dialect">org.hibernate.dialect.MySQL8Dialectproperty>
      
      <property name="hbm2ddl.auto">updateproperty>  
      
      <property name="show_sql">trueproperty>
      
      <property name="format_sql">trueproperty>
      
      <mapping resource="com/uestc/Grade.hbm.xml"/>
      <mapping resource="com/uestc/Student.hbm.xml"/>
   session-factory>
hibernate-configuration>
  1. 测试类,测试单向一对多和是否获取到Grade下面的基础和名字是否对应。

/**
 * 单向一对多
 */
@Test
public void testSingleOneToMany() {
    Session session = null;
    Transaction tx = null;
    try {
        session = HibernateUtil.getSession();
        tx = session.beginTransaction();
?
        //创建实例对象
?
        Student student = new Student();
        student.setName("张三");
        student.setAge(18);
?
        Student student2 = new Student();
        student2.setName("李四");
        student2.setAge(18);
?
?
        Student student3 = new Student();
        student3.setName("王五");
        student3.setAge(18);
?
        Grade grade1 = new Grade();
        grade1.setName("基础");
        grade1.getStudents().add(student);
        grade1.getStudents().add(student2);
?
        Grade grade2 = new Grade();
        grade2.setName("中级");
        grade2.getStudents().add(student3);
?
        //存储的顺序是根据外键约束而定的,如果外键不可以为空,必须先存储外键的一端
        //单向一对多会多执行update语句,效率不如多对一
        session.save(grade1);
        session.save(grade2);
?
        session.save(student);
        session.save(student2);
        session.save(student3);
?
?
        tx.commit();
?
    }catch (Exception e){
        e.printStackTrace();
        tx.rollback();
    }finally {
        HibernateUtil.closeSession();
    }
}
?
/**
 * 获取
 * 查询不用开启事务,会降低性能
 */
@Test
public void testSingleGetOneToMany() {
    Session session = null;
    Transaction tx = null;
    try {
        session = HibernateUtil.getSession();
        tx = session.beginTransaction();
?
        Grade grade = session.get(Grade.class,1);
        System.out.println("grade:" +grade.getName());
        for(Student stu : grade.getStudents()){
            System.out.println("stuName:" +stu.getName());
        }
?
?
?
        tx.commit();
?
    }catch (Exception e){
        e.printStackTrace();
        tx.rollback();
    }finally {
        HibernateUtil.closeSession();
    }
  1. 数据库最后得到的结果。