码迷,mamicode.com
首页 > Web开发 > 详细

Hibernate 入门教程

时间:2015-06-28 17:39:34      阅读:182      评论:0      收藏:0      [点我收藏+]

标签:hibernate多对多   hibernate入门教程   

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

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 在前面我都说过,大家可以根据自已情况来选择一下配置,至于单边的配置,只要删除类中和配置文件中相关的地方就可以了,这里不再赘述








Hibernate 入门教程

标签:hibernate多对多   hibernate入门教程   

原文地址:http://blog.csdn.net/zhangpan19910604/article/details/46671297

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!