一对一关联关系,当需要对2个对象进行独立对待时,分2个类来完成映射
主键关联映射,没有额外字段维护关联,id值保持一致
package org.leadfar.hibernate.model; public class Person { private long id; private String name; private IdCard idcard; Person(){} public long getId() { return id; } public IdCard getIdcard() { return idcard; } public String getName() { return name; } public void setId(long id) { this.id = id; } public void setIdcard(IdCard idcard) { this.idcard = idcard; } public void setName(String name) { this.name = name; } }
<?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="org.hibernate.auction"> <class name="org.leadfar.hibernate.model.Person" table="t_persons" > <!-- id为数据库标识,作为主键 --> <id name="id"> <generator class="native"/> </id> <property name="name"/> <!-- 根据本方id到t_idcard中寻找id值相同的那条记录 --> <one-to-one name="idcard"> </one-to-one> </class> </hibernate-mapping>
package org.leadfar.hibernate.model; public class IdCard { private long id; private String sn; private Person person; IdCard() {} public long getId() { return id; } public Person getPerson() { return person; } public String getSn() { return sn; } public void setId(long id) { this.id = id; } public void setPerson(Person person) { this.person = person; } public void setSn(String sn) { this.sn = sn; } }
<?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="org.hibernate.auction"> <class name="org.leadfar.hibernate.model.IdCard" table="t_idcard" > <id name="id"> <!-- 使用foreign表示本记录的id值依赖于对方的id值 --> <generator class="foreign"> <!-- 表示被依赖的对象(通过对象可以映射到表中某条记录,从而得到id) --> <param name="property">person</param> </generator> </id> <property name="sn" not-null="true" unique="true"></property> <!--constraint表示外键具有约束条件,即idcard存在时不能删除对应的person --> <!-- one-to-one表示根据自己的id到对方表中寻找相同id值的记录 --> <one-to-one name="person" constrained="true"></one-to-one> </class> </hibernate-mapping>
测试
package org.leadfar.hibernate.model; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import junit.framework.TestCase; public class OneToOneTest extends TestCase { public void oneToOne_save() { Configuration cfg = new Configuration().configure(); SessionFactory sf = cfg.buildSessionFactory(); Session session = sf.openSession(); try { session.beginTransaction(); /** *配置文件映射方式:one-to-one idCard的id生成策略为foreign,参考Person的id属性来设置自己的id(两者id保存一致) *先有Person,再有IdCard,其中IdCard的id属性生成需要参考Person中的id *所以,必需先保存Person,再保存IdCard */ Person p1 = new Person(); p1.setName("张三1"); Person p2 = new Person(); p2.setName("张三2"); Person p3 = new Person(); p3.setName("张三3"); session.save(p1); session.save(p2); session.save(p3); IdCard idcard = new IdCard(); idcard.setSn("21938404320997903"); idcard.setPerson(p3);//通过p3找到数据库中对应的id,然后作为idcard记录的id session.save(idcard); session.getTransaction().commit(); } catch(Exception e) { session.getTransaction().rollback(); e.printStackTrace(); } finally { session.close(); } } //根据Person获取idCard public void oneToOne_load01() { Configuration cfg = new Configuration().configure(); SessionFactory sf = cfg.buildSessionFactory(); Session session = sf.openSession(); try { session.beginTransaction(); Person p1 = (Person)session.load(Person.class, 3L);//如果id为long类型,则需要加L后缀 IdCard idcard = p1.getIdcard(); System.out.println(p1.getName()+","+idcard.getSn()); session.getTransaction().commit(); } catch(Exception e) { session.getTransaction().rollback(); e.printStackTrace(); } finally { session.close(); } } //根据idCard获取Person public void oneToOne_load02() { Configuration cfg = new Configuration().configure(); SessionFactory sf = cfg.buildSessionFactory(); Session session = sf.openSession(); try { session.beginTransaction(); IdCard idcard = (IdCard)session.load(IdCard.class, 3L); Person person = idcard.getPerson(); System.out.println(idcard.getSn()+","+person.getName()); session.getTransaction().commit(); } catch(Exception e) { session.getTransaction().rollback(); e.printStackTrace(); } finally { session.close(); } } }
唯一外键关联映射,在其中一端使用1个字段记录对方的id
package org.leadfar.hibernate.model; public class Person { private long id; private String name; private IdCard idcard; Person(){} public long getId() { return id; } public IdCard getIdcard() { return idcard; } public String getName() { return name; } public void setId(long id) { this.id = id; } public void setIdcard(IdCard idcard) { this.idcard = idcard; } public void setName(String name) { this.name = name; } }
<?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="org.hibernate.auction"> <class name="org.leadfar.hibernate.model.Person" table="t_persons" > <!-- 外键关联时,id生成策略任意皆可,因为不是通过id进行关联的 --> <id name="id"> <generator class="assigned"> </generator> </id> <property name="name"/> <!-- property-ref="person"说明映射的时候将参考对方的person属性字段来映射,而不是通过对方的主键id来映射的!--> <!-- 如果不指定property-ref="person" 将会根据对方的id主键进行映射,就不是通过外键来映射了!一定要搞清楚!!--> <one-to-one name="idcard" property-ref="person"> </one-to-one> </class> </hibernate-mapping>
package org.leadfar.hibernate.model; public class IdCard { private long id; private String sn; private Person person; IdCard() {} public long getId() { return id; } public Person getPerson() { return person; } public String getSn() { return sn; } public void setId(long id) { this.id = id; } public void setPerson(Person person) { this.person = person; } public void setSn(String sn) { this.sn = sn; } }
<?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="org.hibernate.auction"> <class name="org.leadfar.hibernate.model.IdCard" table="t_idcard" > <!-- 外键关联时,id生成策略任意皆可,因为不是通过id进行关联的 --> <id name="id"> <generator class="assigned"/> </id> <property name="sn" not-null="true" unique="true"></property> <!-- unique=true 将many-to-one 限制为一对一关系 --> <!-- 外键将使用many-to-one中的属性,即person属性将作为外键被使用 --> <!-- 也就是说,IdCard一端将通过person属性去获取Person --> <!-- 而且,Person一端如果要使用person字段映射到本表的话,就必须使用property-ref=person --> <!-- 这样双方才能通过唯一的person进行双向关联映射 --> <many-to-one name="person" unique="true" column="personid"></many-to-one> </class> </hibernate-mapping>
测试
package org.leadfar.hibernate.model; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import junit.framework.TestCase; public class OneToOneTest extends TestCase { public void oneToOne_save() { Configuration cfg = new Configuration().configure(); SessionFactory sf = cfg.buildSessionFactory(); Session session = sf.openSession(); try { session.beginTransaction(); /** *one-to-one 外键关联映射 *1.先保存Person (one-to-one)Idcard中的person字段值需要参考person表的主键id *<one-to-one name="idcard" property-ref="person"> </one-to-one> * *2.再保存IdCard,其中IdCard中的person属性将使用前面保存的Person对象 (many-to-one) *<many-to-one name="person" unique="true" column="personid"></many-to-one> */ Person p1= new Person(); p1.setId(1L); p1.setName("1abc"); session.save(p1); Person p2= new Person(); p2.setId(2L); p2.setName("2abc"); session.save(p2); Person p3= new Person(); p3.setId(3L); p3.setName("3abc"); session.save(p3); IdCard idcard1 = new IdCard(); idcard1.setId(2L); idcard1.setSn("11111111111"); idcard1.setPerson(p1);//关联关系一定不要丢 session.save(idcard1); IdCard idcard2 = new IdCard(); idcard2.setId(3L); idcard2.setSn("22222222222"); idcard2.setPerson(p2);//关联关系一定不要丢 session.save(idcard2); IdCard idcard3 = new IdCard(); idcard3.setId(4L); idcard3.setSn("33333333333"); idcard3.setPerson(p3);//关联关系一定不要丢 session.save(idcard3); session.getTransaction().commit(); } catch(Exception e) { session.getTransaction().rollback(); e.printStackTrace(); } finally { session.close(); } } //根据Person获取idCard public void oneToOne_load01() { Configuration cfg = new Configuration().configure(); SessionFactory sf = cfg.buildSessionFactory(); Session session = sf.openSession(); try { session.beginTransaction(); Person p1 = (Person)session.load(Person.class, 2L);//如果id为long类型,则需要加L后缀 IdCard idcard = p1.getIdcard(); System.out.println(p1.getName()+","+idcard.getSn()); session.getTransaction().commit(); } catch(Exception e) { session.getTransaction().rollback(); e.printStackTrace(); } finally { session.close(); } } //根据idCard获取Person public void oneToOne_load02() { Configuration cfg = new Configuration().configure(); SessionFactory sf = cfg.buildSessionFactory(); Session session = sf.openSession(); try { session.beginTransaction(); IdCard idcard = (IdCard)session.load(IdCard.class, 2L); Person person = idcard.getPerson(); System.out.println(idcard.getSn()+","+person.getName()); session.getTransaction().commit(); } catch(Exception e) { session.getTransaction().rollback(); e.printStackTrace(); } finally { session.close(); } } }
相关推荐
本篇将详细讲解如何使用Hibernate实现一对一唯一外键(Unique Foreign Key)关联映射,并以双向关联为例进行深入探讨。 一、Hibernate一对一关联类型 一对一关联在现实世界中很常见,例如一个人只有一个身份证,一...
在提供的压缩包文件`bionetoonetable`中,可能包含了示例代码或者相关的配置文件,用于演示双向一对一基于主键的关联映射的实现。具体的内容需要查看文件才能了解详情。 总结,双向一对一基于主键的关联映射是...
总之,Hibernate的一对一双向外键关联是数据库设计中一个重要的概念,它使得Java对象和数据库记录之间的关系管理更加方便。理解并掌握这种关联方式对于开发高效、健壮的Java应用程序至关重要。通过实践和探索提供的...
这个压缩包文件“HibernateORM”很可能包含了关于如何在实际项目中设置和使用Hibernate一对多双向关联的示例代码、配置文件或者详细教程。通过学习这些材料,开发者能够深入理解如何在Java应用中利用Hibernate来处理...
本篇主要探讨的是基于主键(Primary Key)的双向关联映射,这在实际项目中非常常见,比如用户与账户、员工与职务等场景。 一、主键关联映射概述 主键关联映射是通过将两个实体类的主键相互引用来实现一对一关系的。...
在数据库中,一对一双向关联意味着两个表(或实体类)之间存在一对一的关系,并且双方都可以导航到对方。例如,一个员工可能只属于一个部门,而一个部门也可能只包含一个经理,这样的关系就是一对一双向的。在...
本篇文章将深入探讨 Hibernate 中的一对多双向关联映射。 在数据库设计中,一对多关联是指一个实体可以与多个其他实体相关联,比如一个学生可以有多个课程,一个部门可以有多名员工。在Hibernate中,这种关系可以...
总之,理解并正确实现Hibernate中的一对多双向关联映射是提升应用程序性能和数据一致性的重要步骤。通过细心配置映射文件,编写相应的实体类,以及妥善处理关联关系的维护,我们可以有效地管理复杂的数据结构。
在Java的持久化框架Hibernate中,一对一(One-to-One)关联映射是常见的关系数据库模型映射方式之一。本文将详细解析如何实现一对一唯一外键(Uniquely Foreign Key,UFK)关联映射,特别是在单向关联的情况下的具体...
- Hibernate通过XML配置文件或注解来设置一对一的关联。在XML配置文件中,我们需要在`<one-to-one>`元素中指定关联的实体和外键字段。在注解方式下,使用`@OneToOne`注解并指定`@JoinColumn`或`@MapsId`。 5. **懒...
本篇将深入探讨Hibernate中的一对一唯一外键关联映射,特别是双向关联的实现。 ### 1. 一对一关联概述 一对一关联意味着一个实体只能与另一个实体的单一实例相关联,这种关系通常出现在两个表之间,其中一个表的...
9. Hibernate 一对一外键双向关联、主键双向关联、连接表双向关联、一对多外键双向关联、一对多连接表双向关联、多对多双向关联: 这些关联方式与单向关联类似,区别在于两个实体类都知道彼此的关联。在双向关联中...
本篇文章将详细探讨如何实现Hibernate中的一对一主键关联映射,并以双向关联为例进行解析。 在一对一主键关联映射中,两个实体共享同一个主键,这表示它们在数据库中的记录是唯一的,不可重复。这种映射方式可以...
通过以上分析,我们可以了解到Hibernate中一对一关联映射的原理和实现方法,以及如何进行双向一对一双向关联的配置。实际应用中,需要根据业务需求选择合适的映射方式,并注意维护好关联关系的正确性。在...
1. **关联类型:** Hibernate支持四种基本的关联类型,包括一对一(OneToOne)、一对多(OneToMany)、多对一(ManyToOne)和多对多(ManyToMany)。本主题将主要聚焦在一对一和一对多关联。 2. **关联的方向性:**...
通过注解方式实现一对一关联映射,可以避免传统的XML配置文件,使得代码更加简洁、易读。 ### Hibernate一对一关联映射原理 一对一关联映射是指在数据库中两个表之间存在一对一的关系,例如,一个人只有一个身份证...
- 在一对一双向关联中,如果两个实体都维护外键,可能会导致数据不一致,因此要谨慎处理。 总结起来,Hibernate双向一对一关联映射通过XML配置文件使得我们在Java代码中可以方便地操作数据库中的一对一关系,同时...
在Java持久化框架Hibernate中,一对一双向关联是一种常见的实体关系映射,它反映了数据库中的两个表之间一对一的对应关系。这种关联关系可以是单向的,也可以是双向的,而这里的"hibernate关联关系之一对一双向关联...