一对一关联映射有两种方式:主键关联和外键关联
以夫妻为例(Husband----Wife)
单向关联实体类:
Husband.java
package com.java.hibernate; public class Husband { private int id; private String name; private Wife wife; public Wife getWife() { return wife; } public void setWife(Wife wife) { this.wife = wife; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Wife.java
package com.java.hibernate; public class Wife { private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
双向关联实体类:
Husband.java
package com.java.hibernate; public class Husband { private int id; private String name; private Wife wife; public Wife getWife() { return wife; } public void setWife(Wife wife) { this.wife = wife; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Wife.java
package com.java.hibernate; public class Wife { private int id; private String name; private Husband husband; public Husband getHusband() { return husband; } public void setHusband(Husband husband) { this.husband = husband; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
单向主键关联:
Husband映射文件:
<?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> <class name="com.java.hibernate.Husband" table="t_husband"> <id name="id"> <!-- 采用foreign生成策略,forgeign会取得关联对象的标识 --> <generator class="foreign"> <!-- property只关联对象 --> <param name="property">wife</param> </generator> </id> <property name="name"></property> <!-- one-to-one指示hibernate如何加载其关联对象,默认根据主键加载 也就是拿到关系字段值,根据对端的主键来加载关联对象 constrained="true表示,当前主键(husband的主键)还是一个外键 参照了对端的主键(wife的主键),也就是会生成外键约束语句 --> <one-to-one name="wife" constrained="true"/> </class> </hibernate-mapping>
Wife映射文件:
<?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> <class name="com.java.hibernate.Wife" table="t_wife"> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> </class> </hibernate-mapping>
测试类
package com.java.hibernate; import junit.framework.TestCase; import org.hibernate.Session; public class Test extends TestCase{ public void testSave1() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Wife wife = new Wife(); wife.setName("昆凌"); Husband husband = new Husband(); husband.setName("周杰伦"); //建立关联 husband.setWife(wife); //没有抛出TransientObjectException //是由一对一关联映射的特性决定的,它必须先保存关联对象wife //这样它采用foreign映射策略才能取得关联对象的标识 //也就是它默认了cascade属性 session.save(husband); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { HibernateUtils.closeSession(session); } } public void testSave2() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Wife wife = new Wife(); wife.setName("昆凌"); Husband husband = new Husband(); husband.setName("周杰伦"); //建立关联 husband.setWife(wife); //只能将IdCard保存,不能将Person保存 //因为关系的维护端在Person端,IdCard不知道Person的存在 session.save(wife); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { HibernateUtils.closeSession(session); } } public void testLoad1() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Husband husband = (Husband)session.load(Husband.class, 1); System.out.println("husband.name=" + husband.getName()); System.out.println("husband.wife=" + husband.getWife().getName()); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } } }
双向主键关联:
参照单向主键关联,只需修改Wife映射文件:
<?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> <class name="com.java.hibernate.Wife" table="t_wife"> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> <one-to-one name="husband"></one-to-one> </class> </hibernate-mapping>
测试类:
package com.java.hibernate; import junit.framework.TestCase; import org.hibernate.Session; public class Test extends TestCase { public void testLoad() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Wife wife = (Wife) session.load(Wife.class, 1); System.out.println(wife.getName()); System.out.println(wife.getHusband().getName()); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { HibernateUtils.closeSession(session); } } }
单向外键关联:
一对一唯一外键关联映射其实是多对一的特例,采用<many-to-one>标签来映射,指定多的一端unique为true,这样就限制了多的一端的多重性唯一,就是这样来映射的。
Husband映射文件
<?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> <class name="com.java.hibernate.Husband" table="t_husband"> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> <many-to-one name="wife" unique="true"></many-to-one> </class> </hibernate-mapping>
Wife映射文件
<?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> <class name="com.java.hibernate.Wife" table="t_wife"> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> </class> </hibernate-mapping>
测试类
package com.java.hibernate; import junit.framework.TestCase; import org.hibernate.Session; public class Test extends TestCase{ public void testSave1() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Wife wife = new Wife(); wife.setName("昆凌"); Husband husband = new Husband(); husband.setName("周杰伦"); //建立关联 husband.setWife(wife); //抛出TransientObjectException //因为IdCard为Transient状态 session.save(husband); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { HibernateUtils.closeSession(session); } } public void testSave2() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Wife wife = new Wife(); wife.setName("昆凌"); session.save(wife); Husband husband = new Husband(); husband.setName("周杰伦"); //建立关联 husband.setWife(wife); session.save(husband); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { HibernateUtils.closeSession(session); } } public void testLoad1() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Husband husband = (Husband)session.load(Husband.class, 2); System.out.println("husband.name=" + husband.getName()); System.out.println("husband.wife=" + husband.getWife().getName()); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } } }
双向外键关联:
一对一唯一外键关联双向采用<one-to-one>标签映射,必须指定<one-to-one>标签中的property-ref属性为关系字段的名称
参照单向外键关联,只需修改Wife映射 文件
<?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> <class name="com.java.hibernate.Wife" table="t_wife"> <id name="id"> <generator class="native"></generator> </id> <property name="name"></property> <one-to-one name="husband" property-ref="wife"></one-to-one> </class> </hibernate-mapping>
测试类:
package com.java.hibernate; import junit.framework.TestCase; import org.hibernate.Session; public class Test extends TestCase { public void testLoad() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Wife wife = (Wife) session.load(Wife.class, 1); System.out.println(wife.getName()); System.out.println(wife.getHusband().getName()); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { HibernateUtils.closeSession(session); } } }
时间: 2024-10-19 16:09:44