¿Cómo procesar filas lógicamente relacionadas después de ItemReader en SpringBatch?

Guió

Para simplificar, supongamos que tengo un ItemReader que me devuelve 25 filas.

as primeras 10 filas pertenecen al alumno A

Los siguientes 5 pertenecen al estudiante B

y los 10 restantes pertenecen al estudiante C

Quiero agregarlos juntos lógicamente decir porIdentificación del Estudiant y aplanarlos para terminar con una fila por estudiante.

Problem

Si lo entiendo correctamente, establecer el intervalo de confirmación en 5 hará lo siguiente:

Envíe 5 filas al procesador (que las agregará o hará cualquier lógica de negocios que se lo indique). After Processed escribirá 5 filas.Entonces lo volverá a hacer durante las próximas 5 filas y así sucesivamente.

Si eso es cierto, entonces para los próximos cinco tendré que verificar los que ya están escritos, sacarlos, agregarlos a los que estoy procesando actualmente y volver a escribirlos.

Personalmente no me gusta eso.

Cuál es la mejor práctica para manejar una situación como esta en Spring Batch?Alternativ

A veces siento que es mucho más fácil escribir un programa principal de Spring JDBC y luego tengo el control total de lo que quiero hacer. Sin embargo, quería aprovechar la supervisión del estado del repositorio del trabajo, la capacidad de reiniciar, omitir, escucha del trabajo y de pasos ...

My Spring Batch Code

Mi module-context.xml

   <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:batch="http://www.springframework.org/schema/batch"
    xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <description>Example job to get you started. It provides a skeleton for a typical batch application.</description>

    <batch:job id="job1">
        <batch:step id="step1"  >           
            <batch:tasklet transaction-manager="transactionManager" start-limit="100" >             
                 <batch:chunk reader="attendanceItemReader"
                              processor="attendanceProcessor" 
                              writer="attendanceItemWriter" 
                              commit-interval="10" 
                 />

            </batch:tasklet>
        </batch:step>
    </batch:job> 

    <bean id="attendanceItemReader" class="org.springframework.batch.item.database.JdbcCursorItemReader"> 
        <property name="dataSource">
            <ref bean="sourceDataSource"/>
        </property> 
        <property name="sql"                                                    
                  value="select s.student_name ,s.student_id ,fas.attendance_days ,fas.attendance_value from K12INTEL_DW.ftbl_attendance_stumonabssum fas inner join k12intel_dw.dtbl_students s on fas.student_key = s.student_key inner join K12INTEL_DW.dtbl_schools ds on fas.school_key = ds.school_key inner join k12intel_dw.dtbl_school_dates dsd on fas.school_dates_key = dsd.school_dates_key where dsd.rolling_local_school_yr_number = 0 and ds.school_code = ? and s.student_activity_indicator = 'Active' and fas.LOCAL_GRADING_PERIOD = 'G1' and s.student_current_grade_level = 'Gr 9' order by s.student_id"/>
        <property name="preparedStatementSetter" ref="attendanceStatementSetter"/>           
        <property name="rowMapper" ref="attendanceRowMapper"/> 
    </bean> 

    <bean id="attendanceStatementSetter" class="edu.kdc.visioncards.preparedstatements.AttendanceStatementSetter"/>

    <bean id="attendanceRowMapper" class="edu.kdc.visioncards.rowmapper.AttendanceRowMapper"/>

    <bean id="attendanceProcessor" class="edu.kdc.visioncards.AttendanceProcessor" />  

    <bean id="attendanceItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter"> 
        <property name="resource" value="file:target/outputs/passthrough.txt"/> 
        <property name="lineAggregator"> 
            <bean class="org.springframework.batch.item.file.transform.PassThroughLineAggregator" /> 
        </property> 
    </bean> 

</beans>

Mis clases de apoyo para el lector.

A PreparedStatementSetter

package edu.kdc.visioncards.preparedstatements;

import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.springframework.jdbc.core.PreparedStatementSetter;

public class AttendanceStatementSetter implements PreparedStatementSetter {

    public void setValues(PreparedStatement ps) throws SQLException {

        ps.setInt(1, 7);

    }

}

y un RowMapper

package edu.kdc.visioncards.rowmapper;

import java.sql.ResultSet;
import java.sql.SQLException;

import org.springframework.jdbc.core.RowMapper;

import edu.kdc.visioncards.dto.AttendanceDTO;

public class AttendanceRowMapper<T> implements RowMapper<AttendanceDTO> {

    public static final String STUDENT_NAME = "STUDENT_NAME";
    public static final String STUDENT_ID = "STUDENT_ID";
    public static final String ATTENDANCE_DAYS = "ATTENDANCE_DAYS";
    public static final String ATTENDANCE_VALUE = "ATTENDANCE_VALUE";

    public AttendanceDTO mapRow(ResultSet rs, int rowNum) throws SQLException {

        AttendanceDTO dto = new AttendanceDTO();
        dto.setStudentId(rs.getString(STUDENT_ID));
        dto.setStudentName(rs.getString(STUDENT_NAME));
        dto.setAttDays(rs.getInt(ATTENDANCE_DAYS));
        dto.setAttValue(rs.getInt(ATTENDANCE_VALUE));

        return dto;
    }
}

Mi procesador

package edu.kdc.visioncards;

import java.util.HashMap;
import java.util.Map;

import org.springframework.batch.item.ItemProcessor;

import edu.kdc.visioncards.dto.AttendanceDTO;

public class AttendanceProcessor implements ItemProcessor<AttendanceDTO, Map<Integer, AttendanceDTO>> {

    private Map<Integer, AttendanceDTO> map = new HashMap<Integer, AttendanceDTO>();

    public Map<Integer, AttendanceDTO> process(AttendanceDTO dto) throws Exception {

        if(map.containsKey(new Integer(dto.getStudentId()))){

            AttendanceDTO attDto = (AttendanceDTO)map.get(new Integer(dto.getStudentId()));
            attDto.setAttDays(attDto.getAttDays() + dto.getAttDays());
            attDto.setAttValue(attDto.getAttValue() + dto.getAttValue());

        }else{
            map.put(new Integer(dto.getStudentId()), dto);
        }
        return map;
    }

}
Mis inquietudes del código anterior

En el procesador, creo un HashMap y, mientras proceso las filas, verifico si ya tengo ese Estudiante en el mapa, si no está allí, lo agrego. Si ya está allí, tomo los valores que me interesan y los agrego con la fila que estoy procesando actualmente.

Después de eso, Spring Batch Framework escribe en un archivo de acuerdo con mi configuración

Mi pregunta es la siguiente:

No quiero que vaya al escritor. Quiero procesar todas las filas restantes. ¿Cómo guardo este mapa que he creado en la memoria para el siguiente conjunto de filas que deben pasar por este mismo procesador? Cada vez que se procesa una fila a través de AttendanceProcessor, se inicializa el mapa. ¿Debo poner la inicialización del Mapa en un bloque estático?

Respuestas a la pregunta(8)

Su respuesta a la pregunta