Professional Hibernate第5章读书笔记
2006-08-07 01:30
232 查看
这一章介绍的内容很多,不像前面几章,我可以每天一章 ,这章我就放慢了脚步,用了3天的时间看完,因为这章确实也比较的重要。
这章的题目是Creating Persistent Classes。Hibernate里面核心问题之一。为了能把oop中的所有特性完全的映射到关系数据库里面,hibernate用了很多的方法。从这一章开始就是一一的开始讲解。
在持久化的时候要注意以下几点:
Hibernate只持久那些在mapping documet里面出现的属性,所以你就可以在类里面自由定义临时的属性,这些属性在Hibernate从数据库里面load对象的时候将消失。
所有要被持久的属性都要声明为private,有setter和getter,遵从javabean规范。setter和getter不必声明为public,你可以声明为protected甚至private,因为Hibernate会利用反射机制来找到他们。
所有的要持久化的类都必须定义id属性,方便Hibernate和数据库定义主键
所有要被持久化的类要定义一个默认的构造函数。
下面就来说下映射一个类时的要做的具体的事情:
首先你要建立一个mapping document,Hibernate用这个xml文件来定义如何将Java class映射到数据库的表里面,mapping document的命名一般就是PersistedClassName.hbm.xml。
mapping document有一个root element-<hibernate-mapping>,里面有一个package属性值得注意一下,定义了package属性,这个映射文件将以定义的目录来找要持久的类。比如:<hibernate-mapping package="example.code">.这样下面的class element的name属性将以example.code为根目录去查找所需要的类。
class tag就描述了要被持久类。比较重要的属性是name--类的路径,table--数据库里面对应的表。如:<class name="example.products.Book" table="books">
id tag是class的subelement,定义了这个类的id属性,前面已经说了每个要持久的类都必须有个id属性。这个tag比较重要的属性是name--id的名字,unsaved-value--当一个对象被实例化时id属性的值,Hibernate用这个值来判断这个对象是应该save(insert into..)还是update(update table...)。id element还有个<generator>subelement,这个element比较重要的属性是class--生成id所用到的方案。
<property>描述了Java class里面要被持久的属性,比较重要的属性是name--属性的名字,not-null--是否可以为null,column--对应到表里面的列,type--数据的类型。当type没有指明的时候,Hibernate会用到反射机制来确定数据的类型,当column没指明的时候,将把此属性持久到表里面和name相同的列。<property>还可以有一个subelement就是column,功能和属性column差不多,只不过可以通过<column sql-type="">来定义sql数据类型。
下面帖出一个mapping dcument例子来:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="example.products.Book" table="books">
<id name="id"
type="int"
unsaved-value="0">
<generator class="hilo"/>
</id>
<property name="title"/>
<property name="author"/>
<property name="isbn"
not-null="true"/>
<property name="pages"
type="integer"
column="pagecount" />
<property name="copyright"/>
<property name="cost">
<column name="cost"
sql-type="NUMERIC(12,2)"/>
</property>
</class>
</hibernate-mapping>
比较基本的类的映射文件可以通过这些来描述持久化,当然还有一些其他特殊的东西会出现,比如持久一个2进制数据等等。。。。
持久一个2进制属性:只要javabean class的类的相关属性定义为Bolb数据类型,然后映射文件里这样定义这个属性:<property name="data"
type="binary">
<column name="data"
sql-type="blob"/>
</property> type--为binary,sql-type为blob。
持久一个串行化属性:大部分情况下,持久一个object,你要指明这个object所属类的属性,添加到配置文件里面。Hibernate取出数据库里面存放的object是这样完成的,首先实例化一个新的object,然后把数据库一行里存放的属性数据取出放到新实例化的object对应的属性里。还有另外一个办法,就是用Serializable接口。我们可以这样定义一个<property>来实现他:
<property name="ivalue" type="serializable" >
<column name="value" sql-type="blob"/>
</property>
ivalue属性的type改成serializable,而不是java class里面声明的type,这样Hibernate会串行化这个属性(也就是这个object),sql-type也要相应的改成blob。
注意,这种方法只能用在Java application中。
映射一个Data/Calendar属性:
private Date setupdate;
<property name="setupdate">
<column name="setup" sql-type="Date"/>
</property>
映射一个只读类:
<class name="example.util.Support" table="support" mutable="false">
映射一个version/timestamp属性:
private int version;
<version name="version"
column="version"
type="integer"
unsaved-value="undefined"/>和id element差不多。
private Timestamp timestamp;
<timestamp name="timestamp"
column="stamp"
unsaved-value="undefined"/>
好了,现在要来说下非常重要的一部分了。。。。。
持久有继承关系的类:
持久有继承关系的类有以下3种方案:
Table-per-class hierarchy
Table-per-subclass
Table-per-concrete class
第一种方案是一个继承链上的所有类被持久化到一个表里面。这样就要从继承链最低层的类开始,将所有出现过的属性都放到一个table里面,然后用一个<discriminator>元素来定义一个列用来区分是哪一个类被持久化的。
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping package="example.products">
<classname="CD" table="cd" discriminator-value="cd">
<id name="id" type="integer" unsaved-value="0">
<generator class="hilo"/>
</id>
<discriminator column="cd_type" type= "string"/>
<property name="title"/>
<property name="artist"/>
<property name="purchasedate" type="date"/>
<property name="cost" type="double"/>
<subclass name="SpecialEditionCD" discriminator-value="SpecialEditionCD">
<property name="newfeatures" type="string"/>
</subclass>
<subclass name="InternationalCD" discriminator-value="InternationalCD">
<property name="languages"/>
<property name="region"/>
</subclass>
</class>
</hibernate-mapping>
注意红色的部分,<class/subclass .....discriminator-value="">定义了这个类的标识值,<discriminator column....>定义了表里面分辨是哪个类的列名,这个列里面的值则是<class/subclass .....discriminator-value="">里面定义的。
第2中方案是每个类一张表,但是父类的所有要持久的属性将被映射到对应的表里面,而子类表里面只有自己特殊的属性。
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping package="example.products">
<class name="CD" table="cd">
<id name="id" type="integer" unsaved-value="0">
<generator class="hilo"/>
</id>
<property name="title"/>
c795
;
<property name="artist"/>
<property name="purchasedate" type="date"/>
<property name="cost" type="double"/>
<joined-subclass name="SpecialEditionCD" table="secd">
<key column="id"/>
<property name="newfeatures" type="string"/>
</joined-subclass>
<joined-subclass name="InternationalCD" table="icd">
<key column="id"/>
<property name="languages"/>
<property name="region"/></joined-subclass>
</class>
</hibernate-mapping>
<key>tag指明了父类的哪个属性用来指明父子关系。<key>tag还可以用来定义外键。
第3种方案是不管是父类还是子类,都建一个完整的表,第2种方案是父类的表里面有子类的部分属性信息,而第3种方案则是哪个类被持久了,所有的属性都在所对应的表里面存储。
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping package="example.products">
<class name="CD" table="cd" discriminator-value="cd">
<id name="id" type="integer" unsaved-value="0">
<generator class="hilo"/>
</id>
<property name="title"/>
<property name="artist"/>
<property name="purchasedate" type="date"/>
<property name="cost" type="double"/>
</class>
<class name="SpecialEditionCD" table="secd">
<id name="id" type="integer" unsaved-value="0">
<generator class="hilo"/>
</id>
<property name="title"/>
<property name="artist"/>
<property name="purchasedate" type="date"/>
<property name="cost" type="double"/>
<property name="newfeatures" type="string"/></class>
<class name="InternationalCD" table="icd">
<id name="id"type="integer" unsaved-value="0">
<generator class="hilo"/>
</id>
<property name="title"/>
<property name="artist"/>
<property name="purchasedate" type="date"/>
<property name="cost" type="double"/>
<property name="languages"/>
<property name="region"/>
</class>
</hibernate-mapping>
这章的题目是Creating Persistent Classes。Hibernate里面核心问题之一。为了能把oop中的所有特性完全的映射到关系数据库里面,hibernate用了很多的方法。从这一章开始就是一一的开始讲解。
在持久化的时候要注意以下几点:
Hibernate只持久那些在mapping documet里面出现的属性,所以你就可以在类里面自由定义临时的属性,这些属性在Hibernate从数据库里面load对象的时候将消失。
所有要被持久的属性都要声明为private,有setter和getter,遵从javabean规范。setter和getter不必声明为public,你可以声明为protected甚至private,因为Hibernate会利用反射机制来找到他们。
所有的要持久化的类都必须定义id属性,方便Hibernate和数据库定义主键
所有要被持久化的类要定义一个默认的构造函数。
下面就来说下映射一个类时的要做的具体的事情:
首先你要建立一个mapping document,Hibernate用这个xml文件来定义如何将Java class映射到数据库的表里面,mapping document的命名一般就是PersistedClassName.hbm.xml。
mapping document有一个root element-<hibernate-mapping>,里面有一个package属性值得注意一下,定义了package属性,这个映射文件将以定义的目录来找要持久的类。比如:<hibernate-mapping package="example.code">.这样下面的class element的name属性将以example.code为根目录去查找所需要的类。
class tag就描述了要被持久类。比较重要的属性是name--类的路径,table--数据库里面对应的表。如:<class name="example.products.Book" table="books">
id tag是class的subelement,定义了这个类的id属性,前面已经说了每个要持久的类都必须有个id属性。这个tag比较重要的属性是name--id的名字,unsaved-value--当一个对象被实例化时id属性的值,Hibernate用这个值来判断这个对象是应该save(insert into..)还是update(update table...)。id element还有个<generator>subelement,这个element比较重要的属性是class--生成id所用到的方案。
<property>描述了Java class里面要被持久的属性,比较重要的属性是name--属性的名字,not-null--是否可以为null,column--对应到表里面的列,type--数据的类型。当type没有指明的时候,Hibernate会用到反射机制来确定数据的类型,当column没指明的时候,将把此属性持久到表里面和name相同的列。<property>还可以有一个subelement就是column,功能和属性column差不多,只不过可以通过<column sql-type="">来定义sql数据类型。
下面帖出一个mapping dcument例子来:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="example.products.Book" table="books">
<id name="id"
type="int"
unsaved-value="0">
<generator class="hilo"/>
</id>
<property name="title"/>
<property name="author"/>
<property name="isbn"
not-null="true"/>
<property name="pages"
type="integer"
column="pagecount" />
<property name="copyright"/>
<property name="cost">
<column name="cost"
sql-type="NUMERIC(12,2)"/>
</property>
</class>
</hibernate-mapping>
比较基本的类的映射文件可以通过这些来描述持久化,当然还有一些其他特殊的东西会出现,比如持久一个2进制数据等等。。。。
持久一个2进制属性:只要javabean class的类的相关属性定义为Bolb数据类型,然后映射文件里这样定义这个属性:<property name="data"
type="binary">
<column name="data"
sql-type="blob"/>
</property> type--为binary,sql-type为blob。
持久一个串行化属性:大部分情况下,持久一个object,你要指明这个object所属类的属性,添加到配置文件里面。Hibernate取出数据库里面存放的object是这样完成的,首先实例化一个新的object,然后把数据库一行里存放的属性数据取出放到新实例化的object对应的属性里。还有另外一个办法,就是用Serializable接口。我们可以这样定义一个<property>来实现他:
<property name="ivalue" type="serializable" >
<column name="value" sql-type="blob"/>
</property>
ivalue属性的type改成serializable,而不是java class里面声明的type,这样Hibernate会串行化这个属性(也就是这个object),sql-type也要相应的改成blob。
注意,这种方法只能用在Java application中。
映射一个Data/Calendar属性:
private Date setupdate;
<property name="setupdate">
<column name="setup" sql-type="Date"/>
</property>
映射一个只读类:
<class name="example.util.Support" table="support" mutable="false">
映射一个version/timestamp属性:
private int version;
<version name="version"
column="version"
type="integer"
unsaved-value="undefined"/>和id element差不多。
private Timestamp timestamp;
<timestamp name="timestamp"
column="stamp"
unsaved-value="undefined"/>
好了,现在要来说下非常重要的一部分了。。。。。
持久有继承关系的类:
持久有继承关系的类有以下3种方案:
Table-per-class hierarchy
Table-per-subclass
Table-per-concrete class
第一种方案是一个继承链上的所有类被持久化到一个表里面。这样就要从继承链最低层的类开始,将所有出现过的属性都放到一个table里面,然后用一个<discriminator>元素来定义一个列用来区分是哪一个类被持久化的。
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping package="example.products">
<classname="CD" table="cd" discriminator-value="cd">
<id name="id" type="integer" unsaved-value="0">
<generator class="hilo"/>
</id>
<discriminator column="cd_type" type= "string"/>
<property name="title"/>
<property name="artist"/>
<property name="purchasedate" type="date"/>
<property name="cost" type="double"/>
<subclass name="SpecialEditionCD" discriminator-value="SpecialEditionCD">
<property name="newfeatures" type="string"/>
</subclass>
<subclass name="InternationalCD" discriminator-value="InternationalCD">
<property name="languages"/>
<property name="region"/>
</subclass>
</class>
</hibernate-mapping>
注意红色的部分,<class/subclass .....discriminator-value="">定义了这个类的标识值,<discriminator column....>定义了表里面分辨是哪个类的列名,这个列里面的值则是<class/subclass .....discriminator-value="">里面定义的。
第2中方案是每个类一张表,但是父类的所有要持久的属性将被映射到对应的表里面,而子类表里面只有自己特殊的属性。
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping package="example.products">
<class name="CD" table="cd">
<id name="id" type="integer" unsaved-value="0">
<generator class="hilo"/>
</id>
<property name="title"/>
c795
;
<property name="artist"/>
<property name="purchasedate" type="date"/>
<property name="cost" type="double"/>
<joined-subclass name="SpecialEditionCD" table="secd">
<key column="id"/>
<property name="newfeatures" type="string"/>
</joined-subclass>
<joined-subclass name="InternationalCD" table="icd">
<key column="id"/>
<property name="languages"/>
<property name="region"/></joined-subclass>
</class>
</hibernate-mapping>
<key>tag指明了父类的哪个属性用来指明父子关系。<key>tag还可以用来定义外键。
第3种方案是不管是父类还是子类,都建一个完整的表,第2种方案是父类的表里面有子类的部分属性信息,而第3种方案则是哪个类被持久了,所有的属性都在所对应的表里面存储。
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping package="example.products">
<class name="CD" table="cd" discriminator-value="cd">
<id name="id" type="integer" unsaved-value="0">
<generator class="hilo"/>
</id>
<property name="title"/>
<property name="artist"/>
<property name="purchasedate" type="date"/>
<property name="cost" type="double"/>
</class>
<class name="SpecialEditionCD" table="secd">
<id name="id" type="integer" unsaved-value="0">
<generator class="hilo"/>
</id>
<property name="title"/>
<property name="artist"/>
<property name="purchasedate" type="date"/>
<property name="cost" type="double"/>
<property name="newfeatures" type="string"/></class>
<class name="InternationalCD" table="icd">
<id name="id"type="integer" unsaved-value="0">
<generator class="hilo"/>
</id>
<property name="title"/>
<property name="artist"/>
<property name="purchasedate" type="date"/>
<property name="cost" type="double"/>
<property name="languages"/>
<property name="region"/>
</class>
</hibernate-mapping>
相关文章推荐
- 《ERP从内部集成起步》读书笔记——第5章 MRP系统的时间概念 5.1 时间三要素 5.1.4 时区与定单状态
- 《ERP从内部集成起步》读书笔记——第5章 MRP系统的时间概念 5.2 提前期
- 读书笔记-高质量C++/C编程指南-第5章 常量
- 《Essential Guide》读书笔记【4】 【第5章】
- <从0到1》读书笔记第5章“后发优势”第2记:打造垄断企业技术小结
- pandas入门 《利用Python进行数据分析》读书笔记 第5章
- 《浪潮之巅》读书笔记——第5章 Intel
- 《ERP从内部集成起步》读书笔记——第5章 MRP系统的时间概念 5.2 五种作业时间
- 《TCP/IP详解 卷1:协议》 读书笔记 第5章 RARP:逆地址解析协议
- 《Flask Web开发》读书笔记(5)第5章数据库(关键词:Web开发/Flask/数据库)
- 《Android源码设计模式》读书笔记 (5) 第5章 工厂模式
- 《Java并发编程实战》读书笔记-第5章 基础构建模块
- 深入实践c++模板编程 第5章,容器、迭代器与算法。读书笔记。
- 《Unix环境高级编程》读书笔记 第5章-标准I/O流
- 《ERP从内部集成起步》读书笔记——第5章 MRP系统的时间概念 5.1 时间三要素 5.1.2 时段
- <从PAXOS到ZOOKEEPER分布式一致性原理与实践>读书笔记-第5章zookeeper使用
- STL源码分析读书笔记--第5章--关联式容器
- java读书笔记-《java设计模式》-第5章 - 合成模式
- 《编写可维护的JavaScript》读书笔记第5章:UI层的松耦合
- 《COM技术内幕》读书笔记——第5章 动态连接