2010-11-06 9 views
11

Estoy trabajando en un proyecto que convierta entidades de base de datos en objetos DTO. Para hacerlo, se usa una clase de convertidor especial para cada conversión.Marco para convertir objetos java


Proporciono un ejemplo simplificado de las cosas que estamos haciendo. Intencionalmente me perdí setters/getters y algunas otras cosas para la claridad del código.

Así que aquí son entidades persistentes:

class Car { 
    String number; 
    Driver driver; 
} 

class Driver { 
    String name; 
    License license; 
} 

class License { 
    String serial; 
    Date expired; 
} 

y suponiendo que necesitamos siguientes objetos DTO:

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

Creamos siguientes clases convertidor:

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; 
    } 
} 

Y un poco más compleja ejemplo:

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; 
    } 
} 

Se necesita una gran cantidad de tiempo, por lo que se preguntan si hay algún marco que puede tomar la responsbility para ese trabajo. Y solo necesitaré configurarlo con archivos de propiedades o anotaciones.

Smth así

Si hecha por archivo de propiedades:

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; 
} 

O sea posible ejemplo de entidad anotada

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

El requisito importante es que no debe utilizar cualquier reflexión. Todas las anotaciones o archivos de propiedades se deben compilar en la etapa de compilación o precompilación, y se deben generar códigos de bytes o de código fuente.

Estaré muy contento si alguien me puede indicar un marco así. También con gusto participaré en su creación si todavía está en desarrollo.

Respuesta

5

Debe consultar Dozer - Java bean to bean mapper. Fácil de usar, fácil de extender.

+0

Thx He echado un primer vistazo a él. Es lo que quería si no tomamos en consideración que utiliza la reflexión. De todos modos, marqué la respuesta como correcta. Si alguien puede sugerir un marco más poderoso, me alegraré y cambiaré mi opción de respuesta "correcta". – Zalivaka

+0

Durante conocer a Dozer, me propusieron el siguiente enlace http://stackoverflow.com/questions/1432764/any-tool-for-java-object-to-object-mapping. Puede ser útil para alguien que también esté interesado en esa pregunta. – Zalivaka

3

Puede consultar ModelMapper.

Se diferencia de Dozer y otros en que minimiza la cantidad de configuración necesaria al mapear inteligentemente modelos de objetos. Cuando se necesita configuración, ModelMapper ofrece una API segura de refactorización que utiliza el código real para mapear propiedades y valores en lugar de utilizar referencias de cadenas o XML.

visitar el sitio ModelMapper para más información:

http://modelmapper.org

0

Una alternativa al dormilón, que puede resultar interesante es jDTO Binder, que es realmente fácil de usar y proporciona integración con el back-end más popular contenedores.

jDTO Binder

0

Usted puede estar interesado en MapStruct que es un generador de código de tiempo de compilación precisamente para este caso de uso (disclaimer: Estoy trabajando en este proyecto).

Como MapStruct es una herramienta de tiempo de compilación, no hace uso de la reflexión ni requiere tipo de dependencias de tiempo de ejecución. Es necesario declarar una interfaz como esta:

@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); 
} 

durante la construcción (por ejemplo a través de Maven o en su IDE), MapStruct generará una implementación de la interfaz que básicamente se parece a su código original escrito a mano.

Si te interesa, puedes encontrar más información en el reference guide.