Spring Batch:数据库到XML问题

时间:2013-05-15 14:00:33

标签: xml spring spring-batch xstream

我有一个简单的spring批处理程序,它从数据库表读取并使用下面的默认XStreamMarshaller编写器类形成输出XML

org.springframework.oxm.xstream.XStreamMarshaller 

我读取输入的数据库表TOY包含两列:TOY_NAME,TOY_COLOR

对于单个TOY,可能有多个不同颜色的条目。

例如对于TOY CAR和TOY BUS,数据库条目如下:

TOY_NAME   |    TOY_COLOR
--------------------------
 CAR       |    RED
 CAR       |    YELLOW
 CAR       |    BLUE
 BUS       |    RED
 BUS       |    YELLOW
--------------------------

将传递给ROW MAPPER的结果集将是5行,每行有两列即。 toy_name和color。

我的java域对象包含一个包含TOY对象列表的主对象TOYS。

TOY对象本身包含两个字段即。 toyName和String toyColor列表。

我的输出XML具有简单的读写配置如下:

<TOYS>

   <TOY>
       <NAME>CAR</NAME>
       <COLORS>
         <COLOR>RED</COLOR>
       </COLORS>
   </TOY>

   <TOY>
       <NAME>CAR</NAME>
       <COLORS>
         <COLOR>YELLOW</COLOR>
       </COLORS>
   </TOY>

   <TOY>
       <NAME>CAR</NAME>
       <COLORS>
         <COLOR>BLUE</COLOR>
       </COLORS>
   </TOY>

   <TOY>
       <NAME>BUS</NAME>
       <COLORS>
         <COLOR>RED</COLOR>
       </COLORS>
   </TOY>

   <TOY>
       <NAME>BUS</NAME>
       <COLORS>
         <COLOR>BLUE</COLOR>
       </COLORS>
   </TOY>

</TOYS>

从上面可以清楚地看到,对于结果集的每一行,都会创建一个单独的TOY​​节点。

但是,我想要输出如下:

<TOYS>

   <TOY>
       <NAME>CAR</NAME>
       <COLORS>
         <COLOR>RED</COLOR>
         <COLOR>YELLOW</COLOR>
         <COLOR>BLUE</COLOR>
       </COLORS>
   </TOY>

   <TOY>
       <NAME>BUS</NAME>
       <COLORS>
         <COLOR>RED</COLOR>
         <COLOR>BLUE</COLOR>
       </COLORS>
   </TOY>

 </TOYS>

即 - 对于每个TOY,只应创建一个包含该特定TOY的所有颜色的TOY节点。

如何根据我的结果集在READER(或ROW MAPPER)中处理此要求?

有没有办法调整我的阅读器sql以满足上述场景?

我当前的sql(生成第一个xml)是:

SELECT TOY_NAME, TOY_COLOR FROM TOY ORDER BY TOY_NAME

感谢阅读!

1 个答案:

答案 0 :(得分:0)

我不会在您的域对象玩具中使用List,而是尝试使用带有key = name的Map。在你的读者和作者之间,我会实现一个ItemProcessor,试图从地图中获取玩具对象并将addColor()添加到它,然后将其放回地图中。

所以在你的例子中,你最终会得到

[car,[toy[name=car,colors={blue,red,yellow}]]    
[bus,[toy[name=bus,colors={blue,red}]]

然后XStream将编写您需要的输出。 (您可能必须使用转换器)

这只适用于一个小的resultSet ......那么一个resultSet samller然后你的commit-interval。因为如果你的resultSet大于你的提交间隔,你将无法访问你的地图,你最终可能会有多个

<TOY><name="car">

这个合并之王的问题在于,在将其刷新到磁盘之前,必须在内存中构建所有XML文档!

如果我想到更好的东西,我会编辑。

编辑:哦,你也可以使用GROUP BY名称和CONCAT颜色

这会给你

car | blue,yellow,red
bus | red,blue

然后您可以使用ItemProcessor来获取此字符串:蓝色,黄色,红色并提取每种颜色以将其添加到您的域对象颜色列表中。

祝你好运