我需要使用这种结构将一些数据库表的内容转储到XML文件中
<dump>
<table name="tableName1">
<records>
<record>
<first column name>value</first column name>
<second column name>value</second column name>
<third column name>value</third column name>
</record>
<record>...</record>
</records>
</table>
<table name="tableName2">...</table>
</dump>
每个表在未知状态下的真实记录数,因此我无法将单个表的所有数据存储在内存中并转储到XML。
我的工作现在定义为:
<job id="dump-database-job">
<step id="dumpTables">
<tasklet>
<chunk reader="dumpReader" processor="dumpProcessor" writer="dumpWriter" commit-interval="100" />
</tasklet>
</step>
</job>
<bean name="dumpProcessor" class="RecordBeanToJaxbElementProcessor" />
<bean name="dumpReader" class="CompositeItemReader">
<property name="delegates">
<array>
<ref bean="TABLE_ONE_Reader" />
<ref bean="TABLE_TWO_Reader" />
<ref bean="TABLE_NTH_Reader" />
<!-- Other delegates omitted,one for table,for brevity... -->
</array>
</property>
<property name="name" value="dumpReader" />
</bean>
<bean name="TABLE_ONE_Reader" class="JdbcCursorItemReader">
<property name="rowMapper">
<bean name="rowMapper" class="RecordBeanRowMapper">
<property name="tableName=" value="TABLE_ONE" />
</bean>
</property>
<!--other mandatory property omitted -->
</bean>
<bean name="dumpWriter" class="StaxEventItemWriter" scope="step">
<property name="resource" value="file:#{jobParameters['outfile']}" />
<property name="shouldDeleteIfEmpty" value="true" />
<property name="marshaller" ref="marshaller" />
<property name="overwriteOutput" value="true" />
<property name="rootTagName" value="dump" />
</bean>
<bean name="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="supportJaxbElementClass" value="true" />
<property name="classesToBeBound">
<array>
<value>RecordBean</value>
</array>
</property>
</bean>
public class RecordBeanRowMapper implements RowMapper<RecordBean> {
final static RowMapper<Map<String, Object>> columnMapRowMapper = new ColumnMapRowMapper();
private String tableName;
public void setTableName(String tableName) {
this.tableName = tableName;
}
@Override
public RecordBean mapRow(ResultSet rs, int rowNum) throws SQLException {
final RecordBean b = new RecordBean();
b.setTableName(tableName);
b.setColumnValues(Maps.transformValues(columnMapRowMapper.mapRow(rs, rowNum), new Function<Object, String>() {
@Override
public String apply(Object input) {
return (input == null ? "NULL" : input.toString();
}
}
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(namespace="")
class RecordBean {
private String tableName;
@XmlJavaTypeAdapter
/* Entries are written using an adapter to write data as
* <key>value</key>
* <key>value</key>
* ...
*/
public Map<String,String> entries = new HashMap<String,String>();
}
/* Use to build item node name using dynamic tableName as
* <tableName>
* <key>value</key>
* <key>value</key>
* </tableName>
*/
public class RecordBeanToJaxbElementProcessor implements ItemProcessor<RecordBean, JAXBElement<?>> {
@Override
public JAXBElement<?> process(RecordBean item) throws Exception {
return new JAXBElement<RecordBean>(new QName(item.getTableName()), RecordBean.class, item);
}
}
这项工作不完整,无法满足我的需求,因为输出看起来像
<?xml version="1.0" encoding="UTF-8"?>
<dump>
<!-- First record of table TABLE_ONE -->
<TABLE_ONE>
<code>Code one</code>
<description>A record</description>
<agomappedtable>xyz</agomappedtable>
<enumcode>NULL</enumcode>
<is_persistent>false</is_persistent>
<keep_history_data>false</keep_history_data>
</TABLE_ONE>
<!-- Other tons from TABLE_ONE -->
<!-- First record of table TABLE_TWO -->
<TABLE_TWO>
<code>Code 2</code>
<description>Another record</description>
<his_name>no_name</his_name>
</TABLE_TWO>
<!-- Other tons from TABLE_TWO -->
<!-- More tables... -->
</dump>
我认为我必须丰富作家和/或编组人员的组件才能实现我的目标,但我还没有找到继续前进的好方法:(
我的问题是:
如何按照开始时所述构建复杂的XML结构,并使作业完全可重新启动并且占用较少的内存?
摘自spring.io [论坛]
默认的StaxEventItemWriter可能没有此html" target="_blank">功能。我必须为我的一个项目做类似的事情,并编写了一个自定义的GroupingStaxEventItemWriter。请参见下面的代码。您需要针对特定用例修改openGroup和closeGroup方法。请注意,通过直接写入基础java.io.Writer而不是通过XMLEventWriter来关闭分组标记。这是重新启动性所必需的。
public class GroupingStaxEventItemWriter<T> extends StaxEventItemWriter<T> {
private static final String GROUP_IDENTIFIER = "CURRENT_GROUP";
private Classifier<T, String> classifier;
private String currentGroup;
private XMLEventWriter eventWriter;
private Writer writer;
@Override
public void write(List<? extends T> items) throws XmlMappingException, Exception {
Map<String, List<T>> itemsGroup = new LinkedHashMap<String, List<T>>();
for (T item : items) {
String group = classifier.classify(item);
if (!itemsGroup.containsKey(group)) {
itemsGroup.put(group, new ArrayList<T>());
}
itemsGroup.get(group).add(item);
}
for (String group : itemsGroup.keySet()) {
if (group == null || !group.equals(currentGroup)) {
if (currentGroup != null) {
closeGroup(currentGroup);
}
currentGroup = group;
if (currentGroup != null) {
openGroup(currentGroup);
}
}
super.write(itemsGroup.get(group));
}
}
protected void openGroup(String group) throws XMLStreamException, FactoryConfigurationError {
String groupTagName = group;
String groupTagNameSpacePrefix = "";
String groupTagNameSpace = null;
if (groupTagName.contains("{")) {
groupTagNameSpace = groupTagName.replaceAll("\\{(.*)\\}.*", "$1");
groupTagName = groupTagName.replaceAll("\\{.*\\}(.*)", "$1");
if (groupTagName.contains(":")) {
groupTagNameSpacePrefix = groupTagName.replaceAll("(.*):.*", "$1");
groupTagName = groupTagName.replaceAll(".*:(.*)", "$1");
}
}
XMLEventFactory xmlEventFactory = createXmlEventFactory();
eventWriter.add(xmlEventFactory.createStartElement(groupTagNameSpacePrefix, groupTagNameSpace, groupTagName));
}
protected void closeGroup(String group)
throws XMLStreamException, FactoryConfigurationError {
String groupTagName = group;
String groupTagNameSpacePrefix = "";
if (groupTagName.contains("{")) {
groupTagName = groupTagName.replaceAll("\\{.*\\}(.*)", "$1");
if (groupTagName.contains(":")) {
groupTagNameSpacePrefix = groupTagName.replaceAll("(.*):.*", "$1") + ":";
groupTagName = groupTagName.replaceAll(".*:(.*)", "$1");
}
}
try {
writer.write("</" + groupTagNameSpacePrefix + groupTagName + ">");
} catch (IOException ioe) {
throw new DataAccessResourceFailureException("Unable to close group: [" + group + "]", ioe);
}
}
@Override
protected XMLEventWriter createXmlEventWriter(XMLOutputFactory outputFactory, Writer writer)
throws XMLStreamException {
this.writer = writer;
this.eventWriter = super.createXmlEventWriter(outputFactory, writer);
return eventWriter;
}
@Override
public void open(ExecutionContext executionContext) {
if (executionContext.containsKey(getExecutionContextKey(GROUP_IDENTIFIER))) {
currentGroup = executionContext.getString(getExecutionContextKey(GROUP_IDENTIFIER));
}
super.open(executionContext);
}
@Override
public void update(ExecutionContext executionContext) {
executionContext.putString(getExecutionContextKey(GROUP_IDENTIFIER), currentGroup);
super.update(executionContext);
}
@Override
public void close() {
if (currentGroup != null) {
try {
closeGroup(currentGroup);
} catch (XMLStreamException e) {
throw new ItemStreamException("Failed to write close tag for element: " + currentGroup, e);
} catch (FactoryConfigurationError e) {
throw new ItemStreamException("Failed to write close tag for element: " + currentGroup, e);
}
}
super.close();
}
@Override
public void afterPropertiesSet() throws Exception {
super.afterPropertiesSet();
Assert.notNull(classifier, "Missing required property 'classifier'");
}
public void setClassifier(Classifier<T, String> classifier) {
this.classifier = classifier;
}
}
我有一个类定义为 由于类中有一个const成员,编译器会隐式删除默认的复制构造函数。需要给它一个参数进行初始化。 问题出现在课堂上 这个类包含前面类对象的std::array。如何初始化这个数组?大小参数需要给std::array的每个元素来初始化。我想将std::array的每个元素设置为。 当然,我可以使用初始值设定项列表,但由于构造函数有12个元素和其他参数,代码变得越来越难看。此外,我用6
经过稍加搜索,我找到了一个StackOverflow的答案,它用comonoids必须满足的定律更好地解释了这一点。所以我想我明白了为什么在Haskell中只有一个假设的Comonoid类型的可能实例。 因此,要找到一个非平凡的comonoide,我想我们必须从其他类别中寻找。当然,如果范畴理论家有一个comonoids的名字,那么有一些有趣的。该页上的其他答案似乎暗示了一个涉及的示例,但我找不出
6.7.2 StaxEventItemWriter 输出与输入相对应. StaxEventItemWriter 需要 1个 Resource, 1个 marshaller 以及 1个 rootTagName. Java对象传递给marshaller(通常是标准的Spring OXM marshaller), marshaller 使用自定义的事件writer写入Resource, 并过滤由OXM工
问题内容: 在C ++ 11中,您可以使用带有thread_local存储的非平凡对象: 不幸的是,此功能尚未在gcc中实现(从4.7开始)。 gcc确实允许您拥有线程局部变量,但仅具有普通类型。 我正在寻找一种解决方法: 这是我到目前为止的内容: 我需要帮助的是在当前线程的出口处调用placement_delete_x(&x_storage)。我可以使用pthreads和/或linux中的机制来
我知道POD类可以安全地设置。在c 17(?)std::is\U pod被std::is\U标准布局和std::is\U琐碎取代。如果一个非平凡但标准的布局结构只包含char[]数据和一个用户定义的构造函数,那么它可以安全地被memset吗。 具有数十个char[]成员变量的遗留类。 现有代码在使用对象时只对其执行memset。 我想在更新的结构B上调用用户定义的构造函数,因为除了“0”之外,还有
我正在尝试编写一个工厂函数来创建闭包,用作gstreamer中的“pad回调”。我已经提供了一个精简的例子,它应该可以在安装了gstreamer机箱和gstreamer二进制文件/插件的情况下编译。 通过我的研究,我使用了“impl-trait”方法,而不是装箱,使工厂函数工作。不过,我想找出装箱方法,因为它在某些情况下似乎更合适。 这是我得到的最接近。通过使用“Box”取消标记为<code>Cl