将DTO转换为实体,反之亦然

时间:2015-02-24 18:25:01

标签: java spring-mvc jpa

我在我的网络应用程序中使用Spring MVC架构和JPA

手动将DTO转换为实体,反之亦然(不使用任何框架)?

6 个答案:

答案 0 :(得分:12)

这是一个老问题,已接受答案但是要使用模型映射器API以简单的方式更新它。

<dependency>
    <groupId>org.modelmapper</groupId>
    <artifactId>modelmapper</artifactId>
    <version>0.7.4</version>
</dependency>

使用此API,您可以避免使用手动设置器和在接受的答案中解释的吸气剂。

在我看来,两个转换都应该在私有实用程序方法的帮助下进行,并使用Java8流的映射(如果交换了DTO集合),如this article中所示。

它应该发生在控制器上,因为DTO应该是独占的传输对象。我没有把我的DTO进一步向下。

您为自己的服务编码&amp;实体上的数据访问层,并在调用服务方法之前将DTO转换为实体。在从控制器返回响应之前将实体转换为DTO。

我更喜欢这种方法,因为实体很少更改,并且可以根据需要从DTO添加/删除数据。

详细的模型映射器配置和规则描述为here

答案 1 :(得分:8)

我认为你在询问在哪里写整个实体 - &gt; DTO转换逻辑。

喜欢你的实体

class StudentEntity {
 int age ;
 String name;

 //getter
 //setter

 public StudentDTO _toConvertStudentDTO(){
    StudentDTO dto = new StudentDTO();
    //set dto values here from StudentEntity
    return dto;
 }

}

您的DTO应该像

class StudentDTO  {
 int age ;
 String name;

 //getter
 //setter

 public StudentEntity _toConvertStudentEntity(){
    StudentEntity entity = new StudentEntity();
    //set entity values here from StudentDTO
    return entity ;
 }

}

你的控制器应该像

@Controller
class MyController {

    public String my(){

    //Call the conversion method here like
    StudentEntity entity = myDao.getStudent(1);
    StudentDTO dto = entity._toConvertStudentDTO();

    //As vice versa

    }

}

答案 2 :(得分:7)

在我看来

  • 实体 - &gt;在调度jsp页面之前,应在Controller中完成DTO转换
  • DTO - &gt;在验证从jsp页面返回的DTO后,应在Controller中完成实体转换

它使您可以更好地控制进程,并且每次填充实体的某些逻辑发生更改时,您不必更改服务/持久性类。

答案 3 :(得分:5)

我可以建议使用mapstruct库:

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-jdk8</artifactId>
    <version>1.2.0.Final</version>
</dependency>

例如,如果您有这样的实体:

public class Entity {
    private Integer status;
    private String someString;
    private Date startDate;
    private Date endDate;

    // SKIPPED

和DTO:

public class Dto {
    private Boolean status;
    private String someString;
    private Long startDate;
    private Long endDate;

    // SKIPPED

然后可以通过以下方式在服务层中完成转换:

@Service
public class SomeServiceImpl implements SomeService {

    @Autowired
    SomeDao someDao;

    @Autowired
    SomeMapper someMapper;


    public Dto getSomething(SomeRequest request) throws SomeException {
        return someDao.getSomething(request.getSomeData())
                .map(SomeMapper::mapEntityToDto)
                .orElseThrow(() -> new SomeException("..."));
    }

映射器可以表示如下:

@Mapper 
public interface SomeMapper {
    @Mappings(
            {@Mapping(target = "entity", 
                      expression = "java(entity.getStatus() == 1 ? Boolean.TRUE : Boolean.FALSE)"),
             @Mapping(target = "endDate", source = "endDate"),
             @Mapping(target = "startDate", source = "startDate")
            })

    Dto mapEntityToDto(Entity entity);
}

答案 4 :(得分:3)

我建议另一种无需额外依赖的方法:

import org.springframework.beans.BeanUtils
...
BeanUtils.copyProperties(sourceObject, targetObject);

如果属性类型和名称相同,则可用于将DTO转换为实体,反之亦然。

如果您想忽略某些字段,只需在targetObject之后添加它们即可。

BeanUtils.copyProperties(sourceObj, targetObj, "propertyToIgnoreA", "propertyToIgnoreB", "propertyToIgnoreC");

来源:http://appsdeveloperblog.com/dto-to-entity-and-entity-to-dto-conversion/

我认为这是最干净的方法。

答案 5 :(得分:0)

使用的mapstruct库。另外在build.gradle中添加了以下内容

sourceSets {
    main.java.srcDirs += "build/generated/sources/annotationProcessor/java/main/"
}