第5章Hibernate的基本用法 5.7映射组件属性
来源:互联网 发布:桌面desktop.ini 知乎 编辑:程序博客网 时间:2024/04/28 19:54
5.7 映射组件属性
映射组件属性的意思是:持久化类的属性并不是基本数据类型,也不是字符串、日期等标量类型的变量,而是一个符合类型的对象,在持久化的过程中,它仅仅被当做值类型,而并非引用另一个持久化实体。
为了映射组件属性,Hibernate提供了<component.../>元素,每个<component.../>元素映射一个组件属性。使用<component.../>元素映射组件属性时需要指定一个name属性,用于指定该组件属性的名称。除此之外,使用<component.../>元素还需要如下几个可选属性。
为<component../>元素添加<property.../>子元素来映射组件属性的子属性。
添加<parent.../>子元素用于映射组件类内一个指向其容器实体的引用。定义<parent.../>子元素时只需一个name属性,其值为引用容器实体的属性名。
除此之外,<component.../>元素内还可出现如下几种子元素:
*<component.../>:该组件属性里的属性是一个组件类型。
*集合映射元素:如果组件类型里的属性是数组类型、集合类型等
*关联映射元素:如果组件属性里的属性是另外一个持久化实例的引用
例子:
1)Person.java
<span style="font-size:18px;">public class Person{//标识属性private Integer id;//普通属性ageprivate int age;//组件属性nameprivate Name name;//...//name属性的setter和getter方法public void setName(Name name){this.name = name;}public Name getName(){return this.name;}}</span>
2)Name.java
<span style="font-size:18px;">public class Name{//定义first属性private String first;//定义last属性private String last;//引用拥有该Name的Person对象private Person owner;//无参数的构造器public Name(){}//初始化first、last属性的构造器public Name(String first , String last){this.first = first;this.last = last;}//...//owner属性的setter和getter方法public void setOwner(Person owner){this.owner = owner;}public Person getOwner(){return this.owner;}}</span>3)Person.hbm.xml
<span style="font-size:18px;"><?xml version="1.0" encoding="GBK"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="org.crazyit.app.domain"><class name="Person" table="person_inf"><!-- 映射标识属性 --><id name="id" column="person_id"><!-- 指定主键生成器策略 --><generator class="identity"/></id><!-- 映射普通属性 --><property name="age" type="int"/><!-- 映射组件属性name,组件属性的类型为Name --><component name="name" class="Name" unique="true"><!-- 指定owner属性代表容器实体 --><parent name="owner"/><!-- 映射组件属性的first属性 --><property name="first"/><!-- 映射组件属性的last属性 --><property name="last"/></component></class></hibernate-mapping></span>4)PersonManager.java
<span style="font-size:18px;">private void createAndStorePerson(){Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction();//创建Person对象Person yeeku = new Person();//为Person对象设置属性yeeku.setAge(29);Name n = new Name("crazyit.org" , "疯狂Java联盟");yeeku.setName(n);session.save(yeeku);tx.commit();HibernateUtil.closeSession();}</span>对于这种只包含基本类型、字符串、日期类型等属性的组件,Hibernate将会把每个属性映射成一个数据列——即<component.../>元素里每个<property.../>子元素映射一个数据列。
5.7.1 组件属性为集合
如果组件类再次包括了List、Set、Map等集合属性,则我们可以在<component.../>元素里使用<list.../>、<set.../>和<map.../>子元素来映射这些集合元素。
例子:
1)Name.java
public class Name{//定义first属性private String first;//定义last属性private String last;//引用拥有该Name的Person对象private Person owner;private Map<String ,Integer> power= new HashMap<String ,Integer>();//...//owner属性的setter和getter方法public void setOwner(Person owner){this.owner = owner;}public Person getOwner(){return this.owner;}//power属性的setter和getter方法public void setPower(Map<String ,Integer> power){this.power = power;}public Map<String ,Integer> getPower(){return this.power;}}2)Person.hbm.xml
<?xml version="1.0" encoding="GBK"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="org.crazyit.app.domain"><class name="Person" table="person_inf"><!-- 映射标识属性 --><id name="id" column="person_id"><!-- 指定主键生成器策略 --><generator class="identity"/></id><!-- 映射普通属性 --><property name="age" type="int"/><!-- 映射组件属性name,组件属性的类型为Name --><component name="name" class="Name" unique="true"><!-- 指定owner属性代表容器实体 --><parent name="owner"/><!-- 映射组件属性的first属性 --><property name="first"/><!-- 映射组件属性的last属性 --><property name="last"/><!-- 映射组件属性里的Map集合属性 --><map name="power" table="name_power"><!-- 映射集合属性数据表的外键列 --><key column="person_name_id" not-null="true"/><!-- 映射集合属性数据表的Map key列 --><map-key column="name_aspect" type="string"/><!-- 映射保存集合元素的数据列 --><element column="name_power" type="int"/></map></component></class></hibernate-mapping>当主程序保存了这样的Person对象后,Hibernate依然将Name组件的各属性映射成不同的数据列,再将Name里的Map属性映射到另一个数据表。
5.7.2 集合属性的元素为组件
映射集合属性时依然使用<list.../>、<set.../>和<map.../>等元素,只是不再使用<element.../>元素来映射集合元素,而是用<composite-element.../>元素来映射集合元素。配置<composite-element.../>元素时需要指定一个class属性,其值指定了集合里组件对象的类型。
例子:
1)Person.java
public class Person{//标识属性private Integer id;//普通属性ageprivate int age;//组件属性nameprivate Map<String , Name> nicks= new HashMap<String , Name>();//...//nicks属性的setter和getter方法public void setNicks(Map<String , Name> nicks){this.nicks = nicks;}public Map<String , Name> getNicks(){return this.nicks;}}2)Person.hbm.xml
<?xml version="1.0" encoding="GBK"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="org.crazyit.app.domain"><class name="Person" table="person_inf"><!-- 映射标识属性 --><id name="id" column="person_id"><!-- 指定主键生成器策略 --><generator class="identity"/></id><!-- 映射普通属性 --><property name="age" type="int"/><!-- 映射nicks集合属性,集合属性对应的数据表为nick_inf --><map name="nicks" table="nick_inf"><!-- 映射集合属性数据表的外键列 --><key column="person_id" not-null="true"/><!-- 映射集合属性数据表的Map key列 --><map-key column="phase" type="string"/><!-- 映射保存集合里的组件元素 --><composite-element class="Name"><!-- 指定owner属性代表容器实体 --><parent name="owner"/><!-- 映射组件属性的first属性 --><property name="first"/><!-- 映射组件属性的last属性 --><property name="last"/></composite-element></map></class></hibernate-mapping>对于这种集合元素是组件的情形,Hibernate依然会把组件的各属性映射到不同的数据列,只是这些数据列将保存在集合属性列中。
5.7.3 组件作为Map的索引
Hibernate使用<composite-map-key.../>元素来映射符合类型的key,定义<composite-map-key.../>元素时需要指定一个class属性,其值为Map key的类名。
由于Map key的特殊性,所以程序必须重写该组件类的equals()和hashCode()两个方法。
1)Person.java
public class Person{//标识属性private Integer id;//普通属性ageprivate int age;//集合属性nickPowerprivate Map<Name , Integer> nickPower= new HashMap<Name , Integer>();//...//nickPower属性的setter和getter方法public void setNickPower(Map<Name , Integer> nickPower){this.nickPower = nickPower;}public Map<Name , Integer> getNickPower(){return this.nickPower;}}2)Name.java
public class Name{//定义first属性private String first;//定义last属性private String last;//引用拥有该Name的Person对象private Person owner;//...//owner属性的setter和getter方法public void setOwner(Person owner){this.owner = owner;}public Person getOwner(){return this.owner;}//重写equals方法,根据first、last进行判断public boolean equals(Object obj){if (this == obj){return true;}if (obj != null && obj.getClass() == Name.class){Name target = (Name)obj;if (target.getFirst().equals(getFirst())&& target.getLast().equals(getLast())){return true;}}return false;}//重写hashCode方法,根据first、last计算hashCode值public int hashCode(){return getFirst().hashCode() * 13 + getLast().hashCode();}}3)Person.hbm.xml
<?xml version="1.0" encoding="GBK"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="org.crazyit.app.domain"><class name="Person" table="person_inf"><!-- 映射标识属性 --><id name="id" column="person_id"><!-- 指定主键生成器策略 --><generator class="identity"/></id><!-- 映射普通属性 --><property name="age" type="int"/><!-- 映射nickPower集合属性,集合属性对应的数据表为nick_power --><map name="nickPower" table="nick_power"><!-- 映射集合属性数据表的外键列 --><key column="person_id" not-null="true"/><!-- 映射集合属性数据表的Map key列 ,因为Map key的数据类型是复合类型,所以使用如下元素--><composite-map-key class="Name"><!-- 映射复合组件的属性 --><key-property name="first" type="string"/><key-property name="last" type="string"/></composite-map-key><!-- 映射集合元素的数据列 --><element column="nick_power" type="int"/></map></class></hibernate-mapping>Name组件的各属性被映射到集合属性表里的数据列,且此时Name属性作为Map key使用,因此Hibernate会将外键列、Name属性所映射的多列作为联合主键。
5.7.4 组件作为复合主键
使用组件作为复合主键,也就是使用组件作为持久化类的标识符,则该组件类必须满足以下要求:
*必须实现java.io.Serializable接口
*建议正确地重写equals()和hashCode()方法,也就是根据组件类的关键属性来区分组件对象
Hibernate使用<composite-id.../>元素来映射这种复合主键,在<composite-id.../>元素里使用<key-property.../>元素来映射组件类的各属性。
例子:
1)Person.java
public class Person{//以Name组件作为标识属性private Name name;//普通属性ageprivate int age;//name属性的setter和getter方法public void setName(Name name){this.name = name;}public Name getName(){return this.name;}//..}2)Name.java
public class Nameimplements java.io.Serializable{//定义first属性private String first;//定义last属性private String last;//无参数的构造器public Name(){}//初始化全部属性的构造器public Name(String first , String last){this.first = first;this.last = last;}//...//重写equals方法,根据first、last进行判断public boolean equals(Object obj){if (this == obj){return true;}if (obj != null && obj.getClass() == Name.class){Name target = (Name)obj;if (target.getFirst().equals(getFirst())&& target.getLast().equals(getLast())){return true;}}return false;}//重写hashCode方法,根据first、last计算hashCode值public int hashCode(){return getFirst().hashCode() * 7 + getLast().hashCode();}}3)Person.hbm.xml
<?xml version="1.0" encoding="GBK"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="org.crazyit.app.domain"><class name="Person" table="person_inf"><!-- 映射组件类型的标识属性 --><composite-id name="name" class="Name"><!-- 映射组件主键里的各属性 --><key-property name="first" type="string"/><key-property name="last" type="string"/></composite-id><!-- 映射普通属性 --><property name="age" type="int"/></class></hibernate-mapping>4)PersonManager.java
private void createAndStorePerson(){Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction();//创建Person对象Person yeeku = new Person();//为Person对象设置属性yeeku.setAge(29);//创建一个Name对象作为Person对象的标识属性值Name n = new Name("crazyit.org" , "疯狂Java联盟");yeeku.setName(n);session.save(yeeku);tx.commit();HibernateUtil.closeSession();}程序运行结束后,Hibernate将会把Name组件所映射的多个数据列作为联合主键。
5.7.5 多列作为联合主键
Hibernate允许直接将持久化类的多列映射成联合主键。如果需要直接将持久化类的多列映射成联合主键,则该持久化类必须满足如下两个条件:
1、实现java.io.Serializable接口
2、建议根据联合主键列所映射的属性来重写equals()和hashCode()方法。
例子:
1)Person.java
public class Personimplements java.io.Serializable{//定义first属性,作为标识属性的成员private String first;//定义last属性,作为标识属性的成员private String last;//普通属性ageprivate int age;//...//重写equals方法,根据first、last进行判断public boolean equals(Object obj){if (this == obj){return true;}if (obj != null && obj.getClass() == Person.class){Person target = (Person)obj;if (target.getFirst().equals(getFirst())&& target.getLast().equals(getLast())){return true;}}return false;}//重写hashCode方法,根据first、last计算hashCode值public int hashCode(){return getFirst().hashCode() * 13+ getLast().hashCode();}}
如需映射first和last两个标识属性,同样使用<composite-id.../>元素,此时的<composite-id.../>元素不需要name和class属性。
2)Person.hbm.xml<?xml version="1.0" encoding="GBK"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"><hibernate-mapping package="org.crazyit.app.domain"><class name="Person" table="person_inf"><!-- 直接使用composite-id映射多列联合主键 --><composite-id><!-- 映射组件主键里的各属性 --><key-property name="first" type="string"/><key-property name="last" type="string"/></composite-id><!-- 映射普通属性 --><property name="age" type="int"/></class></hibernate-mapping>
- 第5章Hibernate的基本用法 5.7映射组件属性
- 第5章 Hibernate的基本用法 5.2 Hibernate入门
- Hibernate 映射组件属性
- hibernate映射组件属性
- Hibernate 映射组件属性
- hibernate映射组件属性
- Hibernate映射组件属性
- 5.7 映射组件属性:组件属性的子属性为基本类型
- Hibernate 基本映射与组件映射
- Hibernate映射组件(对象)、组件集合属性
- Hibernate的组件映射
- 第5章 HIbernate的基本用法 5.3Hibernate的体系结构
- 第5章Hibernate的基本用法 5.4深入Hibernate的配置文件
- Hibernate:组件属性和关联映射的区别
- Hibernate:组件属性和关联映射的区别
- 第5章 Hibernate的基本用法 5.1 ORM和Hibernate
- 5.7 映射组件属性:集合属性的元素为组件
- 第28章:ProgressBar的基本属性和用法o
- 文章标题
- 结构体作为函数形参(三种方法)
- 选择排序和归并排序
- 富人跟穷人的区别
- 设计模式
- 第5章Hibernate的基本用法 5.7映射组件属性
- C#将原工程中的WinForm窗体添加到新工程中
- 一语双关
- Java的位运算符详解实例——与(&)、非(~)、或(|)、异或(^)
- 使用jersey(2.5.1)编写Java REST客户端
- Android 的陷阱(1) 静态变量
- WIFI模块AT指令:
- SQL Server之视图
- pat1030Travel Plan (30)