你的位置:首页 > Java教程

[Java教程]hibernate(六)一对一映射


关系映射是指对象之间的关系,并不是指数据库的关系,关系映射是解决当对象处于以下关系之一时,数据库表该如何映射的问题

(一)一对一单向外键关联

1、注解方式配置

创建一个Husband类和Wife类

Husband类:(getWife方法上加注解OneToOne)

package cn.orlion.hibernate.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.OneToOne;@Entitypublic class Husband {    private int id;    private String name;    private Wife wife;    @Id  @GeneratedValue  public int getId() {    return id;  }  public void setId(int id) {    this.id = id;  }  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  @OneToOne
  @JoinColumn(name="wifeId")//默认生成的外键id是wife_id在这里使用JoinColumn注解name属性指定为wifeId public Wife getWife() { return wife; } public void setWife(Wife wife) { this.wife = wife; }}

Wife类

package cn.orlion.hibernate.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;@Entitypublic class Wife {  private int id;    private String name;    @Id  @GeneratedValue  public int getId() {    return id;  }  public void setId(int id) {    this.id = id;  }  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }}

然后创建一个测试类HibernateMappingTest

package cn.orlion.hibernate.model;import org.hibernate.cfg.AnnotationConfiguration;import org.hibernate.tool.hbm2ddl.SchemaExport;import org.junit.Test;public class HibernateORMappingTest {  @Test  public void testSchemaExport(){        new SchemaExport(new AnnotationConfiguration().configure()).create(true , true);  }}

运行testSchemaExport可以在控制台看到建表语句:

 

2、

首先创建一个Student类和StuIdCard(学生证)

Student类:

package cn.orlion.hibernate.model;public class Student {  private int id;    private String name;    private String sex;  public int getId() {    return id;  }  public void setId(int id) {    this.id = id;  }  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  public String getSex() {    return sex;  }  public void setSex(String sex) {    this.sex = sex;  }}

StuIdCard:

package cn.orlion.hibernate.model;public class StuIdCard {  private int id;    private int num;    private Student student;  public int getId() {    return id;  }  public void setId(int id) {    this.id = id;  }  public int getNum() {    return num;  }  public void setNum(int num) {    this.num = num;  }  public Student getStudent() {    return student;  }  public void setStudent(Student student) {    this.student = student;  }}

然后创建两个配置文件Student.hbm.

<??><!DOCTYPE hibernate-mapping PUBLIC    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="cn.orlion.hibernate.model">  <class name="cn.orlion.hibernate.model.Student">    <id name="id">      <generator class="native"></generator>    </id>        <property name="name"></property>        <property name="sex"></property>  </class></hibernate-mapping>

StuIdCard.hbm.

<??><!DOCTYPE hibernate-mapping PUBLIC    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="cn.orlion.hibernate.model">  <class name="cn.orlion.hibernate.model.StuIdCard">    <id name="id">      <generator class="native"></generator>    </id>        <property name="num" />        <many-to-one name="student" column="studentId" unique="true"></many-to-one>    <!-- many-to-one是当前类即StuIdCard类相对于Student类是多对一关系 (多个学生证对应一个学生) ,unique=true限定为了一对一 -->  </class></hibernate-mapping>

然后运行测试类HibernateORMappingTest类的testSchemaExport方法可以在控制台看到建表语句:

(二)一对一双向外键关联

1、注解方式设置

双向外键关联注解方式设置是在wife类中添加husband属性,在getHusband()方法上添加注解@OneToOne(mappedBy="wife")//mappedBy="wife"表示Husband中wife属性已经做映射了,不用管当前类的设置(不再从wife表中生成指向husband的外键)注:如果不写mappedBy="wife"会在wife表中生成一个husband_id外键,这是多余的。

Wife类:

package cn.orlion.hibernate.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.OneToOne;@Entitypublic class Wife {  private int id;    private String name;    private Husband husband;    @Id  @GeneratedValue  public int getId() {    return id;  }  public void setId(int id) {    this.id = id;  }  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  @OneToOne(mappedBy="wife")//mappedBy="wife"表示Husband中wife属性已经做映射了,不用管当前类的设置(不再从wife表中生成指向husband的外键)  public Husband getHusband() {    return husband;  }  public void setHusband(Husband husband) {    this.husband = husband;  }  }

2、
在Student.hbm.

Student类:

package cn.orlion.hibernate.model;public class Student {  private int id;    private String name;    private String sex;    private StuIdCard stuIdCard;  public int getId() {    return id;  }  public void setId(int id) {    this.id = id;  }  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  public String getSex() {    return sex;  }  public void setSex(String sex) {    this.sex = sex;  }  public StuIdCard getStuIdCard() {    return stuIdCard;  }  public void setStuIdCard(StuIdCard stuIdCard) {    this.stuIdCard = stuIdCard;  }  }

Student.hbm.

<??><!DOCTYPE hibernate-mapping PUBLIC    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="cn.orlion.hibernate.model">  <class name="cn.orlion.hibernate.model.Student">    <id name="id">      <generator class="native"></generator>    </id>        <property name="name"></property>        <property name="sex"></property>        <one-to-one name="stuIdCard" property-ref="student"></one-to-one>    <!-- one-to-one只会在一边生成主键,如果这里设置为many-to-one会在student表中生成多余的stuidcard_id外键 -->    <!-- property-ref="student" 类似于mappedby="student"是指在StuIdCard中student属性已经设置好了关联关系 -->  </class></hibernate-mapping>

注:一对一单向和双向在数据库中表现没有区别

 

主键关联是指的一个表的主键和另外一个表的主键关联
外键关联是指的一个表的主键和另外一个表的非主键关联

 

(三)一对一单向主键关联

创建Student类

package cn.orlion.hibernate.model;public class Student {  private int id;    private String name;    private String sex;  public int getId() {    return id;  }  public void setId(int id) {    this.id = id;  }  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  public String getSex() {    return sex;  }  public void setSex(String sex) {    this.sex = sex;  }}

StuIdCard类:

package cn.orlion.hibernate.model;public class StuIdCard {  private int id;    private int num;    private Student student;  public int getId() {    return id;  }  public void setId(int id) {    this.id = id;  }  public int getNum() {    return num;  }  public void setNum(int num) {    this.num = num;  }  public Student getStudent() {    return student;  }  public void setStudent(Student student) {    this.student = student;  }}

Student.hbm.

<??><!DOCTYPE hibernate-mapping PUBLIC    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="cn.orlion.hibernate.model">  <class name="cn.orlion.hibernate.model.Student">    <id name="id">      <generator class="native"></generator>    </id>        <property name="name"></property>        <property name="sex"></property>  </class></hibernate-mapping>

StuIdCard.hbm.

<??><!DOCTYPE hibernate-mapping PUBLIC    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="cn.orlion.hibernate.model">  <class name="cn.orlion.hibernate.model.StuIdCard">    <id name="id">      <generator class="foreign"><!-- StuIdCard的主键应该靠外键来生成,StuIdCard -->        <param name="property">student</param><!-- 依靠student属性的关联关系 -->      </generator>    </id>        <property name="num" />        <one-to-one name="student" constrained="true"></one-to-one>    <!-- constrained="true"用来生成外键约束,不加这个属性就不会加外键 -->  </class></hibernate-mapping>

 

运行:

(四)一对一双向主键关联

注解方式配置:

Husband类:

package cn.orlion.hibernate.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.OneToOne;import javax.persistence.PrimaryKeyJoinColumn;@Entitypublic class Husband {    private int id;    private String name;    private Wife wife;    @Id  @GeneratedValue  public int getId() {    return id;  }  public void setId(int id) {    this.id = id;  }  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  @OneToOne  @PrimaryKeyJoinColumn  public Wife getWife() {    return wife;  }  public void setWife(Wife wife) {    this.wife = wife;  }}

 

Wife类:

package cn.orlion.hibernate.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.OneToOne;@Entitypublic class Wife {  private int id;    private String name;    private Husband husband;    @Id  @GeneratedValue  public int getId() {    return id;  }  public void setId(int id) {    this.id = id;  }  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  @OneToOne  @PrimaryKeyJoinColumn
   public Husband getHusband() { return husband; } public void setHusband(Husband husband) { this.husband = husband; } }

 

(五)联合主键映射

Wife类:

package cn.orlion.hibernate.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.IdClass;@Entity@IdClass(WifePK.class)public class Wife {  private int id;    private String name;    private String age;    @Id  public int getId() {    return id;  }  public void setId(int id) {    this.id = id;  }  @Id  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  public String getAge() {    return age;  }  public void setAge(String age) {    this.age = age;  }  }

WifePK:

package cn.orlion.hibernate.model;public class WifePK {  private int id;    private String name;    public int getId() {    return id;  }  public void setId(int id) {    this.id = id;  }  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }}

Husband类:

package cn.orlion.hibernate.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinColumns;import javax.persistence.OneToOne;@Entitypublic class Husband {    private int id;    private String name;    private Wife wife;    @Id  @GeneratedValue  public int getId() {    return id;  }  public void setId(int id) {    this.id = id;  }  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  @OneToOne  @JoinColumns(    {      @JoinColumn(name="wifeId" , referencedColumnName="id"),      @JoinColumn(name="wifeName" , referencedColumnName="name")    }    )  public Wife getWife() {    return wife;  }  public void setWife(Wife wife) {    this.wife = wife;  }}

运行结果: