hibernate学习四(关系映射一对一与组件映射)
一、关系映射简介
在数据库中,表与表的关系,仅有外键。但使用hibernate后,为面向对象的编程,对象与对象的关系多样化;如 一对一,一对多,多对多,并具有单向和双向之分。
开始练习前,复制上一次项目,并更名为
二、一对一单向外键关联
例如:一个老师只教一个学生,一个学生只能被一个老师教
关系图如:
修改teahcer.java和student.java类(为了简单起见吧Student也更改为使用Annotation的形式)
1 package com.model; 2 3 import javax.persistence.Column; 4 import javax.persistence.Entity; 5 import javax.persistence.GeneratedValue; 6 import javax.persistence.Id; 7 import javax.persistence.Table; 8 9 @Entity 10 @Table(name="teacher") 11 public class Teacher { 12 private int id; 13 private String name; 14 private int age; 15 private String title; 16 17 @Id 18 @GeneratedValue 19 public int getId() { 20 return id; 21 } 22 public void setId(int id) { 23 this.id = id; 24 } 25 public String getName() { 26 return name; 27 } 28 public void setName(String name) { 29 this.name = name; 30 } 31 public int getAge() { 32 return age; 33 } 34 public void setAge(int age) { 35 this.age = age; 36 } 37 public String getTitle() { 38 return title; 39 } 40 public void setTitle(String title) { 41 this.title = title; 42 } 43 }
接着删除数据库里的teahcer和student表,在hibernate.cfg.xml的配置文件里,有一条
1 <property name="hbm2ddl.auto">update</property>
参数为update时,会在第一次运行时检查是否有表结构,没有则自动生成。我让hibernate自动生成表,看看一对一单向关联的表结构是怎样的。
运行测试。
1 public class Main { 2 public static void main(String[] args) { 3 //通过util类创建sessionFactory 4 SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); 5 sessionFactory.close(); 6 } 7 }
三、结果展示
结果为在student表中出现了一个外键,依赖teacher的主键id,而teacher中并没有外键;
四、一对一双向外键关联
忽略关系图;
修改teacher.java,添加属性
private Student student; @OneToOne public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; }
删除表,并运行测试;
结果展示:
两张表都生成了一个外键,并依赖另一张表的主键id;
为了不创建两个外键(效果重复。。。),在其中一个@OneToOne上设置(mappedBy);
例如在student.java上设置;
@OneToOne(mappedBy="student")
mappedBy="student" 中student为teacher里的student属性;
测试运行后,结果只有teacher表中有外键,student表里没有;
PS:建议只要有双向关联,一定要设置mappedBy;
PSS:主键关联忽略,使用时现查现用;
五、组件映射
将一个普通的类作为一个实体类的一部分,里面的属性作为实体类的表里的字段,叫做组件映射;
先将teacher.java类里的Annotation删除,并删除id属性,为了避免字段名重复错误,把teacher类里的name和age属性改为teacherName和teacherAge;
1 package com.model; 2 3 public class Teacher { 4 private String teacherName; 5 private int teacherAge; 6 private String title; 7 8 public String getTeacherName() { 9 return teacherName; 10 } 11 public void setTeacherName(String teacherName) { 12 this.teacherName = teacherName; 13 } 14 public int getTeacherAge() { 15 return teacherAge; 16 } 17 public void setTeacherAge(int teacherAge) { 18 this.teacherAge = teacherAge; 19 } 20 public String getTitle() { 21 return title; 22 } 23 public void setTitle(String title) { 24 this.title = title; 25 } 26 }
修改student.java;
1 package com.model; 2 3 import javax.persistence.Embedded; 4 import javax.persistence.Entity; 5 import javax.persistence.GeneratedValue; 6 import javax.persistence.Id; 7 import javax.persistence.OneToOne; 8 import javax.persistence.Table; 9 10 @Entity 11 @Table(name="student") 12 public class Student { 13 private int id; 14 private String name; 15 private int age; 16 private Teacher teacher; 17 18 @Id 19 @GeneratedValue 20 public int getId() { 21 return id; 22 } 23 public void setId(int id) { 24 this.id = id; 25 } 26 public String getName() { 27 return name; 28 } 29 public void setName(String name) { 30 this.name = name; 31 } 32 public int getAge() { 33 return age; 34 } 35 public void setAge(int age) { 36 this.age = age; 37 } 38 @Embedded 39 public Teacher getTeacher() { 40 return teacher; 41 } 42 public void setTeacher(Teacher teacher) { 43 this.teacher = teacher; 44 } 45 46 }
运行测试;
没有teacher这张表,student表里多了三个字段;
PS:一对一单向外键关联与一对一双向外键关联在数据库的表的格式是一样的,区别在于
java程序中. 双向外键关联可通过Hibernate在两个类间互相调用彼此,而单向外键关联只能单方向调用。
----------------------------------------------------------------------------------------------------
此文为个人学习记录,如有参考转载,请注明出处 黑白熊的博客 http://www.cnblogs.com/xiong233/