我正在开发将数据库实体转换为DTO对象的项目。为此,每次转换都使用特殊的转换器类。
我正在提供我们正在做的事情的简化示例。我故意错过了setter / getters和其他一些代码清晰度的东西。
所以这里是持久性实体:
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;
}
}
这需要花费很多时间,所以我想知道是否有任何框架可以承担这项工作的责任。我只需要用属性文件或注释配置它。
像那样的Smth
如果由属性文件生成:
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;
}
重要的要求是它不应该使用任何反射。应在编译或预编译阶段编译所有注释或属性文件,并应生成字节码或源代码。
如果有人能指出我这样的框架,我将非常高兴。如果它还处于发展阶段,我也很乐意参与它的创作。
答案 0 :(得分:5)
您应该查看Dozer - Java bean到bean映射器。易于使用,易于扩展。
答案 1 :(得分:3)
您可以查看ModelMapper。
它与Dozer和其他人的不同之处在于它通过智能地映射对象模型来最小化所需的配置量。在需要配置的地方,ModelMapper提供了一个重构安全API,它使用实际代码来映射属性和值,而不是使用字符串引用或XML。
查看ModelMapper网站了解更多信息:
答案 2 :(得分:0)
dozer的一个替代品,你可能会觉得有趣的是jDTO Binder,它使用起来非常简单,并提供与最流行的后端容器的集成。
答案 3 :(得分:0)
您可能对MapStruct感兴趣,reference guide正是这个用例的编译时代码生成器(免责声明:我正在研究这个项目)。
由于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将生成该接口的实现,它基本上看起来像您原始的手写代码。
如果您有兴趣,可以在{{3}}中找到更多信息。