Java对象转换框架

11

我正在开发一个将数据库实体转换为DTO对象的项目。为此,每个转换都使用特殊的转换器类。


这里我提供了一些我们正在做的事情的简化示例。出于代码清晰度的考虑,我有意省略了setter/getter和一些其他东西。

这是持久化实体:

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

你应该看看Dozer-Java bean到bean的映射器。易于使用,易于扩展。


谢谢,我已经初步查看了它。如果不考虑它使用反射,那么这正是我想要的东西。无论如何,我将把答案标记为正确的。如果有人能够建议一个更强大的框架,我会很高兴并更改我的“正确”答案选择。 - Zalivaka
在熟悉Dozer时,我被提供了以下链接:https://dev59.com/p3M_5IYBdhLWcg3wThR3。这可能对那些对此问题也感兴趣的人有所帮助。 - Zalivaka

3

您可以查看我的ModelMapper

与Dozer和其他工具不同的是,它通过智能映射对象模型来最小化所需的配置量。在需要配置的情况下,ModelMapper提供了一个重构安全的API,该API使用实际的代码来映射属性和值,而不是使用字符串引用或XML。

请访问ModelMapper网站获取更多信息:

http://modelmapper.org


0

你可能会对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
一个与Dozer相似且可能会引起你兴趣的替代品是jDTO Binder,它非常易于使用并提供与最流行的后端容器的集成。

jDTO Binder


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接