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 {

    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;
    }
}

运行结果:

时间: 2024-10-14 00:24:37

hibernate(六)一对一映射的相关文章

9.hibernate的一对一映射

一.hibernate的一对一按照外键映射 1.创建如下sql脚本: 1 --员工账号表 2 create table USERS1 3 ( 4 USERID NUMBER(6) not null, 5 USERNAME VARCHAR2(20), 6 USERPASS VARCHAR2(20) 7 ) 8 ; 9 10 11 12 --档案表 13 create table RESUME1 14 ( 15 RESID NUMBER(6) not null, 16 RESUSERID NUMBE

Hibernate的一对一映射

一.创建Java工程,新建Lib文件夹,加入Hibernate和数据库(如MySql.Oracle.SqlServer等)的Jar包,创建 hibernate.cfg.xml 文件,并配置,配置项如下: 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-configuration PUBLIC 3 "-//Hibernate/Hibernate Configura

Hibernate(七)一对一映射

一.创建数据库表 --班级表 create table grade ( gid number primary key, --班级ID gname varchar2(50), --班级名称 gdesc varchar2(50) --班级介绍 ); --学生表 create table student ( sid number primary key, --主键ID学生ID sname varchar2(20), --学生姓名 sex varchar2(20), --学生性别 gid number

(12)Hibernate一对一映射

只要你肯努力,没有什么事情是你不能搞砸的. 需求:一个汽车(Car)有一个引擎(Engine),它是一对一的映射关系. 对于一对一的映射,有两种实现方式:基于外键的映射和基于主键的映射.这两种方式学习的重点就是映射文件的配置,推荐使用第一种方式. 1.基于外键的映射 Car.java package com.rk.hibernate.k_one2one; public class Car { private int carId; private String carName; private E

hibernate的实体映射(一对一)

Hibernate的实体映射的主要任务就是实现数据库关系表与持久化类之间的映射,其关系如图: 双向映射一对一关联关系,通过唯一外键方式进行一对一关联映射,就是一个表的外键和另一个表的唯一主键对应形成一对一映射关系. 例如,以下例子,社团与社团负责人(社长),两者之间是一对一的关联关系: 持久化类association.java: public class Association implements java.io.Serializable{     private Integer id;   

【Hibernate步步为营】--单向关联一对一映射(一)

上篇文章对多对一的关联映射做了详细的分析,它在实现上可以有两种方式,并且这两种方式实现也很简单,关键是标签<many-to-one>的使用,它分别指明了多端和一端的映射关系,这种映射关系既是对象模型中的聚合关系.接下来继续讨论关联映射. 一.唯一外键 唯一外键说的是数据库表中的每一行的外键唯一对应着另一张表中的主键,也就是说一个表的主键作为另一张表的外键,并且它们之间的关系是唯一的,这种反应到关系模型中如下图所示: 上图的两个实体表,分别为人和身份证,很明显的一个人对应着一个身份证.身份证作为

hibernate笔记--基于主键的单(双)向的一对一映射关系

上一节介绍的基于外键的一对一映射关系中,在Person表中有一个外键列idCard_id,对应的idCard表的主键id,至于基于主键的一对一映射关系,就是指Person表中抛弃了idcard_id这个外键列,而与idCard表共用一个主键,或者说是其外键为主键的表结构,这种基于主键的双向一对一映射关系应该这样配置: 新建一个IdCard实体类: public class IdCard { private int id; private String code; private Person p

【Hibernate步步为营】--双向关联一对一映射具体解释(一)

一对一的映射在对象模型中是常常见到的,为了将对象模型转换为关系模型就必须在映射文件里进行配置,上篇文章讨论了一对一映射的单向关联的情况,重点是<one-to-one>标签的使用,须要在映射的主对象中加入该标签,并将该对象的主键设置为foreign这样就实现了主键关联映射.讨论完了单向接下来讨论双向映射. 一.双向主键关联 双向的主键关联事实上是单向一对一主键关联的一种特殊情况.仅仅只是要在关联对象的两端的映射文件里都要进行<one-to-one>的配置.另外还要在主映射的主键一端採

【Hibernate步步为营】--双向关联一对一映射详解(二)

很不好意思,有两天时间没有更新博客文章了,不写文章的日子还真是感觉很空洞啊,养成了写文章的恶习想改也改不掉啊.说点题外话,前两天收到一位朋友的私信,邀请笔者写一篇有关OWS的文章,用来研究图标工具的一种技术,很荣幸收到这位朋友的邀请,但是因为这几天开发的项目着急上线所以暂时没有时间去研究,只能等这周末了,利用周末的时间来研究然后更新类似的技术文章. 回到文章的正题,上篇文章讨论了双向主键关联,它其实是一对一主键关联的一种特殊情况,想要实现双向的关联就必须在映射文件的两端同时配置<one-to-o

java框架篇---hibernate(一对一)映射关系

对象-关系映射(Object/Relation Mapping,简称ORM),是随着面向对象的软件开发方法发展而产生的,是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术,本质上就是将数据从一种形式转换到另外一种形式. 面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统.对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据.内存中的对象之间存在关联和继承关系,而在数据库中,关系数