1 多对一,从多的一方来看,即从多的一方修改配置文件。
案例:多个学生对于与一个年级。
一的一方,年级实体类:
public class Grade {
private int id;
private String name;
}
实体与表字段映射:
<class name="Grade">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"/>
</class>
多的一方,学生实体类:
public class Student {
private int id;
private String name;
private int age;
private Grade grade;
}
说明:学生实体包含年级类引用。
实体与表字段映射:
<class name="Student">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"/>
<property name="age"/>
<!-- 多对一 name表示当前类中的属性名,class指明属性对应的类, column指表中被设置为外键的列名,
指向Grade类中的Id,foreign-key:为外键设置一个名称-->
<many-to-one name="grade" class="Grade"
column="grade_id" foreign-key="fk_grade"/>
</class>
测试–创建表:
public static void testCreateDB(){
Configuration cfg=new Configuration().configure();
SchemaExport se=new SchemaExport(cfg);
//第一个参数:是否生成脚本。第二个是否真正生成到数据库中
se.create(true,true);
}
控制台显示的创建表的SQL语句:
create table Grade (
id integer not null auto_increment,
name varchar(255),
primary key (id)
)
create table Student (
id integer not null auto_increment,
name varchar(255),
age integer,
grade_id integer,
primary key (id)
)
alter table Student
add constraint fk_grade
foreign key (grade_id)
references Grade (id)
由SQL可知,外键创建将Student 的grade_id指向Grade 的id
测试–插入数据:
public static void testSave(){
Session session=null;
Transaction tx=null;
try{
session=HibernateUtil.getSession();
tx=session.beginTransaction();
//先插入一对多的一方
Grade grade=new Grade();
grade.setName("基础");
session.save(grade);
//一对多的多方
Student student=new Student();
student.setName("张三风");
student.setAge(22);
//通过设置多方,外键grade_id因为与Grade表绑定,grade_id将等于Grade对像中的id。
student.setGrade(grade);
session.save(student);
tx.commit();
}catch(Exception e){
if(tx!=null){
tx.rollback();
}
e.printStackTrace();
}finally{
HibernateUtil.closeSession();
}
}
2 一对多,从一的一方来看,即从一的一方修改配置文件。
实体类多的一方:
public class Student {
private int id;
private String name;
private int age;
}
<class name="Student">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"/>
<property name="age"/>
</class>
实体类一的一方:
public class Grade {
private int id;
private String name;
private Set<Student> students=new HashSet<Student>(0);
}
<class name="Grade">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"/>
<!-- set是Grade中的集合属性,name属性名称 -->
<set name="students">
<!-- key表示外键 列名,表示多的一方中的外键列名,
在Student的映射文件中没有这个列名说明
此处说明Student实体类中外键指向Grade的主键-->
<key column="grade_id"></key>
<!-- one to many 表示一对多 类Grade中 students所表示类型-->
<one-to-many class="Student"/>
</set>
</class>
说明:在一的一方中添加创建一方表中的外键的说明,在实体类中添加Set集合包存储该年级的学生。通过配置文件来绑定。
测试–创建表:可查看上中的java代码。
输出创建表的SQL语句:
create table Grade (
id integer not null auto_increment,
name varchar(255),
primary key (id)
)
create table Student (
id integer not null auto_increment,
name varchar(255),
age integer,
grade_id integer,
primary key (id)
)
alter table Student
add constraint FK_e31ahrkopu13kfn999qyrsltm
foreign key (grade_id)
references Grade (id)
保存数据后:
测试–保存数据:
public static void testSave(){
Session session=null;
Transaction tx=null;
try{
session=HibernateUtil.getSession();
tx=session.beginTransaction();
//定义一个年级
Grade grade=new Grade();
grade.setName("基础");
//创建两个学生
Student student01=new Student();
student01.setName("student01");
student01.setAge(22);
Student student02=new Student();
student02.setName("student02");
student02.setAge(22);
//将多个学生添加到年级中
grade.getStudents().add(student01);
grade.getStudents().add(student02);
//保存
session.save(grade);
session.save(student01);
session.save(student02);
tx.commit();
}catch(Exception e){
if(tx!=null){
tx.rollback();
}
e.printStackTrace();
}finally{
HibernateUtil.closeSession();
}
}
说明:先创建年级,然后创建学生,添加到年级的学生集合中,先保存年级,再保存学生数据。
测试–查询:
public static void query(){
Session session=null;
Transaction tx=null;
try{
session=HibernateUtil.getSession();
tx=session.beginTransaction();
Grade grade=(Grade)session.get(Grade.class, 1);
for ( Student stu: grade.getStudents()) {
System.out.println(stu.getName());
}
tx.commit();
}catch(Exception e){
if(tx!=null){
tx.rollback();
}
e.printStackTrace();
}finally{
HibernateUtil.closeSession();
}
}