Java 如何在spring批处理中从3个表中读取关系数据
我需要从3个表(合同、车道、费率)中读取数据。合同可以是多个,对于每个合同,我可以有多个车道,对于每个车道,我可以有多个费率。表具有外键关系 我想从表中读取数据,并以相关方式将其设置为Java对象。Java POJO就像一个Java 如何在spring批处理中从3个表中读取关系数据,java,spring,spring-batch,Java,Spring,Spring Batch,我需要从3个表(合同、车道、费率)中读取数据。合同可以是多个,对于每个合同,我可以有多个车道,对于每个车道,我可以有多个费率。表具有外键关系 我想从表中读取数据,并以相关方式将其设置为Java对象。Java POJO就像一个 public class Contract extends TICSection { private RTRate rtRate; private List<Lane> lanes = new ArrayList<Lane>(
public class Contract extends TICSection {
private RTRate rtRate;
private List<Lane> lanes = new ArrayList<Lane>();
private String effectiveDate;
private String expirationDate;
private String contractNumber;
private String contractTitle;
}
在java对象契约中,我有车道列表,在车道中,我有费率列表。我希望所有的数据从3个相应的表在这个格式
请帮助我如何使用ItemReader设置此格式的数据。
另外,如果我在上下文xml中设置了commit interval=10,如何确保spring批处理一次只读取和处理1个契约和10个通道。可能吗
问题是我试图从3个不同的表中读取数据,并且我希望以类似的方式将它们映射到Java对象,比如Contract有关联的车道列表,lane有关联的费率列表。因此,当我处理记录时,我会得到所有相关的车道和费率数据
对于1表,我的配置如下所示
<bean id="pagingItemReader"
class="org.springframework.batch.item.database.JdbcPagingItemReader"
scope="step">
<property name="dataSource" ref="dataSource" />
<property name="queryProvider">
<bean
class="org.springframework.batch.item.database.support.SqlPagingQueryProviderFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="selectClause" value="*" />
<property name="fromClause" value="from gtn_lineitem" />
<property name="whereClause" value="record_status in ('O','E') and contract_seq = :contractSeq" />
<property name="sortKey" value="contract_seq" />
</bean>
</property>
<!-- Inject via the ExecutionContext in rangePartitioner -->
<property name="parameterValues">
<map>
<entry key="contractSeq" value="#{stepExecutionContext[contractSeq]}"/>
<entry key="fromId" value="#{stepExecutionContext[fromId]}" />
<entry key="toId" value="#{stepExecutionContext[toId]}" />
</map>
</property>
<property name="pageSize" value="#{stepExecutionContext[laneCount]}" />
<property name="rowMapper">
<bean class="com.cat.srr.gtn.dao.mapper.GTNContractRowMapper" />
</property>
</bean>
<!-- Actual Job -->
<bean id="contractReadPartitioner" class="com.cat.srr.gtn.batch.partitioner.ContractReadPartitioner">
<property name="contractDao" ref="contractDao"></property>
</bean>
<bean id="taskExecutor" class="org.springframework.core.task.SyncTaskExecutor" />
<bean id="contractProcessor" class="com.cat.srr.gtn.batch.ContractProcessor" scope="step">
<property name="threadName" value="#{stepExecutionContext[name]}"></property>
</bean>
<batch:job id="partitionJob" xmlns="http://www.springframework.org/schema/batch">
<batch:step id="masterStep">
<batch:partition step="slaveStep" partitioner="contractReadPartitioner">
<batch:handler grid-size="1" task-executor="taskExecutor"/>
</batch:partition>
</batch:step>
<batch:listeners>
<batch:listener ref="jobListener" />
</batch:listeners>
</batch:job>
<batch:step id="slaveStep">
<batch:tasklet transaction-manager="transactionManager">
<batch:chunk reader="pagingItemReader" writer="contractWriter"
processor="contractProcessor" commit-interval="1" />
</batch:tasklet>
</batch:step>
但是如果为3个不同的表声明3个读卡器,那么如何将数据合并到java对象中。
或
如果我编写一个连接查询来选择所有相关数据,那么行映射器将如何合并结果。正确的方法应该是什么
public class GTNContractRowMapper implements RowMapper<GTNContract>{
@Override
public GTNContract mapRow(ResultSet rs, int arg1) throws SQLException {
GTNContract contract = new GTNContract();
contract.setContractSeq(rs.getString("CONTRACT_SEQ"));
contract.setContractNumber(rs.getString("GTN_CONTRACT_ID"));
contract.setContractTitle(rs.getString("CONTRACT_ID"));
contract.setCarrierName(rs.getString("CARRIER_NAME"));
contract.setCarrierSCAC(rs.getString("CARRIER_SCAC"));
contract.setModeName(rs.getString("MODE_NM"));
contract.setEffectiveDate(rs.getString("TERM_BEGIN"));
contract.setExpirationDate(rs.getString("TERM_END"));
return contract;
}
公共类GTNContractRowMapper实现了RowMapper{
@凌驾
公共GTnContact映射行(结果集rs,int arg1)引发SQLException{
GTN合同=新GTN合同();
contract.setContractSeq(rs.getString(“contract_SEQ”);
合同编号(rs.getString(“GTN_合同ID”);
contract.setContractTitle(rs.getString(“contract_ID”);
合同。setCarrierName(rs.getString(“承运人名称”);
合同。setCarrierSCAC(rs.getString(“承运人”);
contract.setModeName(rs.getString(“MODE_NM”);
合同生效日期(rs.getString(“期限开始”);
合同。设置到期日期(rs.getString(“期限结束”);
退货合同;
}
}实际上,我还需要您的处理器和写入程序的信息。根据这些信息,我可以给出适当的解决方案 但根据您提供的读者信息,我想采用以下两种方法 A.无自定义读卡器 1.分部将在合同级别处理。 2.读者将根据每份合同阅读车道信息。 3.处理者将根据每个合同和车道获取费率信息 因此,在处理器级别,我们有每个合同/通道/费率 我正在等待更多的信息从您的处理器和作家提供准确的方法
public class GTNContractRowMapper implements RowMapper<GTNContract>{
@Override
public GTNContract mapRow(ResultSet rs, int arg1) throws SQLException {
GTNContract contract = new GTNContract();
contract.setContractSeq(rs.getString("CONTRACT_SEQ"));
contract.setContractNumber(rs.getString("GTN_CONTRACT_ID"));
contract.setContractTitle(rs.getString("CONTRACT_ID"));
contract.setCarrierName(rs.getString("CARRIER_NAME"));
contract.setCarrierSCAC(rs.getString("CARRIER_SCAC"));
contract.setModeName(rs.getString("MODE_NM"));
contract.setEffectiveDate(rs.getString("TERM_BEGIN"));
contract.setExpirationDate(rs.getString("TERM_END"));
return contract;
}
B.自定义阅读器
自定义的一个是,您可以使用一个查询构建自己的逻辑,该查询使用GROUPBY子句连接3个表。在Java中,循环结果集并构建契约对象
谢谢,
Nghia好的,我们有你的类,这是MCVE的第一部分:现在我们需要看看你用它们做了什么,你的输出或编译错误是什么。@DanielWisehart我用更多的细节更新了这个问题谢谢你的快速回复。我的处理器就像我必须一个接一个地处理每条车道记录和一些业务逻辑,然后在writer中我想调用Webservice来推送数据。如果我不使用自定义阅读器方法,那么合同和车道记录将如何合并到一个对象中。你能给我一些样本吗?如果你没有自定义阅读器,处理器将如下所示:公共类JdbcPagingItemProcessor实现ItemProcessor{Autowire private LaneDAO LaneDAO;Override public Lane process(Lane Lane)抛出异常{//pull Rate details List rateList=this.LaneDAO.fetchRatesByLaneId(lane.getLaneNumber());land.setRateList(rateList);//通过lane return开始处理}注意:车道类应该有合同字段来引用父对象。所以在这种情况下,您的意思是我必须找到车道的所有费率,这些费率是可以的,但也要找到与车道相关的合同。?记住,分区器已经是合同级别的。当我来到读卡器时,这意味着我们已经“读取”了每个合同。然后处理器只用于车道到特定合同。好的,谢谢。我将尝试此选项:)
public class GTNContractRowMapper implements RowMapper<GTNContract>{
@Override
public GTNContract mapRow(ResultSet rs, int arg1) throws SQLException {
GTNContract contract = new GTNContract();
contract.setContractSeq(rs.getString("CONTRACT_SEQ"));
contract.setContractNumber(rs.getString("GTN_CONTRACT_ID"));
contract.setContractTitle(rs.getString("CONTRACT_ID"));
contract.setCarrierName(rs.getString("CARRIER_NAME"));
contract.setCarrierSCAC(rs.getString("CARRIER_SCAC"));
contract.setModeName(rs.getString("MODE_NM"));
contract.setEffectiveDate(rs.getString("TERM_BEGIN"));
contract.setExpirationDate(rs.getString("TERM_END"));
return contract;
}