Вызов метода внутри SQL-запроса в Spring Batch Reader - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть Enum, который возвращает пол от пола 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);
        }
    }

В работе у меня есть читатель с поставщиком запросов, который выбирает из БД пол столбца (со значениями 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 с полем Enum.Как получить пол Enum из столбца char, вызывающего метод getSex(), и передать его в UserDTO как enum?

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Вы можете реализовать 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;

    }

Немного больше кода, но у вас есть способбольше гибкости

0 голосов
/ 13 февраля 2019

Подход заключается в обработке каждого элемента результата чтения в Job Processor.Мне пришлось создать новый атрибут в DTO, называемый sex, чтобы хранить столбец char sex из базы данных, и получить столбец пола enum, используя это значение атрибута.Вот процессор:

@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");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...