Как сопоставить набор результатов JDBC с DTO: подход на основе перечислений и общий подходJAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Как сопоставить набор результатов JDBC с DTO: подход на основе перечислений и общий подход

Сообщение Anonymous »

У меня была существующая реализация, в которой использовалось перечисление (EventRowMapper) для сопоставления столбцов набора результатов SQL непосредственно с полями в DTO (EventDTO). Этот подход работал, но требовал явного жесткого кодирования каждого сопоставления полей в сопоставителе строк. Вот пример оригинального подхода:

Код: Выделить всё

ID("id"),
NAME("name"),
START_DATE("start_date"),
END_DATE("end_date"),
TYPE("type"),
CREATED_AT("created_at");

private final String column;

public static RowMapper getEventDTORowMapper() {
return (rs, rowNum) -> EventDTO.builder()
.id(rs.getInt(EventRowMapper.ID.column))
.name(rs.getString(EventRowMapper.NAME.column))
.startDate(rs.getDate(EventRowMapper.START_DATE.column))
.endDate(rs.getDate(EventRowMapper.END_DATE.column))
.type(rs.getString(EventRowMapper.TYPE.column))
.createdAt(rs.getDate(EventRowMapper.CREATED_AT.column))
.build();
}
Однако этот подход становится громоздким по мере роста количества полей или когда другим DTO требуются аналогичные сопоставления. Я хотел создать более общую утилиту, которая могла бы динамически обрабатывать сопоставление для различных DTO.
Я провел рефакторинг кода, представив более общую утилиту сопоставления (RowMapperUtils). Эта утилита использует отражение для сопоставления значений ResultSet с DTO на основе полей и типов, определенных в перечислении (EventRowMapper). Я реализовал интерфейс ColumnMapper, который стандартизирует структуру сопоставления, что делает код более удобным в сопровождении и позволяет повторно использовать его в нескольких DTO.
Новый подход:

Код: Выделить всё

@Getter
@AllArgsConstructor
public enum EventRowMapper implements ColumnMapper {
ID("id", "id", DataType.INTEGER),
NAME("name", "name", DataType.STRING),
START_DATE("start_date", "startDate", DataType.DATE),
END_DATE("end_date", "endDate", DataType.DATE),
TYPE("type", "type", DataType.STRING),
CREATED_AT("created_at", "createdAt", DataType.DATE);

private final String column;
private final String field;
private final DataType type;

public static RowMapper getEventDTORowMapper() {
return (rs, rowNum) -> RowMapperUtils.mapResultSetToDTO(rs, EventDTO.class, List.of(EventRowMapper.values()));
}
}
Класс RowMapperUtils предоставляет универсальный служебный метод mapResultSetToDTO(), который динамически устанавливает поля в DTO на основе столбцов в ResultSet. Интерфейс ColumnMapper обеспечивает единообразие сопоставления столбцов.

Код: Выделить всё

    public static  T mapResultSetToDTO(ResultSet rs, Class dtoClass, List columns) {
try {
T dto = dtoClass.getDeclaredConstructor().newInstance();

for (ColumnMapper c : columns) {
Field field = dtoClass.getDeclaredField(c.getField());
field.setAccessible(true); // To prevent IllegalAccessException
field.set(dto, getValueFromResultSet(rs, c));
}

return dto;
} catch (Exception e) {
log.error("Failed to map ResultSet to DTO", e);
throw new RuntimeException("Failed to map ResultSet to DTO");
}
}

private static Object getValueFromResultSet(ResultSet rs, ColumnMapper c) throws SQLException {
switch (c.getType()) {
case INTEGER: return rs.getInt(c.getColumn());
case DATE: return rs.getDate(c.getColumn());
case DOUBLE: return rs.getDouble(c.getColumn());
case BOOLEAN: return rs.getBoolean(c.getColumn());
default: return rs.getString(c.getColumn()); // String will be used here
}
}
Проблемы и вопросы по производительности:
Хотя этот подход повышает гибкость и удобство обслуживания, меня беспокоит потенциальная производительность. влияние использования отражения для динамического сопоставления полей. В сценариях, где производительность имеет решающее значение (например, запросы большого объема), может ли это универсальное решение привести к увеличению накладных расходов по сравнению с более явным подходом к сопоставлению?
  • Существует ли производительность компромиссы, которые мне следует учитывать при использовании отражения таким образом?
  • Приемлем ли этот подход для промышленного использования в высокопроизводительных приложениях?
  • Существуют ли какие-либо альтернативные методы или структуры, которые мне следует рассмотреть для более эффективной обработки динамического картирования? Если да, то какие?


Подробнее здесь: https://stackoverflow.com/questions/790 ... c-approach
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как использовать общий файл Json или общий dto для передачи данных из разных пользовательских интерфейсов в соответствую
    Anonymous » » в форуме C#
    0 Ответы
    28 Просмотры
    Последнее сообщение Anonymous
  • Как сопоставить список перечислений с Varchar с помощью Hibernate 6.2
    Anonymous » » в форуме JAVA
    0 Ответы
    16 Просмотры
    Последнее сообщение Anonymous
  • Преобразование всех значений двух перечислений в один набор
    Anonymous » » в форуме JAVA
    0 Ответы
    8 Просмотры
    Последнее сообщение Anonymous
  • Путаница и проблемы с исходным DTO и целевым DTO [закрыто]
    Anonymous » » в форуме JAVA
    0 Ответы
    75 Просмотры
    Последнее сообщение Anonymous
  • Может ли DTO расширить другой DTO?
    Anonymous » » в форуме JAVA
    0 Ответы
    46 Просмотры
    Последнее сообщение Anonymous

Вернуться в «JAVA»