hibernate多对一,一对多,多对多,一对一举例案例
程序员文章站
2022-07-12 21:21:06
...
1.项目结构
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.javapackage 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.javapackage 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();
}
}
上一篇: Appium自动化测试踩坑记录
下一篇: 前端学数据库之多表操作
推荐阅读
-
leftjoin陷阱之一对多导致数据量增加
-
java Hibernate 一对多自身关联问题
-
对一个tomcat实现多端口、多域名访问的方法
-
使用 doctrine orm 如何在程序逻辑上实现在一张表完成两个外键的设置(或则说一个实体完成两个多对一的关系)?
-
hibernate一对多&多对多关系的操作(四)
-
Mybatis动态sql、if与where的使用、sql片段、foreach遍历、Mybatis的关联查询一对一、一对多、多对多、Mybatis的延时加载
-
mybatis 一对一、一对多和多对多查询实例代码
-
mybatis 一对一、一对多和多对多查询实例代码
-
PageHelper插件实现一对多查询时的分页问题
-
EJB3.0开发之多对多和一对一