单向一对多关联
一:group Set存储contactPerson对象
多:contactPerson
在一的一方维护关联关系
一端持有多方的引用,为一个集合,Set集合比较常用
单向一对多关联---lazy延迟策略
set集合上可以定义的lazy属性:
-true 默认
-false
-extra --> 除非访问到对象属性,否则不会发出查询对象的具体属性的语句!
比如,求集合的size(),发出的查询语句时select count(*) 效率高!
比如,判断集合是否为空,isEmpty(),也不会发出查询属性的select语句!
extra还能改变集合的语义!
比如Set集合中,判断是否包含需要使用到对象equals() hashcode()
而使用lazy=extra时,会屏蔽掉JDK语法规定(hibernate使用了一个代理对象)
原因在于:lazy=extra时,发出的查询语句"不同"!
Hibernate: select 1 from t_person where gid =? and id =?
hibernate会根据已有条件,选择一个最高效率能得到结果的查询语句进行执行!
一对多单向关联,在一端维护关系,如HashSet集合,最好重写hashcode()和equals()
在对HashSet集合进行判断时,如contains(),remove()方法的调用,底层都会通过Hashcode()和equals()去判断对象是否相等。如果不重写,在集合中管理对象时时,会引发许多问题。如果不了解底层原因,很难解决。
1.如果id生成策略是hilo或者uuid,在内存中直接生成id值的,则可以只根据id值重写hashcode和equals
2.如果id生成策略是native,依赖数据库生成id值的,则不能使用id值来重写hashcode和equals
例如,在级联保存瞬时对象时,这些瞬时对象都没有id值,在往HashSet集合中添加的时候,根据这两个方法,判断出这些对象都是同一个,导致最后只有1个对象被保存。
实体类
package org.leadfar.hibernate.model; public class ContactPerson { private int id; private String name; public ContactPerson() { // TODO Auto-generated constructor stub } public ContactPerson(String name) { // TODO Auto-generated constructor stub this.name = 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; } }
<?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"> <!-- name为实体类 table为映射到数据库中的表 lazy默认为true 延迟发出select语句,直到真正用到对象的属性(非id属性)--> <class name="org.leadfar.hibernate.model.ContactPerson" table="t_person" > <!-- id为数据库标识,作为主键 --> <id name="id"> <generator class="native"/> </id> <property name="name"/> </class> </hibernate-mapping>
package org.leadfar.hibernate.model; import java.util.HashSet; import java.util.Set; public class Group { private int id; private String name; private Set<ContactPerson> persons;//hibernate约定使用集合的接口类型! //expert 专家模式 public void addPerson(ContactPerson person) { if(persons == null) { persons = new HashSet<ContactPerson>(); } persons.add(person); } public Set<ContactPerson> getPersons() { return persons; } public void setPersons(Set<ContactPerson> persons) { this.persons = persons; } public Group() { // TODO Auto-generated constructor stub } public Group(String name) { this.name = 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; } }
Grasp 强调类的设计原则
GOF 强制类的职责转移
<?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"> <!-- name为实体类 table为映射到数据库中的表 lazy默认为true 延迟发出select语句,直到真正用到对象的属性(非id属性)--> <class name="org.leadfar.hibernate.model.Group" table="t_group" > <!-- id为数据库标识,作为主键 --> <id name="id"> <generator class="native"/> </id> <property name="name"/> <set name="persons"> <!-- 对方表中的记录本方的外键字段名为gid --> <key column="gid"></key> <!-- class说明多的一方:org.leadfar.hibernate.model.ContactPerson --> <one-to-many class="org.leadfar.hibernate.model.ContactPerson"></one-to-many> </set> </class> </hibernate-mapping>
测试
package org.leadfar.hibernate.model; import java.util.HashSet; import java.util.Set; import junit.framework.TestCase; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class Test_one2Many_01 extends TestCase { public void test_save() throws Exception { Configuration cfg = new Configuration().configure(); SessionFactory sfactory = cfg.buildSessionFactory(); Session session = sfactory.openSession(); try { session.beginTransaction(); ContactPerson cp1 = new ContactPerson("张三"); session.save(cp1); ContactPerson cp2 = new ContactPerson("李四"); session.save(cp2); ContactPerson cp3 = new ContactPerson("王五"); session.save(cp3); Group g1 = new Group("朋友"); //专家模式(grasp)--对外暴露接口,内部封装具体的方法 g1.addPerson(cp1);//group中有一个集合,存储contactPerson对象 g1.addPerson(cp2); session.save(g1); Group g2 = new Group("陌生人"); session.save(g2); Group g3 = new Group("商务"); g3.addPerson(cp3); session.save(g3); //下面的做法不好! /*Set<ContactPerson> persons1 = new HashSet<ContactPerson>(); persons1.add(cp1); persons1.add(cp2); g1.setPersons(persons1); Set<ContactPerson> persons2 = new HashSet<ContactPerson>(); persons2.add(cp3); g3.setPersons(persons2);*/ session.getTransaction().commit(); } catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { session.close(); } } //one-to-many 由一找到多--集合--遍历集合-->多 public void test_load() throws Exception { Configuration cfg = new Configuration().configure(); SessionFactory sfactory = cfg.buildSessionFactory(); Session session = sfactory.openSession(); try { session.beginTransaction(); Group g = (Group) session.load(Group.class, 1); g.getId(); g.getName(); Set<ContactPerson> persons = g.getPersons(); for(ContactPerson cp : persons) { System.out.println(cp.getId()); System.out.println(cp.getName()); } session.getTransaction().commit(); } catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { session.close(); } } }
相关推荐
标题 "Hibernate基于连接表的一对多单向关联" 涉及的是数据库对象关系映射(ORM)框架Hibernate中的一个重要概念。在Java开发中,Hibernate是广泛使用的工具,它允许开发者将Java类与数据库表进行映射,简化了数据...
总结,Hibernate的一对多单向关联映射通过XML映射文件和注解配合,可以方便地管理实体之间的关系。这种方式简化了数据库操作,提高了代码的可读性和可维护性。在实际开发中,应根据业务需求灵活运用,确保数据的一致...
“Hibernate基于外键的一对多单向关联”这个标题指的是在Java持久化框架Hibernate中,如何通过外键实现一个实体类(如订单)与另一个实体类(如商品)之间的一对多关系,并且这种关联是单向的,即从订单端可以访问到...
在Java的持久化框架Hibernate中,一对多关联映射是一种常见的关系映射方式,它用于表示一个实体(如用户)可以拥有多个关联实体(如订单)。在这个场景中,"一"通常代表父实体,"多"代表子实体。这篇博客文章...
在Java的持久化框架Hibernate中,多对一(ManyToOne)关联关系是一种常见的对象关系映射(ORM)场景。这种关系通常出现在一个实体类拥有多条与另一个实体类相关的记录,而另一个实体类可能只有一条对应的记录。例如...
在Java的持久化框架Hibernate中,单向一对多关联映射是常见的数据关系处理方式,尤其是在处理数据库中的实体类和表之间的关系时。本主题主要关注如何使用注解来实现这种映射。Hibernate通过注解使得对象关系映射...
通过`hibernate_many2many_1`这个文件名推测,压缩包可能包含了示例代码或者配置文件,这些内容可以帮助读者更直观地理解多对多单向关联的实现过程。具体来说,可能包含如下内容: 1. `pom.xml`:Maven项目的配置...
在Java的持久化框架Hibernate中,一对一(One-to-One)关联映射是常见的关系数据库模型在对象模型中的体现。这种关联通常用于表示两个实体之间非常特殊的联系,比如一个人只有一个身份证,或者一个公司只有一个总部...
压缩包中的`s2sh_relation07_many2one_uni`可能是示例项目的名称,暗示这是一个基于Spring、Struts2和Hibernate(S2SH)的项目,其中包含了多对一单向关联的实例代码。你可以下载并运行这个项目,以便更直观地理解...
在本主题"Hibernate单向一对多关联映射(XML版)"中,我们将深入探讨如何使用XML配置来实现数据库中一个实体类对应多个实体类的关联关系。 在Hibernate中,一对多关联是一种常见的关系映射类型,它反映了数据库中的...
本教程主要探讨的是Hibernate中的一种重要关系映射类型:一对多单向关联。在关系型数据库中,一对多关联是最常见的关系类型,一个实体可以与多个其他实体相关联。在Hibernate中,这种关系可以通过配置XML映射文件或...
8. Hibernate 多对多单向关联: 多对多关联通常通过连接表实现,但单向关联意味着只有一方(如 Course)知道这个关联,另一方(如 Student)不知情。Course 实体类中会有一个 `set` 或 `list` 类型的属性,使用 `...
总结起来,Hibernate的单向多对多映射通过XML配置文件定义了实体之间的关系,使得在Java代码中处理数据库的多对多关联变得更加简单和直观。理解和熟练掌握这一映射方式,对于提升Java持久层开发的效率和质量至关重要...
本话题主要探讨的是Hibernate中的一种关联映射方式——一对一(One-to-One)单向外键关联。这种关联模式通常用于两个实体之间存在唯一对应的关系,例如一个用户对应一个唯一的账户。 在Hibernate中,一对一关联可以...
在Java的持久化框架Hibernate中,一对多关联映射是一种常见的关系数据库模型,它用于表示一个实体(类)可以与多个其他实体实例相关联的情况。本文将深入探讨Hibernate中的一对多关联映射,以及如何实现双向关联。 ...
本项目“Hibernate学习:单向多对一关联 工程”专注于讲解Hibernate中的单向多对一关联映射,这是数据库设计中常见的关系类型,尤其在处理具有层次结构的数据时。 单向多对一关联指的是在一个实体类中有一个引用,...