我想阅读XML
并将其写入MySql数据库
<?xml version="1.0" encoding="UTF-8"?>
<parentNode id="001" name="p1" type="t1">
<line>message1</line>
<line>message2</line>
<line>message3</line>
<line>message4</line>
</parentNode>
我有以下读者
@XmlRootElement(name = "parentNode")
public class ParentNode {
private String id;
private String name;
private String type;
private List<String> lineNode;
@XmlAttribute(name = "id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@XmlAttribute(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlAttribute(name = "type")
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@XmlElement(name = "line")
public List<String> getLineNode() {
return lineNode;
}
public void setLineNode(List<String> lineNode) {
this.lineNode = lineNode;
}
}
我有一位作家如下
public class ParentNodeItemPreparedStatementSetter implements ItemPreparedStatementSetter<ParentNode> {
@Override
public void setValues(ParentNode parentNode, PreparedStatement ps) throws SQLException {
ps.setString(1, parentNode.getId());
ps.setString(1, parentNode.getLineNode()); //HOW DO I WRITE EACH LINE INSTEAD OF ONLY THE LAST ONE
}
问题是如何将所有三个line
写入数据库。此代码仅将<line>message4</line>
message4
写入数据库。我希望数据库有
ID | LINE
001 | message1
001 | message2
001 | message3
001 | message4
我的配置如下
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:batch="http://www.springframework.org/schema/batch" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<import resource="classpath:context-datasource.xml" />
<!-- JobRepository and JobLauncher are configuration/setup classes -->
<bean id="jobRepository"
class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean" />
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<bean id="xmlItemReaderStep" class="org.springframework.batch.item.xml.StaxEventItemReader">
<property name="resource" value="classpath:test.xml" />
<property name="fragmentRootElementName" value="parentNode" />
<property name="unmarshaller">
<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.results.model.ParentNode</value>
</list>
</property>
</bean>
</property>
</bean>
<bean id="resultsWriter"
class="org.springframework.batch.item.database.JdbcBatchItemWriter">
<property name="dataSource" ref="dataSource" />
<property name="sql">
<value>
<![CDATA[
insert into playground.LINE(id, line) values (?, ?);
]]>
</value>
</property>
<property name="ItemPreparedStatementSetter">
<bean
class="com.results.preparedstatement.ParentNodeItemPreparedStatementSetter" />
</property>
</bean>
<bean id="itemProcessor"
class="com.results.itemprocessors.ParentNodeItemProcessor" />
<bean id="transactionManager"
class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<batch:job id="resultJob">
<batch:step id="step1">
<batch:tasklet transaction-manager="transactionManager">
<batch:chunk reader="xmlItemReaderStep" writer="resultsWriter"
processor="itemProcessor" commit-interval="100" />
</batch:tasklet>
</batch:step>
</batch:job>
</beans>
编辑:
通过修改ParentNodeItemPreparedStatementSetter
,我可以得到我需要的东西。但看起来这不是正确的做法。
public class ParentNodeItemPreparedStatementSetter implements ItemPreparedStatementSetter<ParentNode> {
@Override
public void setValues(ParentNode parentNode, PreparedStatement ps) throws SQLException {
for (int i = 0; i < parentNode.getLineNode().size(); i++) {
ps.setString(1, parentNode.getId());
ps.setString(2, parentNode.getLineNode().get(i));
if (!(i == parentNode.getLineNode().size()-1))
ps.addBatch();
}
}
}
答案 0 :(得分:1)
您希望它们之间似乎没有匹配:
ID | LINE
001 | message1
001 | message2
001 | message3
001 | message4
你有两个输入结构:
<?xml version="1.0" encoding="UTF-8"?>
<parentNode id="001" name="p1" type="t1">
<line>message1</line>
<line>message2</line>
<line>message3</line>
<line>message4</line>
</parentNode>
@XmlRootElement(name = "parentNode")
public class ParentNode {
private String id;
private String name;
private String type;
private List<String> lineNode;
...
在输入中,xml中有1行,因此当读者完成其工作时,只有一个ParentNode实例,但在写入之后,您希望在行表中拥有与lineNode列表中的元素一样多的行,所以4线。 它不是对称的。
如果您需要实际的输入xml结构,请在编写过程中不做任何更改并进行一种自定义映射。
在某种程度上,你可以通过添加与lineNode列表中的元素一样多的行来使用ParentNodeItemPreparedStatementSetter:
for (int i = 0; i < parentNode.getLineNode().size(); i++) {
ps.setString(1, parentNode.getId());
ps.setString(2, parentNode.getLineNode().get(i));
if (!(i == parentNode.getLineNode().size()-1))
ps.addBatch();
}
这是一个技巧,但根据文档,它似乎并不坏:
public interface ItemPreparedStatementSetter
一种方便的SQL更新策略,有效地作为RowMapper的反转。
修改:回答您的评论。 如果您的实际输入xml结构可以修改,因为它是例如生成的,您可以设计xml结构,使其与您的预期匹配。 在输入中,您应该添加parent-id值:
<?xml version="1.0" encoding="UTF-8"?>
<parentNode id="001" name="p1" type="t1">
<line parent-id="001">message1</line>
<line parent-id="001">message2</line>
<line parent-id="001">message3</line>
<line parent-id="001">message4</line>
</parentNode>
在你的读者conf xml中,你会替换
<property name="fragmentRootElementName" value="parentNode" />
<property name="fragmentRootElementName" value="line" />
您还应该修改xml对象的结构。将您的行列表从String类型更改为自己的类,该类拥有两个必需字段:id和line。 通过这种方式,您可以在输入和输出中获得预期的数据,而无需进行任何处理。