欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

hibernate多对一,一对多,多对多,一对一举例案例

程序员文章站 2022-07-12 21:21:06
...

1.项目结构

hibernate多对一,一对多,多对多,一对一举例案例

2. 主配置文件 hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC
	"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
	"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<!-- 把name="foo"属性去掉 -->
	<session-factory>
		<!--这里是Hibernate框架的基本配置:数据库连接,框架参数的配置,映射文件的配置  -->
		<!-- 方言,表示Hibernate框架在与某个数据库进行映射,才能自动生成某个数据库特有的SQL语句 -->
		<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
		<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="connection.url">jdbc:mysql://localhost:3306/myschool?characterEncoding=utf-8</property>
		<property name="connection.username">root</property>
		<property name="connection.password">root</property>
		
		<!--Hibernate框架的基本配置  -->
		<!-- 打印sql语句,一般开发时运用 ,跟踪自动生成的Sql语句-->
		<property name="show_sql">true</property>
		<!-- 格式化打印的sql语句,一般开发时运用,便于区分关键字 -->
		<property name="format_sql">true</property>
		<!--此属性表示根据当前线程来操作数据,可以提交或者回滚  -->
		<property name="current_session_context_class">thread</property>
		<!--数据库中的表结构可以随映射文件的配置发生改变 -->
		<!-- <property name="hbm2ddl.auto">create</property> --> 
		<!--映射文件加载  -->
		<mapping resource="com/zhq/entity/Grade.hbm.xml"/>
		<mapping resource="com/zhq/entity/Subject.hbm.xml"/>
		<mapping resource="com/zhq/entity/Students.hbm.xml"/>
		<mapping resource="com/zhq/entity/Teachers.hbm.xml"/>
		<mapping resource="com/zhq/entity/StudentsInfo.hbm.xml"/>
	</session-factory>
</hibernate-configuration>

3. 多对一相关的举例配置文件Subject.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--映射文件的根节点,package:表示实体对象的包名  -->
<hibernate-mapping package="com.zhq.entity">
  <!--class:表示实体类,name:类名 table:表示数据库中的表名  -->
  <class name="Subject" table="subject">
  	<!--表示主键  -->
  	<id name="subjectNo" column="subjectNo" type="int">
  	<!--主键的生成策略,native:表示交由数据库按自身特定的自动增长策略来自动生成增长值  。-->
  		<generator class="native"/>
  	</id>
  	<!--表示主键和外键之外的普通列name:表示实体对象的属性名,column:数据库表的列名,如果属性名和列名一致可以省略column。  -->
  	<property name="subjectName"/>
  	<property name="classHour"/>
  	<!--多对一的关系映射 name:是外键对象属性名  class:实体类型  -->
  	<many-to-one name="grade" class="Grade">
  		<!--name:表示外键列 查询数据时,根据外键列的值取得实体对象,封装在外键对象属性中  -->
  		<column name="gradeId"/>
  	</many-to-one>
  </class>
  <!-- 可以在一个文件中配置多个实体映射对象,但通常情况下不会这样子做。
  	<class name="XXX" table="XXX">
  	</class>
   -->
</hibernate-mapping>

4. 一对多相关的举例配置文件Grade.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--映射文件的根节点,package:表示实体对象的包名  -->
<hibernate-mapping package="com.zhq.entity">
  <!--class:表示实体类,name:类名 table:表示数据库中的表名  -->
  <class name="Grade" table="grade">
  	<!--表示主键  -->
  	<id name="gradeId" column="gradeId" type="int">
  	<!--主键的生成策略,native:表示交由数据库按自身特定的自动增长策略来自动生成增长值  。-->
  		<generator class="native"/>
  	</id>
  	<!--表示主键和外键之外的普通列name:表示实体对象的属性名,column:数据库表的列名,如果属性名和列名一致可以省略column。  -->
  	<property name="gradeName" column="gradeName" type="string" length="20"></property>
  	<!--一对多的映射 Set List Map  -->
  	<!--name:封装外键对象的属性  -->
  	<set name="subjects">
  		<!--年级表的主键  -->
  		<key column="gradeId"/>
  		<!-- 外键对象 -->
  		<one-to-many class="Subject"/>
  	</set>
  </class>
  <!-- 可以在一个文件中配置多个实体映射对象,但通常情况下不会这样子做。
  	<class name="XXX" table="XXX">
  	</class>
   -->
</hibernate-mapping>

5. 多对多相关的举例配置文件Students.hbm.xml和Teachers.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--映射文件的根节点,package:表示实体对象的包名  -->
<hibernate-mapping package="com.zhq.entity">
  <!--class:表示实体类,name:类名 table:表示数据库中的表名  -->
  <class name="Students" table="students">
  	<!--表示主键  -->
  	<id name="studentId" column="studentId" type="int">
  	<!--主键的生成策略,native:表示交由数据库按自身特定的自动增长策略来自动生成增长值  。-->
  		<generator class="native"/>
  	</id>
  	<!--表示主键和外键之外的普通列name:表示实体对象的属性名,column:数据库表的列名,如果属性名和列名一致可以省略column。  -->
  	<property name="studentName"/>
  	<!--一对一 ,主表,one-to-many property-ref="student"是子表中关联的外键对象名称 -->
  	<one-to-one name="studentInfo" class="StudentsInfo" property-ref="student"/>
  	<!-- 多对多的处理 -->
  	<!--根据学员编号获取老师的编号,再根据老师的编号编号获取老师的信息封装在teachers属性中  -->
  	<set name="teachers" table="s_t">
  		<key column="studentId"/>
  		<many-to-many class="Teachers" column="teacherId"/>
  	</set>
  </class>
  <!-- 可以在一个文件中配置多个实体映射对象,但通常情况下不会这样子做。
  	<class name="XXX" table="XXX">
  	</class>
   -->
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--映射文件的根节点,package:表示实体对象的包名  -->
<hibernate-mapping package="com.zhq.entity">
  <!--class:表示实体类,name:类名 table:表示数据库中的表名  -->
  <class name="Teachers" table="teachers">
  	<!--表示主键  -->
  	<id name="teacherId" column="teacherId" type="int">
  	<!--主键的生成策略,native:表示交由数据库按自身特定的自动增长策略来自动生成增长值  。-->
  		<generator class="native"/>
  	</id>
  	<!--表示主键和外键之外的普通列name:表示实体对象的属性名,column:数据库表的列名,如果属性名和列名一致可以省略column。  -->
  	<property name="teacherName"/>
  	<!-- 多对多的处理 -->
  	<!--根据老师编号获取学生的编号,再根据学生的编号编号获取学生的信息封装在students属性中  -->
  	<set name="students" table="s_t">
  		<key column="teacherId"/>
  		<many-to-many class="Students" column="studentId"/>
  	</set>
  </class>
  <!-- 可以在一个文件中配置多个实体映射对象,但通常情况下不会这样子做。
  	<class name="XXX" table="XXX">
  	</class>
   -->
</hibernate-mapping>

6. 一对一相关的举例配置文件Students.hbm.xml和StudentsInfo.hbm.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--映射文件的根节点,package:表示实体对象的包名  -->
<hibernate-mapping package="com.zhq.entity">
  <!--class:表示实体类,name:类名 table:表示数据库中的表名  -->
  <class name="Students" table="students">
  	<!--表示主键  -->
  	<id name="studentId" column="studentId" type="int">
  	<!--主键的生成策略,native:表示交由数据库按自身特定的自动增长策略来自动生成增长值  。-->
  		<generator class="native"/>
  	</id>
  	<!--表示主键和外键之外的普通列name:表示实体对象的属性名,column:数据库表的列名,如果属性名和列名一致可以省略column。  -->
  	<property name="studentName"/>
  	<!--一对一 ,主表,one-to-many property-ref="student"是子表中关联的外键对象名称 -->
  	<one-to-one name="studentInfo" class="StudentsInfo" property-ref="student"/>
  	<!-- 多对多的处理 -->
  	<!--根据学员编号获取老师的编号,再根据老师的编号编号获取老师的信息封装在teachers属性中  -->
  	<set name="teachers" table="s_t">
  		<key column="studentId"/>
  		<many-to-many class="Teachers" column="teacherId"/>
  	</set>
  </class>
  <!-- 可以在一个文件中配置多个实体映射对象,但通常情况下不会这样子做。
  	<class name="XXX" table="XXX">
  	</class>
   -->
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!--映射文件的根节点,package:表示实体对象的包名  -->
<hibernate-mapping package="com.zhq.entity">
  <!--class:表示实体类,name:类名 table:表示数据库中的表名  -->
  <class name="StudentsInfo" table="studentsInfo">
  	<!--表示主键  -->
  	<id name="studentInfoId" column="studentInfoId" type="int">
  	<!--主键的生成策略,native:表示交由数据库按自身特定的自动增长策略来自动生成增长值  。-->
  		<generator class="native"/>
  	</id>
  	<!--表示主键和外键之外的普通列name:表示实体对象的属性名,column:数据库表的列名,如果属性名和列名一致可以省略column。  -->
  	<property name="sex"/>
  	<!--一对一 ,有外键的表,子表,其实是一对多的关系,加 unique="true"唯一约束,而成了一对一-->
    <many-to-one name="student" column="studentId" class="Students" unique="true"/>
  </class>
  <!-- 可以在一个文件中配置多个实体映射对象,但通常情况下不会这样子做。
  	<class name="XXX" table="XXX">
  	</class>
   -->
</hibernate-mapping>
7. 相关实体类Grade.java,Students.java,StudentsInfo.java,Subject.java,Teachers.java

package com.zhq.entity;

import java.util.Set;

public class Grade {
	private int gradeId;
	private String gradeName;
	private Set<Subject> subjects;
	public int getGradeId() {
		return gradeId;
	}
	public void setGradeId(int gradeId) {
		this.gradeId = gradeId;
	}
	public String getGradeName() {
		return gradeName;
	}
	public void setGradeName(String gradeName) {
		this.gradeName = gradeName;
	}
	
	public Set<Subject> getSubjects() {
		return subjects;
	}
	public void setSubjects(Set<Subject> subjects) {
		this.subjects = subjects;
	}
	@Override
	public String toString() {
		return "Grade [gradeId=" + gradeId + ", gradeName=" + gradeName + "]";
	}
	
	
}
package com.zhq.entity;

import java.util.Set;

public class Students {
	private int studentId;
	private String studentName;
	private StudentsInfo studentInfo;
	private Set<Teachers> teachers;
	public int getStudentId() {
		return studentId;
	}
	public void setStudentId(int studentId) {
		this.studentId = studentId;
	}
	public String getStudentName() {
		return studentName;
	}
	public void setStudentName(String studentName) {
		this.studentName = studentName;
	}
	public StudentsInfo getStudentInfo() {
		return studentInfo;
	}
	public void setStudentInfo(StudentsInfo studentInfo) {
		this.studentInfo = studentInfo;
	}
	public Set<Teachers> getTeachers() {
		return teachers;
	}
	public void setTeachers(Set<Teachers> teachers) {
		this.teachers = teachers;
	}
	
}
package com.zhq.entity;

public class StudentsInfo {
	private int studentInfoId;
	private String sex;
	private Students student;
	public int getStudentInfoId() {
		return studentInfoId;
	}
	public void setStudentInfoId(int studentInfoId) {
		this.studentInfoId = studentInfoId;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public Students getStudent() {
		return student;
	}
	public void setStudent(Students student) {
		this.student = student;
	}
	

}

package com.zhq.entity;

public class Subject {
	private int subjectNo;
	private String subjectName;
	private int classHour;
	//年级编号外键,实体类采用外键对象来处理 多对一
	private Grade grade;
	public int getSubjectNo() {
		return subjectNo;
	}
	public void setSubjectNo(int subjectNo) {
		this.subjectNo = subjectNo;
	}
	public String getSubjectName() {
		return subjectName;
	}
	public void setSubjectName(String subjectName) {
		this.subjectName = subjectName;
	}
	public int getClassHour() {
		return classHour;
	}
	public void setClassHour(int classHour) {
		this.classHour = classHour;
	}
	public Grade getGrade() {
		return grade;
	}
	public void setGrade(Grade grade) {
		this.grade = grade;
	}
	@Override
	public String toString() {
		return "Subject [subjectNo=" + subjectNo + ", subjectName=" + subjectName + ", classHour=" + classHour + ", gradeName=" + grade.getGradeName() +  "]";
	}
	
}
package com.zhq.entity;

import java.util.Set;

public class Teachers {
	private int teacherId;
	private String teacherName;
	private Set<Students> students;
	public int getTeacherId() {
		return teacherId;
	}
	public void setTeacherId(int teacherId) {
		this.teacherId = teacherId;
	}
	public String getTeacherName() {
		return teacherName;
	}
	public void setTeacherName(String teacherName) {
		this.teacherName = teacherName;
	}
	public Set<Students> getStudents() {
		return students;
	}
	public void setStudents(Set<Students> students) {
		this.students = students;
	}
	
}
8. 测试功能所用到相关的类GradeController.java,StudentController.java,SubjectController.java,TeacherController.java
package com.zhq.controller;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.zhq.entity.Grade;
import com.zhq.entity.Subject;
import com.zhq.util.SessionFactoryUtil;

public class GradeController {

	public static void main(String[] args) {
		/*增
		 * Grade g=new Grade();
		   g.setGradeName("大三");
		   add(g);
		 */
		
		
           read();
       
		
		/*通过主键查询某个
		   readOne(1);
		 */
		
		/*通过主键删除
		  delete(29);
		 */
		
		/*通过主键修改
		 * Grade g=new Grade();
		   g.setGradeId(27);
		   g.setGradeName("大三");
		   update(g);
		 */
		
	}
	//查全部
	public static void read() {
		//获取连接Session,此对象用于操作数据库对象
		Session session=SessionFactoryUtil.getSession();
		//开启事务,如果是增删改的操作,必须要提交事务
		session.beginTransaction();
		//根据Session连接对象操作数据库,"from Grade"是HQL语言,注意:Grade是表示实体对象
		Query query=session.createQuery("from Grade");
		@SuppressWarnings("unchecked")
		List<Grade> grades=query.list();
		for(Grade grade:grades){
			System.out.println(grade);
			for(Subject subject:grade.getSubjects()) {
				System.out.println(subject);
			}
		}
		session.close();
	}
	//查单个对象
	public static void readOne(int gradeId) {
		//获取连接Session,此对象用于操作数据库对象
		Session session=SessionFactoryUtil.getSession();
		//开启事务,如果是增删改的操作,必须要提交事务
		session.beginTransaction();
		Grade g=(Grade) session.get(Grade.class, gradeId);
		if(g!=null) {
			System.out.println(g);	
		}else {
			System.out.println("没有找到相关数据");
		}
	}
	//增
	public static void add(Grade g) {
		Session session=SessionFactoryUtil.getSession();
		Transaction tx=null;
		try {
			tx=session.beginTransaction();
			session.save(g);
			tx.commit();
		} catch (Exception e) {
			tx.rollback();
		}
	}
	//删
	public static void delete(int gradeId) {
		Session session=SessionFactoryUtil.getSession();
		Transaction tx=null;
		try {
			tx=session.beginTransaction();
			Grade g=(Grade) session.get(Grade.class, gradeId);
			if(g!=null) {
				session.delete(g);	
			}else {
				System.out.println("没有找到相关数据");
			}
			tx.commit();
		} catch (Exception e) {
			tx.rollback();
		}
	}
	//改
	public static void update(Grade g) {
		Session session=SessionFactoryUtil.getSession();
		Transaction tx=null;
		try {
			tx=session.beginTransaction();
			session.update(g);	
			tx.commit();
		} catch (Exception e) {
			tx.rollback();
		}
	}
}
package com.zhq.controller;

import java.util.List;

import org.hibernate.Session;


import com.zhq.entity.Students;
import com.zhq.entity.StudentsInfo;
import com.zhq.entity.Teachers;
import com.zhq.util.SessionFactoryUtil;

public class StudentController {

	public static void main(String[] args) {
		
		add();
		read();
	}

	private static void add() {
		Session session=SessionFactoryUtil.getSession();
		session.beginTransaction();
		Students student=new Students();
		StudentsInfo studentInfo=new StudentsInfo();
		student.setStudentName("大熊");
		session.save(student);
		studentInfo.setSex("男");
		studentInfo.setStudent(student);
		session.save(studentInfo);
		session.getTransaction().commit();	
	}
	private static void read() {
		Session session=SessionFactoryUtil.getSession();
		session.beginTransaction();
		@SuppressWarnings("unchecked")
		List<Students> list=session.createQuery("from Students").list();
	    for(Students student:list) {
	    	System.out.println(student.getStudentName()+"的老师:");
	    	for(Teachers teacher:student.getTeachers()) {
	    		System.out.print(teacher.getTeacherName()+",");
	    	}
	    	System.out.println();
	    }
	    session.getTransaction().commit();
	}

}
package com.zhq.controller;

import java.util.List;

import org.hibernate.Session;

import com.zhq.entity.Subject;
import com.zhq.util.SessionFactoryUtil;

public class SubjectController {

	public static void main(String[] args) {
		read();

	}

	private static void read() {
		Session session=SessionFactoryUtil.getSession();
		session.beginTransaction();
		@SuppressWarnings("unchecked")
		List<Subject> list=session.createQuery("from Subject").list();
	    for(Subject subject:list) {
	    	System.out.println(subject);
	    }
	    session.getTransaction().commit();
	}

}
package com.zhq.controller;

import java.util.List;

import org.hibernate.Session;

import com.zhq.entity.Students;
import com.zhq.entity.Teachers;
import com.zhq.util.SessionFactoryUtil;

public class TeacherController {

	public static void main(String[] args) {
		read();
	}
	private static void read() {
		Session session=SessionFactoryUtil.getSession();
		session.beginTransaction();
		@SuppressWarnings("unchecked")
		List<Teachers> list=session.createQuery("from Teachers").list();
	    for(Teachers teacher:list) {
	    	System.out.println(teacher.getTeacherName()+"的学生:");
	    	for(Students student:teacher.getStudents()) {
	    		System.out.print(student.getStudentName()+",");
	    	}
	    	System.out.println();
	    }
	    session.getTransaction().commit();
	}

}