Каркас для конвертации Java-объектов - PullRequest
11 голосов
/ 06 ноября 2010

Я работаю над проектом, который преобразует объекты базы данных в объекты DTO.Для этого для каждого преобразования используется специальный класс конвертера.


Я приведу упрощенный пример того, что мы делаем.Я намеренно пропустил сеттеры / геттеры и некоторые другие вещи для ясности кода.

Итак, вот постоянные сущности:

class Car {
    String number;
    Driver driver;
}

class Driver {
    String name;
    License license;
}

class License {
    String serial;
    Date expired;
} 

И предполагая, что нам нужен следующий объект DTO:

class DriverDTO {
    String name;
    String carNumber;
    String licenseSerial;
}

Мы создаем следующий класс конвертера:

class DriverDTOConverter {
    DriverDTO convert(Car car) {
        DriverDTO driverDto = new DriverDTO();
        driverDto.carNumber = car.number;
        driverDto.name = car.driver.name;
        driverDto.licenseSerial = car.driver.license.serial;
        return driverDto;
    }
}

И немного более сложный пример:

class CarDTO {
    String number;
    String driverName;
    LicenseDTO driverLicense;
}

class LicenseDTO {
    String serial;
}

class CarDTOConverter {
    CarDTO convert(Car car) {
        CarDTO carDto = new CarDTO();
        carDto.number = car.number;
        carDto.driverName = car.driver.name;
        LicenseDtoConverter c = new LicenseDtoConverter();
        carDto.driverLicense = c.convert(car.driver.license);
        return carDto;
    }
}

class LicenseDtoConverter {
    LicenseDTO convert(License license) {
        LicenseDTO licenseDto = new LicenseDTO();
        licenseDto.serial = license.serial;
        return licenseDto;
    }
}

Это занимает много времени, поэтому мне интересно, есть ли какие-либо рамки, которые могут взять на себя ответственность за эту работу.И мне нужно только настроить его с помощью файлов свойств или аннотаций.

Что-то вроде этого

Если сделано из файла свойств:

DriverDto <--> Car {
carNumber = number;
name = driver.name;            
licenseSerial = driver.license.serial;
}

CarDTO <--> Car {
number = number;
driverName = driver.name;
driverLicense = driver.license;
}

LicenseDTO <--> License {
license = license;
}

Или пример возможного аннотированного объекта

@Converted(Car.class)
class DriverDTO {
    @Associated("driver.name")
    String name;
    @Associated("number")
    String carNumber;
    @Associated("driver.license.serial")
    String licenseSerial;
}

Важным требованием является то, что он не должен использовать никаких отражений.Все аннотации или файлы свойств должны быть скомпилированы на этапе компиляции или прекомпиляции, и должен быть сгенерирован байт-код или исходный код.

Я буду очень рад, если кто-нибудь может указать мне на такую ​​структуру.Я также с удовольствием приму участие в его создании, если оно еще находится в стадии разработки.

Ответы [ 4 ]

5 голосов
/ 06 ноября 2010

Вы должны проверить Dozer - Java bean to bean mapper. Легко использовать, легко расширять.

3 голосов
/ 24 июня 2011

Вы можете проверить ModelMapper .

Он отличается от Dozer и других тем, что сводит к минимуму объем конфигурации, необходимый для интеллектуального сопоставления объектных моделей.Там, где требуется конфигурация, ModelMapper предлагает безопасный API рефакторинга, который использует фактический код для сопоставления свойств и значений, а не с использованием строковых ссылок или XML.

Для получения дополнительной информации посетите сайт ModelMapper:

http://modelmapper.org

0 голосов
/ 20 февраля 2014

Возможно, вас заинтересует MapStruct , который является генератором кода времени компиляции именно для этого случая использования (отказ от ответственности: я работаю над этим проектом).

Поскольку MapStruct является инструментом времени сборки, он не использует отражения и не требует каких-либо зависимостей времени выполнения.Вам необходимо объявить интерфейс, подобный следующему:

@Mapper
public interface CarMapper {

    CarMapper INSTANCE = Mappers.getMapper ( CarMapper.class );

    @Mapping(source="number", target="carNumber")
    @Mapping(source="driver.name", target="name")
    @Mapping(source="driver.license.serial", target="licenseSerial")
    CarDto carToCarDto(Car car);

    DriverDto driverToDriverDto(Driver driver);
}

Во время сборки (например, через Maven или в вашей IDE) MapStruct сгенерирует реализацию этого интерфейса, которая в основном выглядит как ваш оригинальный рукописный код.

Если вам интересно, вы можете узнать больше в справочном руководстве .

0 голосов

Одной альтернативой бульдозеру, которая может вас заинтересовать, является jDTO Binder, она действительно проста в использовании и обеспечивает интеграцию с наиболее популярными внутренними контейнерами.

jDTO Binder

...