Spring Batch Reader中SQL查询中的调用方法

时间:2019-02-13 12:48:24

标签: java mysql spring-batch

我有一个枚举,它从性别char返回性别:

public enum Gender {
        FEMALE('F'), MALE('M');
        private char gender;

        Gender(char gender) {
            this.gender = gender;
        }

        public static Gender getSex(char gender) {
            return Arrays.stream(Gender.values())
                    .filter(s -> s.gender == gender)
                    .findFirst()
                    .orElseThrow(NoSuchElementException::new);
        }
    }

在作业中,我有一个带有queryprovider的读取器,该查询提供器从DB中选择列性别(值F或M)。

 ItemReader<UserDTO> userDatabaseReader() {
        JdbcPagingItemReader<UserDTO> reader = new JdbcPagingItemReader<>();
        reader.setDataSource(dataSource);
        reader.setPageSize(100);
        reader.setRowMapper(new BeanPropertyRowMapper<>(UserDTO.class));
        MySqlPagingQueryProvider queryProvider = new MySqlPagingQueryProvider();

        queryProvider.setSelectClause("SELECT u.id, " +
                "u.firstname as firstName, " +
                "u.sex as gender, " +
                "u.eliminated ^ 1 as active");

        queryProvider.setFromClause("FROM users u");
        HashMap<String, Order> sortKeys = new HashMap<>();
        sortKeys.put("u.id", Order.DESCENDING);
        queryProvider.setSortKeys(sortKeys);

        reader.setQueryProvider(queryProvider);
        return reader;

    }

我有带有性别枚举字段的UserDTO。 如何从调用getSex()方法的char列中获取性别枚举,并将其作为枚举传递给UserDTO?

2 个答案:

答案 0 :(得分:1)

方法是在作业处理器中处理读取器结果的每个项目。我必须在DTO中创建一个名为sex的新属性,以从数据库中存储char sex列,并使用该属性值获取性别枚举列。这里的处理器:

@Bean
ItemProcessor<UserDTO, UserDTO> userProcessor() {
    return item -> {
        try {
            item.setGender(UserDTO.Gender.getGender(item.getSex()));
        } catch (Exception ex) {
            log.error("Error trying to process user '{}'", item.getId());
        }
        return item;
    };
}

在查询中

 queryProvider.setSelectClause("SELECT u.id, " +
                "u.firstname as firstName, " +
                "u.sex as sex, " +
                "u.eliminated ^ 1 as active");

答案 1 :(得分:1)

您可以手动实现RowMapper。

类似

class UserDTORowMapper implements RowMapper<UserDTO> {

    @Override
    public UserDTO mapRow(ResultSet rs, int rowNum) throws SQLException {

        return new UserDTO(rs.getString("id"), 
                           rs.getString("firstName"), 
                           GenderEnum.valueOf(rs.getString("gender")));
    }
}

比您的读者还要用

 ItemReader<UserDTO> userDatabaseReader() {
        JdbcPagingItemReader<UserDTO> reader = new JdbcPagingItemReader<>();
        reader.setDataSource(dataSource);
        reader.setPageSize(100);
        reader.setRowMapper(new UserDTORowMapper());
        MySqlPagingQueryProvider queryProvider = new MySqlPagingQueryProvider();

        queryProvider.setSelectClause("SELECT u.id, " +
                "u.firstname as firstName, " +
                "u.sex as gender, " +
                "u.eliminated ^ 1 as active");

        queryProvider.setFromClause("FROM users u");
        HashMap<String, Order> sortKeys = new HashMap<>();
        sortKeys.put("u.id", Order.DESCENDING);
        queryProvider.setSortKeys(sortKeys);

        reader.setQueryProvider(queryProvider);
        return reader;

    }

代码多一点,但您有更多的灵活性