hibernate---一对多关联映射

hibernate笔记(二)

映射类型

  1. 一对多(one to many)
  2. 多对一(many to one)
  3. 一对一(one to one)
  4. 多对多(many to many)

一对多关联

在数据库中,可以通过添加主外键的关联,表现一对多的关系

MyEclipse下的开发

jar包

1.手动添加jar包

  1. 建立一个lib,将jar包复制到lib下
  2. 选择lib目录下的所有jar包
  3. 鼠标右键-bulid path

2.IDE本身支持

鼠标右键-MyEclipse-Add Hibernate Capabilities

或者 project facets(capabilities)

Hibernate主配置文件

hibernate的解压缩包拷贝

cfg.xml (config的简写)

<!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="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password"></property>
    <property name="hibernate.connection.url">
        <![CDATA[
            jdbc:mysql://localhost:3306/hibernate?useUnicode=true&characterEncoding=utf8
        ]]>
    </property>
    <property name="show_sql">true</property>
    <property name="hbm2ddl.auto">update</property>

    <!-- 指定映射文件的路径 -->

    <mapping resource="Grade.hbm.xml"/>
    <mapping resource="Student.hbm.xml"/>

    </session-factory>
</hibernate-configuration>

创建工具类

package util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

public class hibernateUtil {
    private static SessionFactory sessionFactory;
    private static Session session;

    static
    {
        //创建Configuration对象,读取主配置文件cfg.xml,完成初始化
        Configuration config = new Configuration().configure();
        //hibernate 4.x 使用的方法
        StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder().applySettings(config.getProperties());
        StandardServiceRegistry ssr = ssrb.build();
        sessionFactory= config.buildSessionFactory(ssr);

    }
    //获取sessionFactory
    public static SessionFactory getSessionFactory()
    {
        return sessionFactory;
    }

    //获取Session
    public static Session getSession()
    {
        return sessionFactory.openSession();
    }

//关闭session
    public static void closeSession(Session session)
    {
        if(session!=null)
        {
            session.close();
        }
    }

}
  1. 获取会话的工具类

mysql数据库中建立表

建立一个students.sql文件

create table grade
(
    gid int primary key,
    gname varchar(20) not null,
    gdesc varchar(50)
);

create table student
(
    sid int primary key,
    sname varchar(20) not null,
    sex char(2),
    gid int
);

//外键约束

alter table student add constraint fk_student_gid foreign key (gid)
references grade(gid);

创建持久化类

一对多的关系,一个班级对应多名学生

学生类

package entity;

import java.io.Serializable;

public class Student implements Serializable {
    private int sid;
    private String sname;
    private String sex;

    public int getSid() {
        return sid;
    }
    public void setSid(int sid) {
        this.sid = sid;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }

}

班级类

package entity;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

public class Grade implements Serializable {
    private int gid;
    private String gname;
    private String gdesc;

    /**
        1.在一方定义一个多方的集合
        2.使用Set集合,学生不可以重复
    */
    private Set<Student> students = new HashSet<Student>();

    public int getGid() {
        return gid;
    }

    public void setGid(int gid) {
        this.gid = gid;
    }

    public String getGname() {
        return gname;
    }

    public void setGname(String gname) {
        this.gname = gname;
    }

    public String getGdesc() {
        return gdesc;
    }

    public void setGdesc(String gdesc) {
        this.gdesc = gdesc;
    }

    public Set<Student> getStudents() {
        return students;
    }

    public void setStudents(Set<Student> students) {
        this.students = students;
    }

    public Grade() {

    }

    public Grade(int gid, String gname, String gdesc, Set<Student> students) {
        super();
        this.gid = gid;
        this.gname = gname;
        this.gdesc = gdesc;
        this.students = students;
    }
}

映射文件的配置

班级Grade映射文件

<hibernate-mapping>
    <class name="entity.Grade" table="grade">
        <id name="gid" column="gid" type="java.lang.Integer">
            <generator class="increment"></generator>
        </id>
        <property name="gname" type="java.lang.String">
            <column name="gname" length="20" not-null="true"></column>
        </property>
        <property name="gdesc">
            <column name="gdesc"></column>
        </property>
        <!-- 配置一对多关联关系 -->
        <set name="students" table="student">
            <!--指定关联的外键列-->
            <key column="gid"></key>
            <one-to-many class="entity.Student"/>
        </set>
    </class>
</hibernate-mapping>
  1. 班级映射文件
  2. class标签对应持久化类,table对应数据库中的数据表
  3. id标签为主键,generator对应生成策略
  4. property标签对应了其它属性

学生Student映射文件

<hibernate-mapping>
    <class name="entity.Student" table="student">
        <id name="sid" column="sid" type="java.lang.Integer">
            <generator class="increment"></generator>
        </id>
        <property name="sname" type="java.lang.String">
            <column name="sname" length="20" not-null="true"></column>
        </property>
        <property name="sex">
            <column name="sex"></column>
        </property>
        <!-- 配置多对一关联关系 -->

    </class>
</hibernate-mapping>

测试

单向一对多关系(班级—>学生)

班级的构造方法(wihtout id and students)

学生的构造方法(without id )和无参构造方法

在学生表中添加相应的班级编号,需要在班级中添加学生,建立关联关系

package entity;

import java.util.Set;

import org.hibernate.Session;
import org.hibernate.Transaction;

import util.hibernateUtil;

public class Test {
    public static void main(String[] args) {
        //add();
        //findStudentByGrade();
        //update();
        delete();
    }

    //将学生添加到班级
    public static void add()
    {
        Grade g = new Grade("电气一班","信息学院");
        Student stu1 = new Student("依然", "女");
        Student stu2 = new Student("牧月", "女");

        //在学生表中添加相应的班级编号,需要在班级中添加学生,建立关联关系
        g.getStudents().add(stu1);
        g.getStudents().add(stu2);

        Session session = hibernateUtil.getSession();
        Transaction tx = session.beginTransaction();
        session.save(g);
        session.save(stu1);
        session.save(stu2);
        tx.commit();
        hibernateUtil.closeSession(session);

    }

    //学生信息的查询,班级中学生信息
    //建立关联关系后,可以方便的从一个对象导航到另一个对象
    //注意关联的方向 班级--->学生

    public static void findStudentByGrade()
    {
        Session session = hibernateUtil.getSession();
        Grade grade = (Grade) session.get(Grade.class,1);
        System.out.println(grade.getGname()+","+grade.getGdesc());

        Set<Student>  students = grade.getStudents();
        for(Student stu:students)
        {
            System.out.println(stu.getSname()+","+stu.getSex());
        }

    }

    //修改学生信息
    public static void update()
    {
        Grade g = new Grade("健行一班", "健行学院");

        Session  session = hibernateUtil.getSession();
        Transaction tx = session.beginTransaction();
        Student stu = (Student)session.get(Student.class, 1);
        g.getStudents().add(stu);
        session.save(g);
        tx.commit();
        hibernateUtil.closeSession(session);
    }

    //删除学生信息
    public static void delete()
    {
        Session session = hibernateUtil.getSession();
        Transaction tx = session.beginTransaction();
        Student stu = (Student)session.get(Student.class, 1);
        session.delete(stu);
        tx.commit();
        hibernateUtil.closeSession(session);
    }
}


单向多对一关联

通过在多方持有一方的引用实现,需要在多的一端使用

  1. 在多方的持久化类中定义一个多方的引用,并且生成getter/setter
  2. 映射文件的配置(多方);一方配置不用更改

    package test;

    import org.hibernate.Session;

    import org.hibernate.Transaction;

    import util.hibernateUtil;

    import entity.Grade;

    import entity.Student;

    //测试单向多对一(学生—>班级)

    public class Test2 {

    public static void main(String[] args) {

    save();

    }

    //保存
    public static void save()
    {
        Grade g = new Grade("电气一班", "信息学院");
        Student stu1 = new Student("王九九","女");
        Student stu2 = new Student("林浣溪", "女");
    
        //设置关联关系
        stu1.setGrade(g);
        stu2.setGrade(g);
    
        Session session = new hibernateUtil().getSession();
        Transaction tx = session.beginTransaction();
        session.save(g);
        session.save(stu1);
        session.save(stu2);
        tx.commit();
        hibernateUtil.closeSession(session);
    
    }
    

    }


双向多对一

package test;

import org.hibernate.Session;
import org.hibernate.Transaction;

import util.hibernateUtil;
import entity.Grade;
import entity.Student;

//测试单向多对一(学生--->班级)

public class Test2 {
    public static void main(String[] args) {
        save();
    }

    //保存
    public static void save()
    {
        Grade g = new Grade("电气一班", "信息学院");
        Student stu1 = new Student("王九九","女");
        Student stu2 = new Student("林浣溪", "女");

        //设置关联关系
        g.getStudents().add(stu1);
        g.getStudents().add(stu2);
        stu1.setGrade(g);
        stu2.setGrade(g);

        Session session = new hibernateUtil().getSession();
        Transaction tx = session.beginTransaction();
        session.save(g);
        session.save(stu1);
        session.save(stu2);
        tx.commit();
        hibernateUtil.closeSession(session);

    }
}

inverse属性

set标签

指定关联关系的控制方向,默认由one方来维护

在关联关系中,inverse=”false”,则为主动方,由主动方负责维护关联关系

在一对多关联中,只能设置one方的inverse为true,这将有助于性能的改善

cascade属性

session.save(g);
session.save(stu1);
session.save(stu2);
  1. 操作麻烦,保存班级,仍然需要进行保存学生的操作
  2. 级联操作简化

当设置了cascade属性不为none时,hibernate会自动持久化所关联的对象

cascade属性的设置会带来性能上的变动,需谨慎设置

查询操作

查询学生所在班级的信息

//查询学生所在班级信息
public static void findGradeByStudent()
{
    Session session = hibernateUtil.getSession();
    Student stu =(Student) session.get(Student.class, 2);
    System.out.println(stu.getSid()+","+stu.getSname()+","+stu.getSex());

    Grade g = stu.getGrade();
    System.out.println(g.getGid()+","+g.getGname()+","+g.getGdesc());
    hibernateUtil.closeSession(session);
}

总结

实现单向一对多

  1. 在one方的实体中添加保存many方的集合
  2. 在one方的配置文件中添加one-to-many标签

实现单向多对一

  1. 在many方的实体中添加one方的引用
  2. 在many方的配置文件中添加many-to-one标签

常用属性

  1. cascade:设置级联关系
  2. inverse:设置哪一方维护关联关系

MyEclipse使用技巧

使用IDE提供的支持来简化操作

添加数据库连接视图

MyEclipse的右上角-open perspective-MyEclipse Database Explorer

或者是

菜单栏-Window-Show View-Other 展开MyEclipse Database 选择DB Browser

反向工程

根据数据库中的表,自动生成持久化类和映射关系文件

创建实体包entity


资源

  1. imooc Hibernate初探之一对多映射
  2. 代码
时间: 2024-08-11 10:53:42

hibernate---一对多关联映射的相关文章

Hibernate一对多关联映射的配置及其级联删除问题

首先举一个简单的一对多双向关联的配置: 一的一端:QuestionType类 package com.exam.entity; import java.util.Set; public class QuestionType { private String typeName; private char typeUniqueness; private Set quesion; public String getTypeName() { return typeName; } public void

【SSH系列】Hibernate映射 -- 一对多关联映射

    映射原理       一对多关联映射和多对一关联映射的映射原理是一样一样的,所以说嘛,知识都是相通的,一通百通,为什么说一对多关联映射和多对一关联映射是一样的呢?因为她们都是在多的一端加入一个外键,指向一的一段,关联关系都是在多的一端进行维护,只是我们在写映射的时候发生了变化.       一对多和多对一的映射原理是一样的,但是她们之间也存在着小小的区别,毕竟世界上没有两片完全相同的叶子,她们之间的区别就是维护的关系不同,我们先来看多对一,多端维护一端的关系,在加载多端的时候,可以将一端

【SSH进阶之路】Hibernate映射——一对多关联映射(七)

上上篇博文[SSH进阶之路]Hibernate映射--一对一单向关联映射(五),我们介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证端加载人得信息. 上篇博文[SSH进阶之路]Hibernate映射--一对一双向关联映射(六),双向关联映射解决了单向关联映射只能从一端加载信息的缺陷,当然,双向关联映射并不影响存储,只影响加载.下面我们开始今天的内容: 一对多关联映射 映射原理 一对多关联映射和多对一关联映射的映射原理是一致的,

hibernate之关于使用连接表实现一对多关联映射

[Hibernate]之关于使用连接表实现一对多关联映射 基于中间表实现的一对多的关联映射,还是比较常见的. Person(人)和Group(组) Annotations配置 @Entity @Table(name="t_group") publicclass Group {     private Integer id;     private String name;     private Set<Person> persons=newHashSet<Perso

一步步学习Hibernate框架(四):采用jpa实现一对多关联映射(二)

上篇博客已经采用jpa注解来实现了一对多关联映射,将这种关联映射以外键的形式处理,现在来看看怎么以第三张表的形式处理.采用jpa注解来映射数据库要使用的jar包见上篇博客: 一步步学习Hibernate框架(三):采用jpa实现一对多关联映射(一) 现在看第二种方式:以第三张表的关系来体现 Group.java package com.tgb.zhudan; import java.util.List; import javax.persistence.CascadeType; import j

菜鸟学习Hibernate——一对多关系映射

Hibernate中的关系映射,最常见的关系映射之一就是一对多关系映射例如学生与班级的关系,一个班级对应多个学生.如图: Hibernate中如何来映射这两个的关系呢? 下面就为大家讲解一下: 1.创建实体类Classes和实体类Student Classes.java package com.bjpowernode.hibernate; import java.util.Set; public class Classes { private int id; private String nam

hihernate一对多关联映射

一对多关联映射利用了多对一关联映射原理 多对一关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是多指向一 一对多关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是一指向多 举个例子员工和老板.你说是老板记员工比较容易还是员工记老板比较容易呢?很明显记少的比较容易啊,能维护二者的关系也能减少工作量.hibernate当然也是这么做的. 也就是说一对多和多对一的映射策略是一样的,只是站的角度不同 在关系型数据库理论中,"多对一"关联同于"一对多"关联

014 一对多关联映射 单向(one-to-many)

在对象模型中,一对多的关联关系,使用集合来表示. 实例场景:班级对学生:Classes(班级)和Student(学生)之间是一对多的关系. 多对一.一对多的区别: 多对一关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是多指向一的. 一对多关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是一指向多的. 两者使用的策略是一样的,只是各自所站的角度不同. Classes实体类: public class Classes { private int id; private Stri

【Hibernate】——一对一关联映射

两个对象之间如果是一对一的关系,如Person-IdCard.在Hibernate中有两种策略可以实现一对一的关联映射: 主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系:数据库表不会有额外的字段来维护它们之间的关系,仅通过表得主键来关联. 唯一外键关联:外键关联,本来是用于多对一的配置,但是如果加上唯一的限制之后,也可以用来表示一对一关联关系: 而每种策略又分为两种方向的对应关系,即单向一对一关系和双向一对一关系.分类的原因一般是由需求决定的,单双向是站在不同的角度去看人

hibernate的数据关联映射

数据关联映射分为:一对多.多对一,一对一,多对多. cascade属性• save-update:在执行保存和修改是进行级联操作• delete:在执行删除时进行级联操作• all:在所有情况下进行级联操作• none:不进行级联操作(默认) 抓取策略 一对多.多对一 一对多.多对一持久化类设计 // User类 public class User { private int id; private String name; private int age; private Set<Addres