hibernate(4):hibernate映射关系续

本文介绍了一对一及多对多的数据映射方法,包括表结构设计、Java类定义、XML映射文件配置及测试类实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看完多对一,再来看看一对一的情况:

学生和证件是一对一的关系,并且学生ID和证件的ID是相同的。

 

建表脚本:

 

create table certificate(
    id varchar(100) not null default '',
    `describe` varchar(100) default '',
    primary key (id)
)

create table student(
    id varchar(100) not null default'',
    name varchar(20) default'',
    `cardId` varchar(20) not null default'',
    age int(11) default'0',
    primary key(id)
)

 

Student.java

package com.hibernate.model;

public class Student {
	private String id; //标识ID
	private String cardId;//学号
	private String name;//姓名
	private int age;//年龄 
	private Certificate cer;//身份证
	private Team team;//班级
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getCardId() {
		return cardId;
	}
	public void setCardId(String cardId) {
		this.cardId = cardId;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Certificate getCer() {
		return cer;
	}
	public void setCer(Certificate cer) {
		this.cer = cer;
	}
	public Team getTeam() {
		return team;
	}
	public void setTeam(Team team) {
		this.team = team;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}

 

 

package com.hibernate.model;

public class Certificate {
	private String id;
	private String describe;
	private Student stu;
	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public Student getStu() {
		return stu;
	}

	public void setStu(Student stu) {
		this.stu = stu;
	}

	public String getDescribe() {
		return describe;
	}

	public void setDescribe(String describe) {
		this.describe = describe;
	}

}

 

Student.hbm.xml 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC    
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.hibernate.model.Student" table="student">
		<id name="id" unsaved-value="null">
			<generator class="uuid.hex"/><!-- 这表示用hibernate的字符序列生成ID -->
		</id>
		<property name="cardId" type="string"/><!-- 没有指定 column,则列名和属性名是一样的 -->
		<property name="name" type="string"/>
		<property name="age" type="int"/>
		<one-to-one name="cer" class="com.hibernate.model.Certificate" fetch="join" cascade="all">
		</one-to-one>
	</class>
</hibernate-mapping>

 

Certificate.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC    
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.hibernate.model.Certificate" table="certificate" lazy="true">
		<id name="id">
			<!-- 下面表示引用Certificate的id引用Student的id -->
			<generator class="foreign">
				<!-- 对应Certificate类的stu属性 -->
				<param name="property">stu</param>
			</generator>
		</id>
		<!-- 因为describe是mysql的关键字,所以下面要用`号(数字键1旁边的字符)表示 -->
		<property name="describe" column="`describe`" type="string"/>
		<one-to-one name="stu" class="com.hibernate.model.Student" fetch="select" 
			constrained="true" cascade="none">
		</one-to-one>
	</class>
</hibernate-mapping>

 

在hibernate.hbm.xml中加上映射

    	<mapping resource="Student.hbm.xml"></mapping>
    	<mapping resource="Certificate.hbm.xml"></mapping>

 

测试类

package com.hibernate.util;

import org.hibernate.Session;
import org.hibernate.Transaction;
import com.hibernate.model.Certificate;
import com.hibernate.model.Student;

public class BM {
	public static void main(String[] args) {
		Session session = HibernateUtil.currentSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			//实例化student
			Student stu = new Student();
			stu.setName("lisi");
			stu.setCardId("200202");
			stu.setAge(18);
			//实例化certificate
			Certificate certificate = new Certificate();
			certificate.setDescribe("lisi_certificate");
			//设置关联
			stu.setCer(certificate);
			certificate.setStu(stu);
			//只保存student,certificate会自动保存
			session.save(stu);
			tx.commit();
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			HibernateUtil.closeSession(session);
		}
	}
}

 

 

再来看看一对一的另一种情况,即certificate表中添加一个stu_id字段,这个字段用来关联引用Student的id,

这也是在实际开发中用的最多的。

针对这种情况,只需要修改上例中的Certificate.hbm.xml文件,将one-to-one修改成many-to-one,如下所示,其它类不需要修改。

 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC    
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.hibernate.model.Certificate" table="certificate" lazy="true">
		<id name="id">
			<generator class="uuid.hex">
			</generator>
		</id>
		<property name="describe" column="`describe`" type="string"/>
		<!-- unique表示此字段值唯一,它可将many-to-one改造成one-to-one -->
		<many-to-one name="stu" class="com.hibernate.model.Student" unique="true" column="stu_id"/>
	</class>
</hibernate-mapping>

 

Hibernate多对多映射

 假设有学生(student)和课程(course)的多对多映射。它们使用一张关联表(student_course)来保存关联关系。

建表脚本

 

create table course(
    id varchar(32) not null default'',
    name varchar(20),
    primary key(id)
)

create table student(
    id varchar(32) not null default'',
    cardId varchar(20),
    name varchar(20),
    age int(20)
)
--学生与课程关联表
create table student_course(
    student_id varchar(32) not null default'',
    course_id varchar(32) not null default''
)

 

Student.java

package com.hibernate.model;

import java.util.HashSet;
import java.util.Set;

public class Student {
	private String id; //标识ID
	private String cardId;//学号
	private String name;//姓名
	private int age; //年龄 
	private Set courses = new HashSet();//课程
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getCardId() {
		return cardId;
	}
	public void setCardId(String cardId) {
		this.cardId = cardId;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Set getCourses() {
		return courses;
	}
	public void setCourses(Set courses) {
		this.courses = courses;
	}
}

 

Course.java

package com.hibernate.model;

import java.util.HashSet;
import java.util.Set;

public class Course {
	private String id;
	private String name;
	private Set students = new HashSet();

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Set getStudents() {
		return students;
	}

	public void setStudents(Set students) {
		this.students = students;
	}

	
}

 

Student.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC    
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.hibernate.model.Student" table="student">
		<id name="id" unsaved-value="null">
			<generator class="uuid.hex"/>
		</id>
		<property name="cardId" type="string"/><!-- 没有指定 column,则列名和属性名是一样的 -->
		<property name="name" type="string"/>
		<property name="age" type="int"/>
		<set name="courses" table="student_course" cascade="none" inverse="true">
			<!--下面这两个column都是对应关联表中的字段-->
			<key column="student_id"/>
			<many-to-many class="com.hibernate.model.Course" column="course_id"/>
		</set>
	</class>
</hibernate-mapping>

 

Course.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC    
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
	<class name="com.hibernate.model.Course" table="course">
		<id name="id">
			<generator class="uuid.hex"/>
		</id>
		<property name="name" type="string"/>
		<set name="students" table="student_course" cascade="save-update">
			<key column="course_id"/>
			<many-to-many class="com.hibernate.model.Student" column="student_id"/>
		</set>
	</class>
</hibernate-mapping>

 

测试类

package com.hibernate.util;

import org.hibernate.Session;
import org.hibernate.Transaction;
import com.hibernate.model.Course;
import com.hibernate.model.Student;

public class BM {
	public static void main(String[] args) {
		saveStudentCourse();
	}
	public static void saveStudentCourse(){
		Session session = HibernateUtil.currentSession();
		Student student = null;
		Course course = null;
		Transaction tx = null;
		try{
			tx = session.beginTransaction();
			student = (Student) session.createQuery("from Student s where s.name='hp'").uniqueResult();
			course = (Course) session.createQuery("from Course s where s.name='English'").uniqueResult();
			student.getCourses().add(course);
			course.getStudents().add(student);
			tx.commit();
		}catch (Exception e) {
			e.printStackTrace();
		}finally{
			HibernateUtil.closeSession(session);
		}
	}
}

 

运行后,会自动在Student_Course表中保存关联数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值