表示XML中的数据
XML只是一种文本文件格式;它没有成为数据存储或者数据管理的媒介的继承能力。XML数据模型是脆弱的,它的类型系统复杂且低能,它的数据完整性几乎完全程序化,并且它还引入了几十年前就淘汰了的分层数据结构。然而,XML格式的数据对于在Java中使用却很在吸引力;因为我们有一些好工具。例如,可以用XSLT转换XML数据,这是我们认为最佳的使用案例之一。Hibernate没有内建的功能来存储XML格式的数据;它依赖于关系表示和SQL,这种策略的好处应该很清楚。另一方面,Hibernate能够以XML格式把数据加载和呈现给应用程序的开发人员,它允许你使用一组复杂的工具,而无需任何额外的转换步骤。
假设你在默认的POJO模式下工作,并且很快想要获得一些以XML表示的数据。用EntityMode.DOM4J打开一个临时的Session:
Session dom4jSession = session.getSession(EntityMode.DOM4J); Element userXML = (Element) dom4jSession.get(UserPojo.class,new Long(1));此处返回的是一个dom4j Element,可以用这个dom4j API来读取和操作它。例如,可以用下列片段把它很漂亮地打印到控制台:
try { OutputFormat format = OutputFormat.createPrettyPrint(); XMLWriter writer = new XMLWriter(System.out, format); writer.write(userXML); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }假设你重用来自前面那些例子中的POJO类和数据,你会看到一个UserPojo实例和两个ItemPojo实例。
<UserPojo> <id>1</id> <username>zhangsan</username> <itemsForSale> <Item> <id>2</id> <initialPrice>99</initialPrice> <description>An item for auction</description> <seller>1</seller> </Item> <Item> <id>3</id> <initialPrice>1000</initialPrice> <description>Another item for auction</description> <seller>1</seller> </Item> </itemsForSale> </UserPojo>注意:此时,如果你运行,应该会报错JVM溢出异常,解决方案
1)一方集合设置embed-xml="true"(是否包含xml,Yes)
2)多方设置embed-xml="false"(是否包含xml,No)
可以通过把node属性添加到Hibernate映射元数据来改变这个默认的XML表示法:
<hibernate-mapping package="cn.jbit.entity"> <class name="ItemPojo" table="TBL_ITEM_ENTITY" node="item"> <id name="id" column="ITEM_ID" type="long" node="@id"> <generator class="sequence"> <param name="sequence">SEQ_ITEM_ENTITY_ID</param> </generator> </id> <property name="initialPrice" type="big_decimal" column="INIT_PRICE" node="item-details/@inital-price" /> <property name="description" type="string" column="DESCRIPTION" node="item-details/@description" /> <many-to-one name="seller" class="UserPojo" column="USER_ID" embed-xml="false" node="@seller-id" /> </class> <class name="UserPojo" table="TBL_USER_ENTITY"> <id name="id" column="USER_ID" type="long" node="@id"> <generator class="sequence"> <param name="sequence">SEQ_USER_ENTITY_ID</param> </generator> </id> <property name="username" type="string" column="UNAME" node="@username" /> <bag name="itemsForSale" inverse="true" cascade="all" embed-xml="true" node="item-for-sale"> <key column="USER_ID" /> <one-to-many class="ItemPojo" /> </bag> </class> </hibernate-mapping>每一个node属性都定义了XML表示法:
1)<class>映射中的node="name"属性,给该实体定义了XML元素的名称。
2)任何属性映射中的node="name"属性,指定属性内容应该表示为给定名称的XML元素文本。
3)任何属性映射中的node="@name"属性,指定属性内容应该表示为给定名称的XML属性值。
4)任何属性映射中的node="name/@attname"属性,指定属性内容应该在给定名称的一个子元素中表示为给定名称的XML属性值。
更新过的映射产生下列你之前已经见过的相同数据的XML表示法:
<UserPojo id="1" username="zhangsan"> <item-for-sale> <item id="1" seller-id="1"> <item-details inital-price="100" description="description 1"/> </item> <item id="2" seller-id="1"> <item-details inital-price="400045" description="description 2"/> </item> </item-for-sale> </UserPojo>最后,以XML表示的数据是事务和持久化的,因此你可以修改被查询的XML元素,并让Hibernate更新底层的表:
Element itemXML = (Element) dom4jSession.get(ItemPojo.class,new Long(2)); itemXML.element("item-details").attribute("inital-price").setValue("100000"); dom4jSession.flush();//Hibernate executes UPDATES 可以理解为本来应该延迟至事务提交修改,而现在立刻执行修改 Element userXML = (Element) dom4jSession.get(UserPojo.class,new Long(1)); Element newItem = DocumentHelper.createElement("item"); Element newItemDetails = newItem.addElement("item-details"); newItem.addAttribute("seller-id", userXML.attribute("id").getValue());// 设置关联关系 // 添加商品详细信息 newItemDetails.addAttribute("inital-price", "9999"); newItemDetails.addAttribute("description", "描述信息"); dom4jSession.save(Item.class.getName(), newItem); dom4jSession.flush();最后,注解如果你喜欢,可以同时使用所有三种内建的实体模式。可以映射领域模型的一个静态的POJO实现,为一般的用户界面切换到动态的映射,并把数据导到XML里面。或者,可以编写一个没有任何领域类的应用,只有动态的映射和XML。可是,必须提醒你,软件行业中的原型经常意味着,客户以这个没有人想要抛弃的原型而告终——你愿意买一辆样板车吗?强烈建议你依赖静态的领域模型,如果要创建可维护的系统的话。
后面不再考虑动态的模型或者XML表示法。焦点放在了静态的持久化类以及它们的映射方式上。
总结一下:
学到后面,感觉概念有点稍多,又是一个人独自学的,进度可能有点慢哦哦。这章内容,主要有领域模型分离横切关注点,接着就是实体编程模型(POJO、JPA实体编程模型),有了模型,当然是选择映射方式咯(1、XML映射文件 2、JDK 5.0注解 3、XDoclet),还有像XML映射元数据可以被全局定义,XML点位符的使用等等。。。可以说东西很多,希望大家也能好好掌握。