Search code examples
spring-batch

How do I insert my XML data into existing tables of MySQL database using springboot java


So when i convert xml data  to pojo classes i get many classes , using spring batch i could only fetch one class from the xml data , so when i try to access other classes i get an error

i want each of my xml data which is converted to Po-jo classes to be dumped into different tables of the database

below is the code which i have tried

project directory structure

BatchConfig.java-

@Configuration 
@EnableBatchProcessing
 public class BatchConfig {
@Autowired
private JobBuilderFactory jobBuilderFactory;

@Autowired
private StepBuilderFactory stepBuilderFactory;

@Autowired
private DataSource dataSource;

@Bean
public DataItenProcessor processor(){
    return new DataItenProcessor();
}

@Bean
public StaxEventItemReader<Call_Info> reader(){
    StaxEventItemReader<Call_Info> reader = new StaxEventItemReader<Call_Info>();
    reader.setResource(new ClassPathResource("data.xml"));
    reader.setFragmentRootElementName("data");
    
    Map<String,String> aliasesMap =new HashMap<String,String>();
    aliasesMap.put("data", "com.example.demo.model.Call_Info");
    XStreamMarshaller marshaller = new XStreamMarshaller();
    marshaller.setAliases(aliasesMap);
    
    reader.setUnmarshaller(marshaller);
    return reader;
}

}
 @Bean 
public JdbcBatchItemWriter<Call_Info> writer(){
 JdbcBatchItemWriter<Call_Info> writer = new JdbcBatchItemWriter<Call_Info>(); writer.setDataSource(dataSource); 
writer.setSql("INSERT INTO TBL_IVR_CALLACTIVITY(Cli,Dnis,Dnis_Type,SessionID,CallStarttime,CallEndtime,Language,Menu_Path,Last_Menu,Announce_Path,Agent_Vdnno,CI_Reserve1,CI_Reserve2,CI_Reserve3,CI_Reserve4,CI_Reserve5,CI_Reserve6,CI_Reserve7,CI_Reserve8,CI_Reserve12) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); 

writer.setItemPreparedStatementSetter(new DataPreparedStatementSetter()); return writer;

@Bean
public Step step1(){
    return stepBuilderFactory.get("step1").<Call_Info,Call_Info>chunk(100).reader(reader()).processor(processor()).writer(writer()).build();
}

@Bean
public Job exportPerosnJob(){

    return jobBuilderFactory.get("importData").incrementer(new RunIdIncrementer()).flow(step1()).end().build();
}

DataPreparedStatementSetter.java -

public class DataPreparedStatementSetter implements ItemPreparedStatementSetter<Call_Info> {
@Override
public void setValues(Call_Info data, PreparedStatement ps) throws SQLException {
    ps.setString(1, data.getCli());
    ps.setString(2, data.getDnis());
    ps.setString(3, data.getDnis_Type());
    ps.setString(4, data.getSessionID());
    ps.setString(6, data.getCallStarttime());
    ps.setString(7, data.getCallEndtime());
    ps.setString(8, data.getLanguage());
    ps.setString(9, data.getMenu_Path());
    ps.setString(10, data.getAnnounce_Path());
    ps.setString(11, data.getAgent_Vdnno());
    ps.setString(12, data.getCI_Reserve1());
    ps.setString(13, data.getCI_Reserve2());
    ps.setString(14, data.getCI_Reserve3());
    ps.setString(15, data.getCI_Reserve4());
    ps.setString(16, data.getCI_Reserve5());
    ps.setString(17, data.getCI_Reserve6());
    ps.setString(18, data.getCI_Reserve8());
    ps.setString(19, data.getCI_Reserve12());

}
}

DataItenProcessor.java

@Override
public class DataItenProcessor implements ItemProcessor<Call_Info, Call_Info>{
public Call_Info process(Call_Info data) throws Exception {
    return data;
}
}

for now i could only access call_info class from the modal class , how do i access other classes and write them to the different tables of the database

changes done

BatchConfig.java

@Bean
    public JdbcBatchItemWriter<IvrData> writer(){
        JdbcBatchItemWriter<IvrData> writer = new JdbcBatchItemWriter<IvrData>();
        writer.setDataSource(dataSource);
        writer.setSql("INSERT INTO TBL_IVR_CALLACTIVITY(Cli,Dnis,Dnis_Type,SessionID,CallStarttime,CallEndtime,Language,Menu_Path,Last_Menu,Announce_Path,Agent_Vdnno,CI_Reserve1,CI_Reserve2,CI_Reserve3,CI_Reserve4,CI_Reserve5,CI_Reserve6,CI_Reserve7,CI_Reserve8,CI_Reserve12) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)");
        writer.setSql("INSERT INTO TBL_IVR_ANNOUNCE_DETAILS(menuId,menuStartTime,menuEndTime,  menuOption,menuOptionDesc,menuReserve1)VALUES(?,?,?,?,?,?");
        writer.setSql("INSERT INTO TBL_IVR_HOSTDETAILS(announceId, announceStartTime, announceEndTime)VALUES(?,?,?");
        writer.setSql("INSERT INTO TBL_IVR_MENUDETAILS(hostType,hostMethod,hostStartTime, hostEndTime,hostInparams,hostOutparams)VALUES(?,?,?,?,?,?,?");
        writer.setItemPreparedStatementSetter(new DataPreparedStatementSetter());
        return writer;

DataPreparedStatementSetter.java

public abstract  class DataPreparedStatementSetter implements ItemPreparedStatementSetter<IvrData> {

    public void setValues(IvrData.CallInfo data, PreparedStatement ps) throws SQLException {
        ps.setString(1,data.getAgentVdnno());
        ps.setString(2, data.getAnnouncePath());
        ps.setString(3,data.getCallEndTime());
        ps.setString(4,data.getCallStartTime());
        ps.setString(5,data.getCiReserve1());
        ps.setString(6,data.getCiReserve2());
        ps.setString(7,data.getCiReserve3());
        ps.setString(8,data.getCiReserve4());
        ps.setString(9,data.getCiReserve5());
        ps.setString(10,data.getCiReserve6());
        ps.setString(11,data.getCiReserve7());
        ps.setString(12,data.getCiReserve8());
        ps.setString(13,data.getCiReserve12());
    }

public void setValues(IvrData.Announce data, PreparedStatement ps)throws SQLException{
    ps.setString(1,data.getAnnounceEndTime());
    ps.setString(1,data.getAnnounceId());
    ps.setString(1,data.getAnnounceStartTime());
    
}

public void setValues(IvrData.Host data,PreparedStatement ps)throws SQLException{
    ps.setString(1,data.getHostEndTime());
    ps.setString(1,data.getHostInparams());
    ps.setString(1,data.getHostMethod());
    ps.setString(1,data.getHostOutparams());
    ps.setString(1,data.getHostType());
    ps.setString(1,data.getHostStartTime());
    }

public void setValues(IvrData.Menu data, PreparedStatement ps) throws SQLException{
    ps.setString(1,data.getMenuEndTime());
    ps.setString(1,data.getMenuId());
    ps.setString(1,data.getMenuOptionDesc());
    ps.setString(1,data.getMenuReserve1());
    ps.setString(1,data.getMenuStartTime());
    ps.setString(1,data.getMenuOption());
    ps.setString(1,data.getMenuEndTime());
    
}

}

the error iam getting


Solution

  • The JdbcBatchItemWriter performs a single insert query, you can't insert in multiple tables with that item writer. You need a custom item writer for that.

    Here is an example of a custom item writer:

    import org.springframework.batch.item.Chunk;
    import org.springframework.batch.item.ItemWriter;
    import org.springframework.jdbc.core.JdbcTemplate;
    
    public class IvrDataWriter implements ItemWriter<IvrData> {
    
        private JdbcTemplate jdbcTemplate;
    
        public IvrDataWriter(JdbcTemplate jdbcTemplate) {
            this.jdbcTemplate = jdbcTemplate;
        }
    
        @Override
        public void write(Chunk<? extends IvrData> chunk) throws Exception {
            for (IvrData item : chunk) {
                // get fields from item and use them in the query
                jdbcTemplate.update("Insert into TBL_IVR_CALLACTIVITY ...");
                jdbcTemplate.update("Insert into TBL_IVR_ANNOUNCE_DETAILS ...");
            }
        }
    }