Hibernate框架-1对1关联

来源:互联网 发布:p4vasp windows 编辑:程序博客网 时间:2024/06/01 10:06

Hibernate单向1-1关联

对于单向的1-1关联,需要在实体类中增加相对应关联实体的属性(关联实体对象)

基于外键的单向1-1关联

Annotation方式

无连接表的单向1-1关联

首先使用@OneToOne注解代表关联实体的属性,再使用@JoinColumn映射外键即可
例:Husband类中设置了对应的Wife类对象,并为之增加@OneToOne和@JoinColumn注解,其中unique=true保证了wife_id字段的唯一性

import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinTable;import javax.persistence.OneToOne;/** * @author msidolphin * @time   2017年6月3日 */@Entitypublic class Husband {    private int id;    private String name;    private Wife wife;    @Id    @GeneratedValue    public int getId() {        return id;    }    @Column(length = 50)    public String getName() {        return name;    }    @OneToOne    @JoinColumn(name="wife_id", unique=true)     public Wife getWife() {        return wife;    }    public void setId(int id) {        this.id = id;    }    public void setName(String name) {        this.name = name;    }    public void setWife(Wife wife) {        this.wife = wife;    }}

由于是单向1-1,所有Wife类中没有设置Husband对象

import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;/** * @author msidolphin * @time   2017年6月3日 */@Entitypublic class Wife {    private int id;    private String name;    @Id    @GeneratedValue    public int getId() {        return id;    }    @Column(length = 50)    public String getName() {        return name;    }    public void setId(int id) {        this.id = id;    }    public void setName(String name) {        this.name = name;    }}

测试类:

import org.hibernate.cfg.Configuration;import org.hibernate.tool.hbm2ddl.SchemaExport;import org.junit.Test;/** * @author msidolphin * @time   2017年6月3日 */public class DomainJunit {    @Test    public void schemaExport_() {        new SchemaExport(new Configuration().configure()).create(false, true);    }}

控制台日志输出的SQL语句
这里写图片描述

有连接表的单向1-1关联

有连接表的单向1-1关联需要使用@JoinTable注解映射连接表,由于是1-1关联,因此需要为@JoinTable注解中的joinColumns属性映射的外键字段设置unique=true属性,以此保证严格的1-1关联
Husband类:

import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinTable;import javax.persistence.OneToOne;/** * @author msidolphin * @time   2017年6月3日 */@Entitypublic class Husband {    private int id;    private String name;    private Wife wife;    @Id    @GeneratedValue    public int getId() {        return id;    }    @Column(length = 50)    public String getName() {        return name;    }    @OneToOne    @JoinColumn(name="wife_id", unique=true)     @JoinTable(            name="husband_wife", //表名            joinColumns=@JoinColumn(                    name="husband_id",                     unique=true,                     referencedColumnName="id"            ),            inverseJoinColumns=@JoinColumn(                    name="wife_id",                    unique=true,                    referencedColumnName="id"            )    )    public Wife getWife() {        return wife;    }    public void setId(int id) {        this.id = id;    }    public void setName(String name) {        this.name = name;    }    public void setWife(Wife wife) {        this.wife = wife;    }}

Wife类无需改动,同上

控制台输出的sql语句:
这里写图片描述

XML方式

使用<many-to-one>标签设置关联实体属性,由于是1-1,所以unique属性要设置为true
husband.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="pers.msidolphin.hibernate.one2one">    <class name="Husband" table="husband">        <id name="id" column="id">            <generator class="native"></generator>        </id>        <property name="name" column="name" length="50"/>        <many-to-one name="wife" column="wife_id" unique="true"></many-to-one>    </class></hibernate-mapping>

wife.hbm.xml文件

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="pers.msidolphin.hibernate.one2one">    <class name="Wife" table="wife">        <id name="id" column="id">            <generator class="native"></generator>        </id>        <property name="name" column="name" length="50"></property>    </class></hibernate-mapping>

Hibernate双向1-1关联

双向1-1关联需要在两个实体类中都增加引用关联实体的属性

基于外键的双向1-1关联

Annotation方式

无连接表的双向1-1关联

两端都需要为关联实体属性增加@OneToOne注解,对于基于外键的双向1-1关联,外键可以存放在任意一端,存放外键的一端,需要增加@JoinColumn注解映射外键字段,当选择一方增加外键后,该表即变为从表,而另一张表则为主表,主表对应的实体使用@OneToOne注解时,应增加mappedBy属性,表示该表作为主表使用,不增加对应从表的外键(这么做是为了防止修改从表时需要更新对应的主表字段,导致生成额外的update语句,引起性能下降)
例:
Husband类:husband表作为主表

import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.OneToOne;/** * @author msidolphin * @time   2017年6月3日 */@Entitypublic class Husband {    private int id;    private String name;    private Wife wife;    @Id    @GeneratedValue    public int getId() {        return id;    }    @Column(length = 50)    public String getName() {        return name;    }    @OneToOne(mappedBy="husband")    public Wife getWife() {        return wife;    }    public void setId(int id) {        this.id = id;    }    public void setName(String name) {        this.name = name;    }    public void setWife(Wife wife) {        this.wife = wife;    }}

Wife类:

import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.OneToOne;/** * @author msidolphin * @time   2017年6月3日 */@Entitypublic class Wife {    private int id;    private String name;    private Husband husband;    @Id    @GeneratedValue    public int getId() {        return id;    }    @Column(length = 50)    public String getName() {        return name;    }    @OneToOne    @JoinColumn(            name="husband_id",             unique=true    )     public Husband getHusband() {        return husband;    }    public void setId(int id) {        this.id = id;    }    public void setName(String name) {        this.name = name;    }    public void setHusband(Husband husband) {        this.husband = husband;    }}

结果:
这里写图片描述

有连接表的双向1-1关联

有连接表的双向1-1关联需要在两端都使用@JoinTable映射连接表,在映射连接表时,两端指定的连接表的表名应当相同,字段名当然也要一致
Husband类:

import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinTable;import javax.persistence.OneToOne;/** * @author msidolphin * @time   2017年6月3日 */@Entitypublic class Husband {    private int id;    private String name;    private Wife wife;    @Id    @GeneratedValue    public int getId() {        return id;    }    @Column(length = 50)    public String getName() {        return name;    }    @OneToOne    @JoinTable(            name="husband_wife", //表名            joinColumns=@JoinColumn(                    name="husband_id",                     unique=true,                     referencedColumnName="id"            ),            inverseJoinColumns=@JoinColumn(                    name="wife_id",                    unique=true,                    referencedColumnName="id"            )    )    public Wife getWife() {        return wife;    }    public void setId(int id) {        this.id = id;    }    public void setName(String name) {        this.name = name;    }    public void setWife(Wife wife) {        this.wife = wife;    }}

Wife类:

import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinTable;import javax.persistence.OneToOne;/** * @author msidolphin * @time   2017年6月3日 */@Entitypublic class Wife {    private int id;    private String name;    private Husband husband;    @Id    @GeneratedValue    public int getId() {        return id;    }    @Column(length = 50)    public String getName() {        return name;    }    @OneToOne    @JoinTable(            name="husband_wife", //表名            joinColumns=@JoinColumn(                    name="wife_id",                     unique=true,                     referencedColumnName="id"            ),            inverseJoinColumns=@JoinColumn(                    name="husband_id",                    unique=true,                    referencedColumnName="id"            )    )    public Husband getHusband() {        return husband;    }    public void setId(int id) {        this.id = id;    }    public void setName(String name) {        this.name = name;    }    public void setHusband(Husband husband) {        this.husband = husband;    }}

结果:
这里写图片描述

XML方式

husband.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="pers.msidolphin.hibernate.one2one">    <class name="Husband" table="husband">        <id name="id" column="id">            <generator class="native"></generator>        </id>        <property name="name" column="name" length="50"/>        <many-to-one name="wife" column="wife_id" unique="true"></many-to-one>    </class></hibernate-mapping>

wife.hbm.xml文件
注:这里使用的是<one-to-one>标签,如果使用<many-to-one>标签,则在两张表中都会生成外键字段

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="pers.msidolphin.hibernate.one2one">    <class name="Wife" table="wife">        <id name="id" column="id">            <generator class="native"></generator>        </id>        <property name="name" column="name" length="50"></property>        <one-to-one name="husband"></one-to-one>    </class></hibernate-mapping>

Hibernate联合主键关联

Annotation方式

Wife类:id和name字段作为联合主键

import java.io.Serializable;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.Id;/** * @author msidolphin * @time   2017年6月3日 */@Entitypublic class Wife implements Serializable{    private static final long serialVersionUID = 1L;    private int id;    private String name;    @Id    public int getId() {        return id;    }    @Id    @Column(length = 50)    public String getName() {        return name;    }    public void setId(int id) {        this.id = id;    }    public void setName(String name) {        this.name = name;    }    @Override    public boolean equals(Object obj) {        if(obj == null) {            return false;        }        if(obj instanceof Wife) {            Wife pk = (Wife) obj;            if(this.id == pk.getId() && this.name.equals(pk.getName())) {                return true;            }            return false;        }        return false;    }    @Override    public int hashCode() {        return this.name.hashCode();    }}

Husband类:

import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.JoinColumns;import javax.persistence.OneToOne;/** * @author msidolphin * @time   2017年6月3日 */@Entitypublic class Husband {    private int id;    private String name;    private Wife wife;    @Id    @GeneratedValue    public int getId() {        return id;    }    @Column(length = 50)    public String getName() {        return name;    }    @OneToOne    @JoinColumns({        @JoinColumn(name="wife_id", referencedColumnName="id", unique=true),        @JoinColumn(name="wife_name", referencedColumnName="name", unique=true)    })    public Wife getWife() {        return wife;    }    public void setId(int id) {        this.id = id;    }    public void setName(String name) {        this.name = name;    }    public void setWife(Wife wife) {        this.wife = wife;    }}

控制台打印的SQL建表语句:
这里写图片描述

XML方式

主键类: Wife表的id和name字段作为联合主键

import java.io.Serializable;/** * @author msidolphin * @time   2017年6月3日 */public class WifePk implements Serializable{    private static final long serialVersionUID = 1L;    private int id;    private String name;    public int getId() {        return id;    }    public String getName() {        return name;    }    public void setId(int id) {        this.id = id;    }    public void setName(String name) {        this.name = name;    }       @Override    public boolean equals(Object obj) {        if(obj == null) {            return false;        }        if(obj instanceof WifePk) {            WifePk pk = (WifePk) obj;            if(this.id == pk.getId() && this.name.equals(pk.getName())) {                return true;            }            return false;        }        return false;    }    @Override    public int hashCode() {        return this.name.hashCode();    }}

Wife类:

/** * @author msidolphin * @time   2017年6月3日 */public class Wife {    private WifePk pk;    public WifePk getPk() {        return pk;    }    public void setPk(WifePk pk) {        this.pk = pk;    }}

Husband类:

/** * @author msidolphin * @time   2017年6月3日 */public class Husband {    private int id;    private String name;    private Wife wife;    public int getId() {        return id;    }    public String getName() {        return name;    }    public Wife getWife() {        return wife;    }    public void setId(int id) {        this.id = id;    }    public void setName(String name) {        this.name = name;    }    public void setWife(Wife wife) {        this.wife = wife;    }}

wife.hbm.xml文件,由于使用了联合主键,所以应该使用<composite-id>标签

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-mapping PUBLIC        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="pers.msidolphin.hibernate.one2one">    <class name="Wife" table="wife">        <composite-id name="pk" class="pers.msidolphin.hibernate.one2one.WifePk">            <key-property name="id"></key-property>            <key-property name="name" length="50"></key-property>        </composite-id>    </class></hibernate-mapping>

husband.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="pers.msidolphin.hibernate.one2one">    <class name="Husband" table="husband">        <id name="id" column="id">            <generator class="native"></generator>        </id>        <property name="name" column="name" length="50"/>        <many-to-one name="wife">            <!-- 要格外注意顺序 -->            <column name="wife_id" unique="true"></column>              <column name="wife_name"  unique="true"></column>           </many-to-one>    </class></hibernate-mapping>

控制台打印的SQL建表语句:
这里写图片描述

阅读全文
0 0
原创粉丝点击