添加映射的过程
在Configuration类中,我们通过add方法添加一个映射,而add方法又把这个任务交给了Binder类的bindrooR方法。
protected void add(org.dom4j.Document doc) throws Exception {
try {
Binder.bindRoot( doc, createMappings() );
}
catch (MappingException me) {
log.error("Could not compile the mapping document", me);
throw me;
}
}
try {
Binder.bindRoot( doc, createMappings() );
}
catch (MappingException me) {
log.error("Could not compile the mapping document", me);
throw me;
}
}
首先,我们来看一段映射配置:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="net.sf.hibernate.examples.quickstart.Cat" table="CAT">
<!-- A 32 hex character is our surrogate key. It's automatically
generated by Hibernate with the UUID pattern. -->
<id name="id" type="string" unsaved-value="null" >
<column name="CAT_ID" sql-type="char(32)" not-null="true"/>
<generator class="uuid.hex"/>
</id>
<!-- A cat has to have a name, but it shouldn' be too long. -->
<property name="name">
<column name="NAME" sql-type="varchar(16)" not-null="true"/>
</property>
<property name="sex"/>
<property name="weight"/>
</class>
</hibernate-mapping>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="net.sf.hibernate.examples.quickstart.Cat" table="CAT">
<!-- A 32 hex character is our surrogate key. It's automatically
generated by Hibernate with the UUID pattern. -->
<id name="id" type="string" unsaved-value="null" >
<column name="CAT_ID" sql-type="char(32)" not-null="true"/>
<generator class="uuid.hex"/>
</id>
<!-- A cat has to have a name, but it shouldn' be too long. -->
<property name="name">
<column name="NAME" sql-type="varchar(16)" not-null="true"/>
</property>
<property name="sex"/>
<property name="weight"/>
</class>
</hibernate-mapping>
我们结合这个映射配置文件来看看bindRoot方法(由于方法过长,这里只截取其中处理class的一部分):
/**
* 传入一个描述映射关系的Document用以填充Mapping
*/
public static void bindRoot(Document doc, Mappings model) throws MappingException {
// 取得根结点,即 hibernate-mapping 结点
Element hmNode = doc.getRootElement();
// 取结点的属性值
Attribute schemaNode = hmNode.attribute("schema");
model.setSchemaName( (schemaNode==null) ? null : schemaNode.getValue() );
//
// 取得所有的class子结点。
// 由此可以看出,一个配置文件可以配置多个class的映射。
Iterator nodes = hmNode.elementIterator("class");
while ( nodes.hasNext() ) {
Element n = (Element) nodes.next();
// 至此为止,又将权利下放到了bindRootClass方法。
// 这是重构长方法的一种办法。
RootClass rootclass = new RootClass();
Binder.bindRootClass(n, rootclass, model);
model.addClass(rootclass);
}
//
}
* 传入一个描述映射关系的Document用以填充Mapping
*/
public static void bindRoot(Document doc, Mappings model) throws MappingException {
// 取得根结点,即 hibernate-mapping 结点
Element hmNode = doc.getRootElement();
// 取结点的属性值
Attribute schemaNode = hmNode.attribute("schema");
model.setSchemaName( (schemaNode==null) ? null : schemaNode.getValue() );
//
// 取得所有的class子结点。
// 由此可以看出,一个配置文件可以配置多个class的映射。
Iterator nodes = hmNode.elementIterator("class");
while ( nodes.hasNext() ) {
Element n = (Element) nodes.next();
// 至此为止,又将权利下放到了bindRootClass方法。
// 这是重构长方法的一种办法。
RootClass rootclass = new RootClass();
Binder.bindRootClass(n, rootclass, model);
model.addClass(rootclass);
}
//
}
所有读取配置信息的工作都是使用上面这种模式:一步一步地把责任往下放,这种做法好处就在于使程序结构清晰,可惜在Binder类中做的还是不够——方法还是太长。
因为后面的代码牵涉到的内容还太多,所以暂时跟踪到此,待mapping包分析完成再来看它。