hibernate---一对多关联映射

本文详细介绍Hibernate中一对多关系的映射配置方法,并通过具体示例演示如何在Java项目中实现一对多关联关系,包括单向和双向关联。

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);
    }
}

set属性


单向多对一关联

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

  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属性的设置会带来性能上的变动,需谨慎设置

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

myeclipse连接数据库视图方法

myeclipse添加hibernate支持方法

myeclipse配置文档和获取会话

myeclipse添加数据库连接

反向工程

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

创建实体包entity


资源

  1. imooc Hibernate初探之一对多映射
  2. 代码
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值