看完多对一,再来看看一对一的情况:
学生和证件是一对一的关系,并且学生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表中保存关联数据。