Hibernate 入门教程

来源:互联网 发布:同志手机聊天软件 编辑:程序博客网 时间:2024/06/05 18:02

上一篇文章中我们将了多对一、一对多的单双边配置,这篇文章我们主要讲一下多对多的单双边配置

Hibernate入门教程 第四章

Hibernate多对多的配置

Hibernate多对多分为2中情况,就是第三张表(中间表)的问题,如果中间表中没有其他的数据是一种,如果第三张表中有其他数据是一种。我们下面将分别对这2中情况进行讲解,我们选择最简单的学生选课为例子。

一、中间表中没有其他字段

1、配置文件

学生类

public class Student200  implements java.io.Serializable {    // Fields         private Integer id;     private String name;     private Set<Course200> courses = new HashSet<Course200>();    // Constructors    /** default constructor */    public Student200() {    }        /** full constructor */    public Student200(String name, Set courses) {        this.name = name;        this.courses = courses;    }       // Property accessors    public Integer getId() {        return this.id;    }        public void setId(Integer id) {        this.id = id;    }    public String getName() {        return this.name;    }        public void setName(String name) {        this.name = name;    }public Set<Course200> getCourses() {return courses;}public void setCourses(Set<Course200> courses) {this.courses = courses;}}

学生类配置文件 Student200.hbm.xml

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!--     Mapping file autogenerated by MyEclipse Persistence Tools--><hibernate-mapping>    <class name="com.sunny.entity200.Student200" table="student200" catalog="test100">        <id name="id" type="java.lang.Integer">            <column name="student_id" />            <generator class="identity"></generator>        </id>        <property name="name" type="java.lang.String">            <column name="name" length="20" />        </property>      <set name="courses" table="t_student_score">        <key column="student_id"></key>        <many-to-many class="com.sunny.entity200.Course200" column="course_id"></many-to-many>      </set>    </class></hibernate-mapping>

班级类

public class Course200  implements java.io.Serializable {    // Fields         private Integer id;     private String name;     private Set<Student200> students = new HashSet<Student200>();    // Constructors    /** default constructor */    public Course200() {    }        /** full constructor */    public Course200(String name) {        this.name = name;    }       // Property accessors    public Integer getId() {        return this.id;    }        public void setId(Integer id) {        this.id = id;    }    public String getName() {        return this.name;    }        public void setName(String name) {        this.name = name;    }public Set<Student200> getStudents() {return students;}public void setStudents(Set<Student200> students) {this.students = students;}}

班级类配置文件 Course200.hbm.xml

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!--     Mapping file autogenerated by MyEclipse Persistence Tools--><hibernate-mapping>    <class name="com.sunny.entity200.Course200" table="course200" catalog="test100">        <id name="id" type="java.lang.Integer">            <column name="course_id" />            <generator class="identity"></generator>        </id>        <property name="name" type="java.lang.String">            <column name="name" length="20" />        </property> <set name="students" table="t_student_score">        <key column="course_id"></key>        <many-to-many class="com.sunny.entity200.Student200" column="student_id"></many-to-many>        </set>    </class></hibernate-mapping>

我们可以看到配置文件中用的多少many-to-many

2、数据库操作
1、插入数据

//插入数据public static void fun1(){Session session = HibernateSessionFactory.getSessionFactory().openSession();Transaction trans = session.beginTransaction();Student200 stu = new Student200();stu.setName("tomcat");Course200 c1 = new Course200();c1.setName("c++");stu.getCourses().add(c1);Course200 c2 = new Course200();c2.setName("java");stu.getCourses().add(c2);session.save(stu);session.save(c1);session.save(c2);trans.commit();session.close();}

2、查询数据

//查询数据public static void fun2(){Session session = HibernateSessionFactory.getSessionFactory().openSession();Query query = session.createQuery("select s,s.name,c.name from Student200 s left join fetch s.courses c");List<Object[]> list = query.list();for(Object[] o : list){System.out.println(o[1]+" "+o[2]);}}

这里我们查询的是部分数据,而且我们用的是fetch,上几张中我们将了lazy的用法,我们知道Hibernate中默认lazy为true,既我们开启了延时加载,所以我们要想从学生中抓取课程的信息要fetch。我要说明的是,这句select s,s.name,c.name from Student200 s left join fetch s.courses c  语句中不要fetch效果是一样,left join 和 left join fetch在这里产生的效果是一样的,不知道Hibernate中为什么要可以这2种用法。

3、更新数据

//更行数据public static void fun3(){Session session = HibernateSessionFactory.getSessionFactory().openSession();Transaction trans = session.beginTransaction();Course200 c = (Course200)session.get(Course200.class, 1);c.setName("PHP");session.save(c);trans.commit();session.close();}

4、删除数据

//删除数据public static void fun4(){Session session = HibernateSessionFactory.getSessionFactory().openSession();Transaction trans = session.beginTransaction();Course200 c = (Course200)session.get(Course200.class, 2);session.delete(c);trans.commit();session.close();}
二、中间表中有其他字段

中间表有其他字段在Hibernate中稍微有点不同,我们还以学生选课为例,我们要在第三张表中加入成绩这个字段,上面没有多余字段情况下,我们我们2个类,2个配置文件,如果中间表中有其他的字段,那么我们就必须要产生中间表的类和配置文件,而且在hibernate中,多对多将拆分成2个一对多的情况(当然有其他的配置,我们这里给出常规的配置情况)。

下面我们给出配置方式

1、配置文件

学生类

package com.sunny.entity202;import java.util.HashSet;import java.util.Set;/** * Student200 entity. @author MyEclipse Persistence Tools */public class Student200  implements java.io.Serializable {    // Fields         private Integer studentId;     private String name;     private Set SCs = new HashSet(0);//SCs对应第三张表选课表    // Constructors    /** default constructor */    public Student200() {    }        /** full constructor */    public Student200(String name, Set SCs) {        this.name = name;        this.SCs = SCs;    }       // Property accessors    public Integer getStudentId() {        return this.studentId;    }        public void setStudentId(Integer studentId) {        this.studentId = studentId;    }    public String getName() {        return this.name;    }        public void setName(String name) {        this.name = name;    }    public Set getSCs() {        return this.SCs;    }        public void setSCs(Set SCs) {        this.SCs = SCs;    }}

学生配置文件

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!--     Mapping file autogenerated by MyEclipse Persistence Tools--><hibernate-mapping>    <class name="com.sunny.entity202.Student200" table="student200" catalog="test100">        <id name="studentId" type="java.lang.Integer">            <column name="student_id" />            <generator class="identity"></generator>        </id>        <property name="name" type="java.lang.String">            <column name="name" length="20" />        </property>        <set name="SCs" inverse="true">            <key>                <column name="student_id" not-null="true" />            </key>            <one-to-many class="com.sunny.entity202.SC" />        </set>    </class></hibernate-mapping>

课程类

public class Course200  implements java.io.Serializable {    // Fields         private Integer courseId;     private String name;     private Set SCs = new HashSet(0);    // Constructors    /** default constructor */    public Course200() {    }        /** full constructor */    public Course200(String name, Set SCs) {        this.name = name;        this.SCs = SCs;    }       // Property accessors    public Integer getCourseId() {        return this.courseId;    }        public void setCourseId(Integer courseId) {        this.courseId = courseId;    }    public String getName() {        return this.name;    }        public void setName(String name) {        this.name = name;    }    public Set getSCs() {        return this.SCs;    }        public void setSCs(Set SCs) {        this.SCs = SCs;    }}

课程配置文件

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!--     Mapping file autogenerated by MyEclipse Persistence Tools--><hibernate-mapping>    <class name="com.sunny.entity202.Course200" table="course200" catalog="test100">        <id name="courseId" type="java.lang.Integer">            <column name="course_id" />            <generator class="identity"></generator>        </id>        <property name="name" type="java.lang.String">            <column name="name" length="20" />        </property>        <set name="SCs" inverse="true">            <key>                <column name="course_id" not-null="true" />            </key>            <one-to-many class="com.sunny.entity202.SC" />        </set>    </class></hibernate-mapping>

中间表,选课表类

package com.sunny.entity202;/** * SC entity. @author MyEclipse Persistence Tools */public class SC  implements java.io.Serializable {    // Fields         private Integer id;     private Student200 student200;     private Course200 course200;     private Integer score;    // Constructors    /** default constructor */    public SC() {    }/** minimal constructor */    public SC(Student200 student200, Course200 course200) {        this.student200 = student200;        this.course200 = course200;    }        /** full constructor */    public SC(Student200 student200, Course200 course200, Integer score) {        this.student200 = student200;        this.course200 = course200;        this.score = score;    }       // Property accessors    public Integer getId() {        return this.id;    }        public void setId(Integer id) {        this.id = id;    }    public Student200 getStudent200() {        return this.student200;    }        public void setStudent200(Student200 student200) {        this.student200 = student200;    }    public Course200 getCourse200() {        return this.course200;    }        public void setCourse200(Course200 course200) {        this.course200 = course200;    }    public Integer getScore() {        return this.score;    }        public void setScore(Integer score) {        this.score = score;    }}

选课类配置文件

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!--     Mapping file autogenerated by MyEclipse Persistence Tools--><hibernate-mapping>    <class name="com.sunny.entity202.SC" table="t_student_score" catalog="test100">        <id name="id" type="java.lang.Integer">            <column name="id" />            <generator class="identity" />        </id>        <many-to-one name="student200" class="com.sunny.entity202.Student200" fetch="select">            <column name="student_id" not-null="true" />        </many-to-one>        <many-to-one name="course200" class="com.sunny.entity202.Course200" fetch="select">            <column name="course_id" not-null="true" />        </many-to-one>        <property name="score" type="java.lang.Integer">            <column name="score" />        </property>    </class></hibernate-mapping>


我们从上面配置可以看出,多对多被拆成了2个一对多

2、数据操作

这里我们就给出一个添加的操作,其他的都差不多

//插入数据public static void fun1(){Session session = HibernateSessionFactory.getSessionFactory().openSession();Transaction trans  = session.beginTransaction();Student200 stu = new Student200();stu.setName("apache");Course200 c  = new Course200();c.setName("java");SC sc = new SC();sc.setCourse200(c);sc.setStudent200(stu);sc.setScore(99);session.save(stu);session.save(c);session.save(sc);trans.commit();session.close();}


总结:我在多对多配置有多余字段的情况(多了成绩一个字段)中,我添加了一个主键id,在第一种情况中我没有添加id(选课表中只有2个字段学生id和课程id,联合主键),第二种情况我之所以要添加一个id是因为我如果不添加一个id,那么学生id和课程id就是联合主键,那么就要多出一个类来存储联合主键,看着麻烦,所以我这么做。

在多对多中配置中,像lazy、cascade、fetch、inverse 在前面我都说过,大家可以根据自已情况来选择一下配置,至于单边的配置,只要删除类中和配置文件中相关的地方就可以了,这里不再赘述







0 0