单向一对多关联
一: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(); } } }
相关推荐
9.配置会员到留言的一对多单向关联关系 10.配置管理员到留言的一对多单向关联关系 11.配置会员到购物车的一对多单向关联关系 12.配置订单到购物车的一对一单向关联关系 13.配置购物车到商品的多对多单向关联关系
一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) 8.2. 在...
7.4.1. 一对多(one to many) / 多对一(many to one) 7.4.2. 一对一(one to one) 7.5. 使用连接表的双向关联(Bidirectional associations with join tables) 7.5.1. 一对多(one to many) /多对一( many ...
7.3 映射一对多双向自身关联关系 7.4 改进持久化类 7.5 小结 7.6 思考题 第8章 通过Hibernate操纵对象(上) 8.1 Java对象在JVM中的生命周期 8.2 理解Session的缓存 8.2.1 Session的缓存的作用 ...
7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) 8.2. 在...
7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) ...
7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) ...
7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) ...
8.5.1. 一对多(one to many) /多对一( many to one) 8.5.2. 一对一(one to one) 8.5.3. 多对多(many to many) 9. 组件(Component)映射 9.1. 依赖对象(Dependent objects) 9.2. 在集合中出现的依赖...
7.4.1. 一对多(one to many) / 多对一(many to one) 7.4.2. 一对一(one to one) 7.5. 使用连接表的双向关联(Bidirectional associations with join tables) 7.5.1. 一对多(one to many) /多对一( many to ...
7.5.1. 一对多(one to many) /多对一( many to one) 7.5.2. 一对一(one to one) 7.5.3. 多对多(many to many) 7.6. 更复杂的关联映射 8. 组件(Component)映射 8.1. 依赖对象(Dependent objects) ...
property-ref:关联类中用于与主控类相关联的属性名,默认为关联类的主键属性名 单向一对多需在一方配置,双向一对多需在双方进行配置 8.lazy=false:被动方的记录由hibernate负责记取,之后存放在主控...
本章介绍一对多关联关系的映射方法,重点介绍inverse属性和cascade属性的用法。本章还将介绍通过Hibernate API来保存、修改和删除具有关联关系的对象的方法。 7.1 建立多对一的单向关联关系 148 7.1.1 [many-to-...
8.5.1. 一对多(one to many) /多对一( many to one) 8.5.2. 一对一(one to one) 8.5.3. 多对多(many to many) 9. 组件(Component)映射 9.1. 依赖对象(Dependent objects) 9.2. 在集合中出现的依赖...
7.3 映射一对多双向自身关联关系 7.4 改进持久化类 7.5 小结 7.6 思考题 第8章 通过Hibernate操纵对象(上) 8.1 Java对象在JVM中的生命周期 8.2 理解Session的缓存 8.2.1 Session的缓存的作用 ...
7.3 映射一对多双向自身关联关系 7.4 改进持久化类 7.5 小结 7.6 思考题 第8章 通过Hibernate操纵对象(上) 8.1 Java对象在JVM中的生命周期 8.2 理解Session的缓存 8.2.1 Session的缓存的作用 ...
7.3 映射一对多双向自身关联关系 7.4 改进持久化类 7.5 小结 7.6 思考题 第8章 通过Hibernate操纵对象(上) 8.1 Java对象在JVM中的生命周期 8.2 理解Session的缓存 8.2.1 Session的缓存的作用 ...
这种策略支持双向的一对多关联,但不支持 IDENTIFY 生成器策略,因为ID必须在多个表间共享。一旦使用就不能使用AUTO和IDENTIFY生成器。 每个类层次结构一张表 @Entity @Inheritance(strategy=InheritanceType....
8.5.1. 一对多(one to many) /多对一( many to one) 8.5.2. 一对一(one to one) 8.5.3. 多对多(many to many) 9. 组件(Component)映射 9.1. 依赖对象(Dependent objects) 9.2. 在集合中出现的依赖...