Hibernate关联关系映射(单向一对多、单向多对一、双向一对多)

注意:我使用的是Hibernate5.2版本。

一、关联关系映射

单向关联:一对一、一对多、多对一。
使用连接表单向:一对一、一对多、多对一、多对多。
双向关联:一对一、一对多。
使用连接表的双向关联:一对一、一对多、多对多。

二、自动生成表

这里介绍一下Schema自动生成(Automatic schema generation)
可以从你的映射文件使用一个Hibernate工具生成DDL。 生成的schema包含有对实体和集合类表的完整性引用约束(主键和外键)。涉及到的标示符生成器所需的表和sequence也会同时生成。

在使用这个工具的时候,你必须 通过hibernate.dialet属性指定一个SQL方言(Dialet),因为DDL是与供应商高度相关的。

首先,要定制你的映射文件,来改善生成的schema。

注意:以前的版本生成方法不同请查看具体API

前提配置好classname.hbm.xml和hibernate.xml

public void testCreadDB(){
        ServiceRegistry serviceRegistry=new StandardServiceRegistryBuilder().configure().build();
        Metadata metadataImplementor=new MetadataSources(serviceRegistry).buildMetadata();
     SchemaExport schemaExport=new SchemaExport();
     schemaExport.create(EnumSet.of(TargetType.DATABASE), metadataImplementor);
    }

三、单向一对多

Grade.java

package com.pojo;

import java.util.HashSet;
import java.util.Set;

import javassist.expr.NewArray;

public class Grade {
    private int id;
    private String name;
    private Set<Student> students=new HashSet<Student>(0);
    public Set<Student> getStudents() {
        return students;
    }
    public void setStudents(Set<Student> students) {
        this.students = students;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

}

Student.java

package com.pojo;
public class Student {
    private int id;
    private String name;
    private int age;
    //private Grade grade;

    // private int gradeId;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }


}

Grade.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 package="com.pojo">

    <class name="Grade" >
    <id name="id">
    <generator class="native" />
    </id>
    <property name="name" />
    <!-- set是grade中集合的属性    name属性名称-->
    <set name="students" table="student">
    <!-- key表示外键  colume外键列名  not-null外键不能空-->
    <key column="grade_id" not-null="true"></key>
    <!-- 一对多 -->
    <one-to-many  class="com.pojo.Student"/>
    </set>
    </class>

    </hibernate-mapping>

Student.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 package="com.pojo">

    <class name="Student" >
    <id name="id">
    <generator class="native" />
    </id>
    <property name="name" />
    <property name="age" />

    </class>

    </hibernate-mapping>

SessionFactoryUtil.java 单例创建sessionfactory

package com.util;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class SessionFactoryUtil {
    private static SessionFactory  sessionfactory;
    private SessionFactoryUtil(){

    }
    public static SessionFactory getSessionFactory(){
        if(sessionfactory==null)
        {
            Configuration configuration=new Configuration();
            configuration.configure();

            sessionfactory=configuration.buildSessionFactory();
        }
        return sessionfactory;
    }

}

测试代码:

package com.test;

import java.util.Iterator;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.pojo.Grade;
import com.pojo.Student;
import com.util.SessionFactoryUtil;
public class StudentDemo {
    public static void main(String[] args) {
        StudentDemo studentDemo = new StudentDemo();
        studentDemo.oneTomany();
    }

    public void oneTomany() {
        // 单向一对多
        SessionFactory sessionFactory = SessionFactoryUtil.getSessionFactory();// 单例创建sessionfactory
        Session session = sessionFactory.openSession();// 创建session对象
        Transaction transaction = session.beginTransaction();// 开始事务
        // 添加数据
        Grade grade = new Grade();
        grade.setName("基础部");

        Student student = new Student();
        student.setName("沈雪冰");
        student.setAge(23);

        Student student2 = new Student();
        student2.setName("李四");
        student2.setAge(19);
        // 关联,建立单向关系
        grade.getStudents().add(student);
        grade.getStudents().add(student2);
        // 保存顺序根据外键来决定的,如果外键不能为null 那么先保存一的一端,否则随意保存
        session.save(grade);

        session.save(student);
        session.save(student2);

        transaction.commit(); // 提交事务

        // 取数据
        Grade gradetemp = session.get(Grade.class, 1);// 取出id为1的grade对象
        System.out.println("gradeName=" + gradetemp.getName());
        System.out.println("grade所对应的一对多数据为:");

        Iterator<Student> iterator = gradetemp.getStudents().iterator(); // 通过gradetemp获取student集合
        while (iterator.hasNext()) {
            // 取出student集合信息
            Student temp = iterator.next(); // 取到一个数据
            System.out.println("name=" + temp.getName() + ",age=" + temp.getAge());
        }

        session.close(); // 关闭session
    }

}

运行结果:

gradeName=基础部
grade所对应的一对多数据为:
name=沈雪冰,age=23
name=李四,age=19

四、单向多对一

Grade.java

package com.pojo;

public class Grade {
    private int id;
    private String name;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

}

Studnet.java

package com.pojo;

public class Student {
    private int id;
    private String name;
    private int age;
    private Grade grade;
  // private int gradeId;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Grade getGrade() {
        return grade;
    }
    public void setGrade(Grade grade) {
        this.grade = grade;
    }
}

Grade.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 package="com.pojo">

    <class name="Grade" >
    <id name="id">
    <generator class="native" />
    </id>
    <property name="name" />

    </class>

    </hibernate-mapping>

Student.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 package="com.pojo">

    <class name="Student" >
    <id name="id">
    <generator class="native" />
    </id>
    <property name="name" />
    <property name="age" />
    <!--
        many-to-one属性:
        * name:关联映射的(一那方的)属性名字。
        * column:和一那方关联的表的外键。数据库字段
        * class:name属性对应持久化类的全路径。
        * not-null:是否允许为空。
      -->
    <many-to-one name="grade" class="Grade" 
    column="grade_id"  not-null="true" foreign-key="FKgrade"
    ></many-to-one>
    </class>





    </hibernate-mapping>

测试代码:

package com.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.pojo.Grade;
import com.pojo.Student;
import com.util.SessionFactoryUtil;

public class StudentDemo {
    public static void main(String[] args) {
        StudentDemo studentDemo=new StudentDemo();
        studentDemo.manytoOne();
    }
    public void manytoOne(){
        //单向多对一
                SessionFactory sessionFactory=SessionFactoryUtil.getSessionFactory();//单例创建
                Session session=sessionFactory.openSession();//创建一个session
                Transaction transaction=session.beginTransaction();//开始事务
                //添加数据
                Grade grade=new Grade();
                grade.setName("基础部");


                Student student=new Student();
                student.setName("沈雪冰");
                student.setAge(23);
                student.setGrade(grade);
                Student student2=new Student();
                student2.setName("李四");
                student2.setAge(19);
                student2.setGrade(grade);

                Student student3=new Student();
                student3.setName("王麻子");
                student3.setAge(30);
                student3.setGrade(grade);
                //保存数据
                session.save(grade);
                session.save(student);
                session.save(student2);
                session.save(student3);

                transaction.commit();//提交数据
                session.close();//关闭数据


                //取数据
                Grade temp=new Grade();             
                Grade temp2=new Grade();
                Grade temp3=new Grade();
                System.out.println("多对一:");
                System.out.println("每位学生所对应数据:");
                temp=student.getGrade();//取出student对应的grade
                System.out.println("name="+student.getName()+",age="+student.getAge()+",grade="+temp.getName());
                temp2=student2.getGrade();//取出student3对应的grade
                System.out.println("name="+student2.getName()+",age="+student2.getAge()+",grade="+temp2.getName());
                temp3=student3.getGrade();//取出student3对应的grade
                System.out.println("name="+student3.getName()+",age="+student3.getAge()+",grade="+temp3.getName());

    }


}

运行结果:

多对一:
每位学生所对应数据:
name=沈雪冰,age=23,grade=基础部
name=李四,age=19,grade=基础部
name=王麻子,age=30,grade=基础部

五、双向一对多

Grade.java

package com.pojo;

import java.util.HashSet;
import java.util.Set;

import javassist.expr.NewArray;

public class Grade {
    private int id;
    private String name;
    private Set<Student> students=new HashSet<Student>(0);
    public Set<Student> getStudents() {
        return students;
    }
    public void setStudents(Set<Student> students) {
        this.students = students;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

}

Student.java

package com.pojo;
/**
***********************************
*
*@类名    Student
*@时间    2017年6月5日下午3:11:28
*@作者    沈雪冰
*@描述    
*
***********************************
*/
public class Student {
    private int id;
    private String name;
    private int age;
    private Grade grade;
  // private int gradeId;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
     public Grade getGrade() {
            return grade;
        }
        public void setGrade(Grade grade) {
            this.grade = grade;
        }

}

Grade.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 package="com.pojo">

    <class name="Grade" >
    <id name="id">
    <generator class="native" />
    </id>
    <property name="name" />
    <!-- set是grade中集合的属性    name属性名称
    -->
    <set name="students" table="student" >
    <!-- key表示外键  colume外键列名  not-null外键不能空-->
    <key column="grade_id" not-null="true"></key>
    <!-- 一对多 -->
    <one-to-many  class="com.pojo.Student"/>
    </set>
    </class>

    </hibernate-mapping>

Student.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 package="com.pojo">

    <class name="Student" >
    <id name="id">
    <generator class="native" />
    </id>
    <property name="name" />
    <property name="age" />

    </class>

    </hibernate-mapping>

测试代码:

package com.test;

import java.util.Iterator;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.pojo.Grade;
import com.pojo.Student;
import com.util.SessionFactoryUtil;


public class StudentDemo {
    public static void main(String[] args) {
        StudentDemo studentDemo = new StudentDemo();
        studentDemo.oneTomany();
    }

    public void oneTomany() {
        // 双向一对多
        SessionFactory sessionFactory = SessionFactoryUtil.getSessionFactory();// 单例创建sessionfactory
        Session session = sessionFactory.openSession();// 创建session
        Transaction transaction = session.beginTransaction();// 开始事务

        Grade grade = new Grade();
        grade.setName("基础部");

        Student student = new Student();
        student.setName("沈雪冰");
        student.setAge(23);

        Student student2 = new Student();
        student2.setName("李四");
        student2.setAge(19);
        // 建立双向关系
        grade.getStudents().add(student);
        grade.getStudents().add(student2);
        student.setGrade(grade);
        student2.setGrade(grade);
        // 保存顺序根据外键来决定的,如果外键不能为null 那么先保存一的一端,否则随意保存
        session.save(grade);

        session.save(student);
        session.save(student2);

        transaction.commit(); // 提交事务

        // 取数据
        Grade gradetemp = session.get(Grade.class, 1); // 获取id为1grade对象
        System.out.println("gradeName=" + grade.getName());
        System.out.println("grade所对应的一对多数据为:");
        Iterator<Student> iterator = gradetemp.getStudents().iterator();// 这里的学生信息是根据gradetemp信息获取的

        while (iterator.hasNext()) {
            Student temp = iterator.next(); // 取到一个数据
            System.out.println("name=" + temp.getName() + ",age=" + temp.getAge() + "" + ",gradename="
                    + temp.getGrade().getName());// 这里的grade信息是通过student信息获取的
        }

        session.close(); // 关闭session
    }

}

运行结果:
要注意和上边单向一对多的区别

gradeName=基础部
grade所对应的一对多数据为:
name=沈雪冰,age=23,gradename=基础部
name=李四,age=19,gradename=基础部
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

离水的鱼儿

一分也是爱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值