hibernate---一对多关联映射

来源:互联网 发布:淘宝怎样退换货 编辑:程序博客网 时间:2024/05/28 04:54

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. 代码
0 0