hibernate一对一唯一外键关联映射(单向关联Citizen---->IDCard)
一对唯一外键关联映射是多对一关联映射的特例
基于外键关联的单向一对一关联和单向多对一关联几乎是一样的。唯一的不同就是单向一对一关联中的外键字段具有唯一性约束。只需要将原来的many-to-one元素增加unique="true"属性,用于表示N的一端也必须是唯一的,在N的一端增加了唯一的约束,即成为单向1-1。
具体做法
1. 单向一对一关联:对象模型和关系模型不匹配。
对象模型上:主控方持有被控方实体类的引用。
关系模型上:主控方对应表中添加一个外键引用自被控方的主键,这个外键必须添加唯一约束。
2. 在主控方的映射文件中:
<many-to-one name="属性名" column="外键名" unique="true" [cascade="all"]/>
Citizen.java
- <span style="font-size: large;">package com.javacrazyer.domain;
- public class Citizen {
- private Long id;
- private String name;
- private Boolean gender;
- //一对一关联中:主控方持有被控方的引用
- private IDCard idCard;
- public Long getId() {
- return id;
- }
- public void setId(Long id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Boolean getGender() {
- return gender;
- }
- public void setGender(Boolean gender) {
- this.gender = gender;
- }
- public IDCard getIdCard() {
- return idCard;
- }
- public void setIdCard(IDCard idCard) {
- this.idCard = idCard;
- }
- public String toString(){
- return "id=" + this.id + ",name=" + this.name + ",gender=" + this.gender;
- }
- }
- </span>
IDCard.java
- <span style="font-size: large;">package com.javacrazyer.domain;
- public class IDCard {
- private Long id;
- private String no;
- public Long getId() {
- return id;
- }
- public void setId(Long id) {
- this.id = id;
- }
- public String getNo() {
- return no;
- }
- public void setNo(String no) {
- this.no = no;
- }
- public String toString(){
- return "id=" + id + ",no=" + this.no;
- }
- }
- </span>
Citizen.hbm.xml
- <span style="font-size: large;"><?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>
- <class name="com.javacrazyer.domain.Citizen">
- <id name="id" column="id">
- <generator class="native"/>
- </id>
- <property name="name"/>
- <property name="gender"/>
- <!-- 映射基于外键一对一关联 -->
- <many-to-one name="idCard" column="card_id" unique="true" cascade="all"/>
- </class>
- </hibernate-mapping></span>
IDCard.hbm.xml
- <span style="font-size: large;"><?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>
- <class name="com.javacrazyer.domain.IDCard" >
- <id name="id" column="id">
- <generator class="native"/>
- </id>
- <property name="no"/>
- </class>
- </hibernate-mapping></span>
hibernate.cfg.xml
- <span style="font-size: large;"><?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="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
- <property name="hibernate.connection.url">jdbc:mysql:///test</property>
- <property name="hibernate.connection.username">root</property>
- <property name="hibernate.connection.password">root</property>
- <!-- 数据库言的配置 -->
- <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
- <property name="hibernate.show_sql">true</property>
- <property name="hibernate.format_sql">true</property>
- <property name="hibernate.hbm2ddl.auto">update</property>
- <!-- 声明实体关系映射文件 -->
- <mapping resource="com/javacrazyer/domain/IDCard.hbm.xml" />
- <mapping resource="com/javacrazyer/domain/Citizen.hbm.xml" />
- </session-factory>
- </hibernate-configuration></span>
启动下Hibernate,自动生成数据库表,数据库表的DDL语句如下
idcard表
- <span style="font-size: large;"> create table `test`.`idcard`(
- `id` BIGINT not null auto_increment,
- `no` VARCHAR(255),
- primary key (`id`)
- );
- create unique index `PRIMARY` on `test`.`idcard`(`id`);</span>
citizen表
- <span style="font-size: large;">create table `test`.`citizen`(
- `id` BIGINT not null auto_increment,
- `name` VARCHAR(255),
- `gender` BIT,
- `card_id` BIGINT unique,
- primary key (`id`)
- );
- alter table `test`.`citizen`
- add index `FK92029348E9FA33E0`(`card_id`),
- add constraint `FK92029348E9FA33E0`
- foreign key (`card_id`)
- references `test`.`idcard`(`id`);
- create unique index `PRIMARY` on `test`.`citizen`(`id`);
- create unique index `card_id` on `test`.`citizen`(`card_id`);
- create index `FK92029348E9FA33E0` on `test`.`citizen`(`card_id`);</span>
Hibernate辅助类
- <span style="font-size: large;">package com.javacrazyer.common;
- import org.hibernate.SessionFactory;
- import org.hibernate.cfg.Configuration;
- /**
- * Hibernate工具类
- *
- */
- public class HibernateUtil {
- private static final SessionFactory factory;
- private HibernateUtil(){}
- static{
- //加载Hibernate全局配置文件,根据配置信息创建SessionFactory工厂实例
- factory = new Configuration().configure().buildSessionFactory();
- }
- public static SessionFactory getSessionFactory(){
- return factory;
- }
- }
- </span>
测试类
- <span style="font-size: large;">package com.javacrazyer.test;
- import org.hibernate.Session;
- import org.hibernate.SessionFactory;
- import org.junit.AfterClass;
- import org.junit.BeforeClass;
- import org.junit.Test;
- import com.javacrazyer.common.HibernateUtil;
- import com.javacrazyer.domain.Citizen;
- import com.javacrazyer.domain.IDCard;
- public class MappingTest {
- private static SessionFactory sessionFactory;
- @BeforeClass
- public static void init(){
- sessionFactory = HibernateUtil.getSessionFactory();
- }
- @AfterClass
- public static void destroy(){
- sessionFactory = null;
- }
- @Test
- public void testSave(){
- Session session = sessionFactory.openSession();
- session.beginTransaction();
- IDCard ic = new IDCard();
- ic.setNo("xx0001");
- Citizen citizen = new Citizen();
- citizen.setName("赵C");
- //设置一对一的关联
- citizen.setIdCard(ic);
- session.save(citizen);
- session.getTransaction().commit();
- session.close();
- }
- @Test
- public void testGet(){
- Session session = sessionFactory.openSession();
- session.beginTransaction();
- Citizen c = (Citizen)session.get(Citizen.class, Long.valueOf(1));
- System.out.println(c.getName());
- IDCard idcard = c.getIdCard();
- System.out.println(idcard.getId());
- session.getTransaction().commit();
- session.close();
- System.out.println(idcard.getNo());
- }
- }</span>