<?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="cn.itcast.i_hbm_oneToOne2">
<!-- 类名 -->
<class name="Person" table="t_person2">
<id name="id" type="integer" column="id">
<generator class="native" />
</id>
<property name="name" type="string" column="name" />

<!-- idCard属性,IdCard类型 表达的是本类与IdCard的一对一。
采用主键一对一映射方式,本方无外键方
-->
<one-to-one name="idCard" class="IdCard" cascade="delete"/>
</class>
</hibernate-mapping>


<?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="cn.itcast.i_hbm_oneToOne2">
<!-- 类名 -->
<class name="IdCard" table="t_idcard2">
<id name="id" type="integer" column="id">
<!-- 当使用基于主键的一对一映射时,
有外键的主键生成策略一定要是foreign。
参数property:
生成主键值时所根据的对象。
-->
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<property name="number" type="string" column="number" />

<!-- person属性,Person类型 表达的是本类与Person的一对一。
采用主键一对一映射方式,本方有外键方
-->
<one-to-one name="person" class="Person" constrained="true"></one-to-one>
</class>
</hibernate-mapping>


package cn.itcast.i_hbm_oneToOne2;

/**
* 公民实体类
*
* @author 风清杨
* @version V1.0
*/
public class Person {
private Integer id;// 主键id
private String name;// 姓名
private IdCard idCard;// 关联的身份证

public Integer getId() {
return id;
}

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

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public IdCard getIdCard() {
return idCard;
}

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

@Override
public String toString() {
return "IdCard [id=" + id + ", name=" + name + "]";
}
}


package cn.itcast.i_hbm_oneToOne2;

/**
* 身份证 实体类
*
* @author 风清杨
* @version V1.0
*/
public class IdCard {
private Integer id;// 主键
private String number;// 身份证编号
private Person person;// 关联的公民对象

public Integer getId() {
return id;
}

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

public String getNumber() {
return number;
}

public void setNumber(String number) {
this.number = number;
}

public Person getPerson() {
return person;
}

public void setPerson(Person person) {
this.person = person;
}

@Override
public String toString() {
return "IdCard [id=" + id + ", number=" + number + "]";
}

}


package cn.itcast.i_hbm_oneToOne2;

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

/**
* 应用程序操作类
*
* @author 风清杨
* @version V1.0
*
*/
public class App {
private static SessionFactory sessionFactory = new Configuration()//
.configure()//
.addClass(Person.class)//
.addClass(IdCard.class)//
.buildSessionFactory();

// 保存,有关联关系
@Test
public void testSave() throws Exception {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// ------------------------------------

// 新建对象
Person person = new Person();
person.setName("张三");

IdCard idCard = new IdCard();
idCard.setNumber("10000001X");

// 关联起来
person.setIdCard(idCard);
idCard.setPerson(person);

// 保存
session.save(person);
session.save(idCard);
// ------------------------------------
tx.commit();
} catch (RuntimeException e) {
tx.rollback();
throw e;
} finally {
session.close();
}
}

// 获取,可以获取到关联的对方
@Test
public void testGet() throws Exception {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// ------------------------------------

// 获取一方数据,并显示另一方信息
// Person person = (Person) session.get(Person.class, 1);
// System.out.println(person);
// System.out.println(person.getIdCard());

IdCard idCard = (IdCard) session.get(IdCard.class, 1);
System.out.println(idCard);
System.out.println(idCard.getPerson());
// ------------------------------------
tx.commit();
} catch (RuntimeException e) {
tx.rollback();
throw e;
} finally {
session.close();
}
}

// 解除关联关系:使用基于主键的一对一映射方式:双方都不可以解除关联关系
@Test
public void testRemoveRelation() throws Exception {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// ------------------------------------

// 基于主键的一对一映射:从有外键方解除关系,不可以,因为主键不能为null。
IdCard idCard = (IdCard) session.get(IdCard.class, 1);
idCard.setPerson(null);

// 从无外键方解除关系,不可以。
// Person person = (Person) session.get(Person.class, 1);
// person.setIdCard(null);

// ------------------------------------
tx.commit();
} catch (RuntimeException e) {
tx.rollback();
throw e;
} finally {
session.close();
}
}

// 删除对象,对关联对象的影响
@Test
public void testDelete() throws Exception {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
// ------------------------------------

// a,如果没有关联的对方:
// b,如果有关联对方:因为会直接删除自已,所以无外键方会有异常,有外键方没有异常。
IdCard idCard = (IdCard) session.get(IdCard.class, 2);
session.delete(idCard);

// Person person = (Person) session.get(Person.class, 1);
// session.delete(person);

// ------------------------------------
tx.commit();
} catch (RuntimeException e) {
tx.rollback();
throw e;
} finally {
session.close();
}
}
}