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 在前面我都说过,大家可以根据自已情况来选择一下配置,至于单边的配置,只要删除类中和配置文件中相关的地方就可以了,这里不再赘述
- Hibernate入门教程
- Hibernate入门教程
- Hibernate入门教程
- Hibernate入门教程
- Hibernate 入门教程
- hibernate官方入门教程 (转载)
- Hibernate入门教程1
- NetBeans + Struts + Hibernate 入门教程
- Hibernate入门教程01
- hibernate官方入门教程
- Hibernate快速入门教程(1)
- Hibernate快速入门教程(2)
- hibernate官方入门教程 (转载)
- hibernate官方入门教程 (转载)
- hibernate官方入门教程 (转载)
- Hibernate 入门教程(总结)
- hibernate简单入门教程
- hibernate官方入门教程
- 黑马程序员-c语言-通讯录的实现
- Exploit writing tutorial part1: Stack Based Overflows
- 程序包
- 大数据下的sql语句使用
- 传统企业进军互联网运营是个筐
- Hibernate 入门教程
- 南阳273 字母小游戏
- 黑马程序员——Java集合框架(二)之泛型
- easeljs的基础
- spring构造器注入
- 杭电1013 Digital Roots
- dlopen与dlsym的说明和使用-动态拿到函数地址
- 不熟悉互联网运营体系,则永远感觉是个渣
- Android Volley完全解析(三),定制自己的Request