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;

@Entity
public 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;

@Entity
public 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、xml方式配置

首先创建一个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.xml:

<?xml version="1.0"?>
<!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.xml:

<?xml version="1.0"?>
<!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;

@Entity
public 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、xml方式配置
在Student.hbm.xml配置文件中添加<one-to-one name="stuIdCard" property-ref="student"></one-to-one>,在Student类中添加stuIdCard属性:

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.xml:

<?xml version="1.0"?>
<!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>

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

 

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

 

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

xml方式配置:

创建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.xml:

<?xml version="1.0"?>
<!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.xml:

<?xml version="1.0"?>
<!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;

@Entity
public 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;

@Entity
public 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 implements java.io.Serializable{

    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;

@Entity
public 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;
    }
}

运行结果:

posted @ 2015-12-21 22:56  orlion  阅读(1340)  评论(0编辑  收藏  举报