Hibernate@OneToOne关联映射的三种形式

来源:互联网 发布:mac查看目录结构 编辑:程序博客网 时间:2024/06/14 23:41

重点内容
在数据库中表与表之间的关系,我们通过引用外键使得它们关联起来,但在Hibernate面向对象编程中,我们如何使的两个持久化类关联起来?在这里我们使用的是JPA注解的方式。

单向一对一关联:需要在持久化类中添加代表关联关系实体的属性,并为该属性添加setter和getter方法。

(一)@OneToOne支持的属性

属性                   说明cascade:1.CascadeType.All:将所有持久化操作级联到关联使用         2.CascadeType.MERGE:将merge操作级联到关联实体         3.CascadeType.PERSIST:将persist操作级联到关联实体         4.CascadeType.REFRESH:将refresh操作级联到关联实体         5.CascadeType.REMOVE:将remove操作级联到关联实体fetch:   1.FetchType.EAGER:立即抓取关联实体         2.FetchType.LAZY:延迟抓取关联实体,需要它时再去抓取。orphanRemovel  1.设置是否删除“孤儿”实体  mappyBy  1.该属性指定关联实体中的哪个属性可以引用到当前实体。optional  1.该属性指定关联关系是否可选targetEntity 1.该属性指定关联实体的类名,通过反射获得关联实体类名

1.持久化类

package cn.codeWang.entity;import java.util.Date;import javax.persistence.CascadeType;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.OneToOne;import javax.persistence.Temporal;import javax.persistence.TemporalType;@Entitypublic class Students {    @Id    @GeneratedValue    private int sid;    private String sname;    private String gender;    @Temporal(TemporalType.DATE)    private Date birthday;    private String major;    @OneToOne(cascade=CascadeType.ALL)    @JoinColumn(name="pid",unique=true)    private IdCard card;    public Students() {    }    public String getSname() {        return sname;    }    public void setSname(String sname) {        this.sname = sname;    }    public IdCard getCard() {        return card;    }    public void setCard(IdCard card) {        this.card = card;    }    public Students(int sid, String sname, String gender, Date birthday, String major, IdCard card) {        super();        this.sid = sid;        this.sname = sname;        this.gender = gender;        this.birthday = birthday;        this.major = major;        this.card = card;    }    public int getSid() {        return sid;    }    public void setSid(int sid) {        this.sid = sid;    }    public String getGender() {        return gender;    }    public void setGender(String gender) {        this.gender = gender;    }    public Date getBirthday() {        return birthday;    }    public void setBirthday(Date birthday) {        this.birthday = birthday;    }    public String getMajor() {        return major;    }    public void setMajor(String major) {        this.major = major;    }}package cn.codeWang.entity;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import org.hibernate.annotations.GenericGenerator;@Entitypublic class IdCard {    @Id    //字符串作为主键的处理方法    @GeneratedValue(generator="pid")    @GenericGenerator(name="pid",strategy="assigned")    @Column(length=18)    private String pid;    private String sname;    public IdCard(){    }    public String getPid() {        return pid;    }    public void setPid(String pid) {        this.pid = pid;    }    public String getSname() {        return sname;    }    public void setSname(String sname) {        this.sname = sname;    }}

2.配置文件

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE hibernate-configuration PUBLIC        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration>    <session-factory>        <!-- 配置连接数据库 -->        <property name="connection.username">root</property>        <property name="connection.password">root</property>        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>        <property name="connection.url">jdbc:mysql:///hibernate?useUnicode=true&amp;characterEncoding=UTF-8</property>        <!-- 配置方言是非常重要!!!我这里配置的为MySQL5Dialect -->        <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>        <!-- 配置C3P0连接池 -->        <property name="hibernate.c3p0.max_size">200</property>        <property name="hibernate.c3p0.min_size">2</property>        <property name="hibernate.c3p0.max_statements">50</property>        <property name="hibernate.c3p0.timeout"></property>        <property name="show_sql">true</property>        <property name="format_sql">true</property>        <property name="hbm2ddl.auto">create</property>        <!-- 配置映射文件 -->       <!-- <property name="hibernate.current_session_context_class">thread</property>  -->          <mapping  class="cn.codeWang.entity.Students"/>        <mapping  class="cn.codeWang.entity.IdCard"/>    </session-factory></hibernate-configuration>

3.测试类

import java.util.Date;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.boot.MetadataSources;import org.hibernate.boot.registry.StandardServiceRegistryBuilder;import org.hibernate.service.ServiceRegistry;import org.junit.After;import org.junit.Before;import org.junit.Test;import cn.codeWang.entity.IdCard;import cn.codeWang.entity.Students;public class DemoTest {    private SessionFactory sessionFactory;    private Session session;    private Transaction transaction;    @Before    public void init() {        // 创建服务注册对象        ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build();        // 创建会话工厂对象        sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();        // 会话对象        session = sessionFactory.openSession();        // 开启事物        transaction = session.beginTransaction();    }    @After    public void destory() {        // 提交事物        transaction.commit();        // 关闭会话        session.close();        // 关闭会话工厂        sessionFactory.close();    }    @Test    // 向数据库中添加数据    public void testSave() {         IdCard card=new IdCard();        card.setPid("123456789");        card.setSname("凯耐");        Students s=new Students(1,"凯耐","男",new Date(),"计算机",card);        //两个实例对象都需要保存        session.save(card);        session.save(s);    }}
总结:处理一对一单向外键只需添加两个JPA注解分别为:    @OneToOne(cascade=CascadeType.ALL)    @JoinColumn(name="pid",unique=true)   注意:必须先保存外键表对象,再保存主键表对象,否则会报错!!!

一对一双向外键关联:指两个持久化类中,“你中有我我中有你”,相互访问。

1.持久化类

package cn.codeWang.entity;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.OneToOne;import org.hibernate.annotations.GenericGenerator;@Entitypublic class IdCard {    @Id    //字符串作为主键的处理方法    @GeneratedValue(generator="pid")    @GenericGenerator(name="pid",strategy="assigned")    @Column(length=18)    private String pid;    private String sname;///////////////////////////////////////////////    @OneToOne(mappedBy="card")    private Students student;    public IdCard(){    }    public String getPid() {        return pid;    }    public void setPid(String pid) {        this.pid = pid;    }    public String getSname() {        return sname;    }    public void setSname(String sname) {        this.sname = sname;    }    public Students getStudent() {        return student;    }    public void setStudent(Students student) {        this.student = student;    }}package cn.codeWang.entity;import java.util.Date;import javax.persistence.CascadeType;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.OneToOne;import javax.persistence.Temporal;import javax.persistence.TemporalType;@Entitypublic class Students {    @Id    @GeneratedValue    private int sid;    private String sname;    private String gender;    @Temporal(TemporalType.DATE)    private Date birthday;    private String major;    @OneToOne(cascade=CascadeType.ALL)    @JoinColumn(name="pid",unique=true)    private IdCard card;    public Students() {    }    public String getSname() {        return sname;    }    public void setSname(String sname) {        this.sname = sname;    }    public IdCard getCard() {        return card;    }    public void setCard(IdCard card) {        this.card = card;    }    public Students(int sid, String sname, String gender, Date birthday, String major, IdCard card) {        super();        this.sid = sid;        this.sname = sname;        this.gender = gender;        this.birthday = birthday;        this.major = major;        this.card = card;    }    public int getSid() {        return sid;    }    public void setSid(int sid) {        this.sid = sid;    }    public String getGender() {        return gender;    }    public void setGender(String gender) {        this.gender = gender;    }    public Date getBirthday() {        return birthday;    }    public void setBirthday(Date birthday) {        this.birthday = birthday;    }    public String getMajor() {        return major;    }    public void setMajor(String major) {        this.major = major;    }}

2.测试类

import java.util.Date;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.boot.MetadataSources;import org.hibernate.boot.registry.StandardServiceRegistryBuilder;import org.hibernate.service.ServiceRegistry;import org.junit.After;import org.junit.Before;import org.junit.Test;import cn.codeWang.entity.IdCard;import cn.codeWang.entity.Students;public class DemoTest {    private SessionFactory sessionFactory;    private Session session;    private Transaction transaction;    @Before    public void init() {        // 创建服务注册对象        ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure().build();        // 创建会话工厂对象        sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();        // 会话对象        session = sessionFactory.openSession();        // 开启事物        transaction = session.beginTransaction();    }    @After    public void destory() {        // 提交事物        transaction.commit();        // 关闭会话        session.close();        // 关闭会话工厂        sessionFactory.close();    }    @Test    // 向数据库中添加数据    public void testSave() {         IdCard card=new IdCard();        card.setPid("123456789");        card.setSname("凯耐");        Students s=new Students(1,"凯耐","男",new Date(),"计算机",card);        //两个实例对象都需要保存,必须先保存外键表对象,再保存主键表对象        session.save(card);        session.save(s);    }}

总结:
1.主控方的配置和 单向一对一外键关联配置方法一样。

2.@OneToOne(mappedBy=”card”)指定被控制方

3.双向关联必须设置mappedBy属性。因为双向关联只能交给一方去控制。无法双方都设置外键。

3.一对一双向外键联合主键有什么作用?等发现其作用再学,哈哈

一对一双向外键联合主键
1.创建主键类必须满足一下条件:
@:必须实现hashCode()和equals()方法
@必须实现serializable接口
2.主键类使用@Embeddable修饰
3.实体类使用@EmbeddedId修饰