首页 > 代码库 > hibernate关联映射【一对一主键】

hibernate关联映射【一对一主键】

从三个部分介绍Hibernate一对一主键关联映射。

1.基本介绍2.代码展示3.总结注意 

1.基本介绍

一对一关联有两种情况:

单向一对一主键关联、双向一对一主键关联。
一对一主键关联:
  是指两个表之间通过主键形成一对一的映射,例如,每个公民只允许拥有一个身份证,公民与身份证就是一对一的关系,
定义两张表,一张People表,一张IdCard表,People表的id既是该表的主键也是该表的外键,并且People的id也就是IdCard的id,

技术分享

 

2.代码

单向一对一主键关联:people表的id既是主键,又是外键,所以在idcard表对应的实体类一方维护People的实例。

hibernate.cfg.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
      <!-- 配置数据库连接驱动类 -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <!-- 配置数据库连接字符串 -->
        <property name="connection.url"><![CDATA[jdbc:mysql://localhost:3306/test111?useUnicode=true&characterEncoding=utf8]]></property>
        <!-- 配置数据库连接用户名 -->
        <property name="connection.username">root</property>
        <!-- 配置数据库连接密码 -->
        <property name="connection.password">123456</property>
        <!-- 配置数据库方言 -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <!-- 配置数据库表生成策略 -->
        <!--<property name="hibernate.hbm2ddl.auto">update</property> -->
        <!-- 配置是否打印显示SQL语句 -->
        <property name="show_sql">true</property>
        <!-- 配置是否格式化显示SQL语句 -->
        <property name="format_sql">true</property>
        <!-- 配置hibernate是否自动提交事务 -->
        <!--<property name="hibernate.connection.autocommit">true</property> -->
        <!-- 配置实体类对应的映射文件 -->
        <!-- 一对一双向主键关联 -->
        <mapping resource="com/great/entity2/People.hbm.xml"></mapping>
        <mapping resource="com/great/entity2/IdCard.hbm.xml"></mapping>
        <!-- 一对一单向主键关联 -->
        <mapping resource="com/great/entity3/People.hbm.xml"></mapping>
        <mapping resource="com/great/entity3/IdCard.hbm.xml"></mapping>
    </session-factory>
</hibernate-configuration>

 

 

 

People.java

 

package com.great.entity3;

public class People {
    // 一对一单向主键关联
    private int id;
    private String pName;


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getpName() {
        return pName;
    }

    public void setpName(String pName) {
        this.pName = pName;
    }


}

 

 

 

IdCard.java

 

package com.great.entity3;

public class IdCard {
    private int id;
    private String CardCode;
    private People people;//维护People

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getCardCode() {
        return CardCode;
    }

    public void setCardCode(String cardCode) {
        CardCode = cardCode;
    }

    public People getPeople() {
        return people;
    }

    public void setPeople(People people) {
        this.people = people;
    }

}

 

 

 

People.hbm.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="com.great.entity2">
  <!-- 配置实体类与数据库表的映射关系 -->
<class name="com.great.entity3.People" table="people">
    <!-- 配置主键映射关系 -->
    <id name="id" column="id" type="int">
      <!-- 配置主键生成策略 -->
      <generator class="assigned">
      </generator>
    </id>
    <!-- 配置属性和表字段映射关系 -->
    <property name="pName" column="pName" type="string"></property>
   
  </class>
</hibernate-mapping>

 

 

 

IdCard.hbm.xml

 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.great.entity3">
    <class name="IdCard" table="idcard">
        <id name="id" column="id" type="int">
            <generator class="foreign">
                <param name="property">people</param>
            </generator>
        </id>
        <!-- 配置属性和表字段映射关系 -->
        <property name="CardCode" column="CardCode" type="string"></property>
        <one-to-one class="com.great.entity3.People" name="people"
            cascade="all"></one-to-one>
    </class>
</hibernate-mapping>

 

 

 

TestOneToOneUnidirectional.java//测试类

 

package com.great.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import com.great.entity3.IdCard;
import com.great.entity3.People;

public class TestOneToOneUnidirectionalKeyRe {
    static Session session;

    // 一对一单向主键关联
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        // 加载hibernate主配置文件
        Configuration cfg = new Configuration().configure();
        // 构建session工厂
        SessionFactory sf = cfg.buildSessionFactory();
        // 打开session
        session = sf.openSession();
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        // 关闭session,释放资源
        session.close();
    }

    // 通过idcard查询people
    @Test
    public void testOneToOneSelect1() {
        IdCard idCard = (IdCard) session.get(IdCard.class, 1);
        System.out.println("身份证号码:" + idCard.getCardCode());
        System.out.println("姓名:" + idCard.getPeople().getpName());
    }

    // 通过保存idCard保存数据,只能通过向IdCard表中插入数据来保存数据
    @Test
    public void testSave() {
        Transaction ts = session.beginTransaction();
        IdCard idCard = new IdCard();
        idCard.setCardCode("411487199505051234");
        People people = new People();
        people.setpName("陈大哥");
        people.setId(2);
        idCard.setPeople(people);
        session.save(idCard);
        ts.commit();
    }

    // 通过删除idCard删除数据
    @Test
    public void testDelete() {
        IdCard idCard = (IdCard) session.get(IdCard.class, 2);
        Transaction ts = session.beginTransaction();
        session.delete(idCard);
        ts.commit();
    }
}

 

 

 

双向一对一主键关联:在idcard表对应的实体类一方维护People的实例,同时在People表对应的实体类一方也维护idcard的实例。

 

新增部分用红色标注了,一个地方在People.hbm.xml中的配置,一处在People.java的属性。

 

IdCard.hbm.xml

 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping  package="com.great.entity2">
<class name="IdCard" table="idcard">

    <id name="id" column="id" type="int">

      <generator class="foreign">
      <param name="property">people</param>
      </generator>
    </id>
    <!-- 配置属性和表字段映射关系 -->
    <property name="CardCode" column="CardCode" type="string"></property>
    <one-to-one class="com.great.entity2.People" name="people"  cascade="all"></one-to-one>
  </class>
</hibernate-mapping>

 

 

People.hbm.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="com.great.entity2">
  <!-- 配置实体类与数据库表的映射关系 -->
<class name="com.great.entity2.People" table="people">
    <!-- 配置主键映射关系 -->
    <id name="id" column="id" type="int">
      <!-- 配置主键生成策略 -->
      <generator class="assigned">
      </generator>
    </id>
    <!-- 配置属性和表字段映射关系 -->
    <property name="pName" column="pName" type="string"></property>

    <!-- 新增 -->
<one-to-one name="idCard" class="com.great.entity2.IdCard" cascade="all"></one-to-one> </class> </hibernate-mapping>

 

 

 

IdCard.java

 

package com.great.entity2;

public class IdCard {
    private int id;
    private String CardCode;
    private People people;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getCardCode() {
        return CardCode;
    }

    public void setCardCode(String cardCode) {
        CardCode = cardCode;
    }

    public People getPeople() {
        return people;
    }

    public void setPeople(People people) {
        this.people = people;
    }

}

 

 

 

People.java

package com.great.entity2;

public class People {
    // 一对一主键关联
    private int id;
    private String pName;
    private IdCard idCard;//新增

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getpName() {
        return pName;
    }

    public void setpName(String pName) {
        this.pName = pName;
    }

    public IdCard getIdCard() {
        return idCard;
    }

    public void setIdCard(IdCard idCard) {
        this.idCard = idCard;
    }

}

 

TestOneToOneBoth.java

 

package com.great.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.great.entity2.IdCard;
import com.great.entity2.People;

public class TestOneToOneBothKeyRe {
    static Session session;

    // 一对一双向主键关联
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        // 加载hibernate主配置文件
        Configuration cfg = new Configuration().configure();
        // 构建session工厂
        SessionFactory sf = cfg.buildSessionFactory();
        // 打开session
        session = sf.openSession();
    }

    @AfterClass
    public static void tearDownAfterClass() throws Exception {
        // 关闭session,释放资源
        session.close();
    }

    // 通过people查询idcard
    @Test
    public void testOneToOneSelect1() {
        IdCard idCard = (IdCard) session.get(IdCard.class, 1);
        System.out.println("身份证号码:" + idCard.getCardCode());
        System.out.println("姓名:" + idCard.getPeople().getpName());
    }

    // 通过idcard查询people
    @Test
    public void testOneToOneSelect2() {
        IdCard idCard = (IdCard) session.get(IdCard.class, 1);
        System.out.println("身份证号码:" + idCard.getCardCode());
        System.out.println("姓名:" + idCard.getPeople().getpName());
    }

    // 插入数据
    @Test
    public void testSave() {
        Transaction ts = session.beginTransaction();
        // 设置idcard
        IdCard idCard = new IdCard();
        idCard.setCardCode("411487199505051234");
        // 设置people
        People people = new People();
        people.setpName("格格");
        people.setId(2);
        // 互相保存
        idCard.setPeople(people);
        people.setIdCard(idCard);
        // 保存idcard,必须保存idCard,保存People出错,Hibernate这次首先持久化了people对象,
        // 由于people表中的id字段建立了外键关系,故持久化失败.
        session.save(idCard);
        ts.commit();
    }

    // 通过删除idCard删除数据
    @Test
    public void testDelete() {
        IdCard idCard = (IdCard) session.get(IdCard.class, 2);
        Transaction ts = session.beginTransaction();
        session.delete(idCard);
        ts.commit();
    }
}

 

3.注意:

 1.配置cascade="all",它可以保证主控方所关联的被控方的操作一致性,例如,主控方进行save、update或delete操作时,被控方会进行同样的操作。

2.单向一对一关联时,select、save、update、delete,只能操作idCard。

2.双向一对一关联时,查询可以进行两个方向查询【因为互相维护对方的实例】,但是save、update、delete,只能操作idCard,例如session.save(idCard);

 

hibernate关联映射【一对一主键】