【问题标题】:Does using DTOs everywhere affect memory usage on jvm?到处使用 DTO 会影响 jvm 上的内存使用吗?
【发布时间】:2019-03-10 14:17:50
【问题描述】:

所以我的问题是在我的项目中,我在我的服务类中使用模型映射器。因此,当服务调用 Dao 层(实际上只是一个 JPA Repository 接口)时,Dao 层现在成功返回实体,而不是只返回实际实体,我先将其转换为 DTO(这是实体的精确副本)使用java的模型映射器。 因为我不想直接暴露我的实体。

代码示例:

public class FormService {

    @Autowired
    private FormMasterDao formMasterDao;

    @Autowired
    private ModelMapper mapper;

    public FormMasterDTO save(FormMasterDTO formMasterDTO) {

        FormMaster formMaster = buildFormMaster(formMasterDTO);

        return convertToFormMasterDTO(formMasterDao.save(formMaster));
    }


    public List<FormMasterDTO> findById(String id) {

        return formMasterDao.findByIdIn(id)
                .stream()
                .map(this::convertToFormMasterDTO)
                .collect(toList());    }

    public void updateAll(List<FormMasterDTO> formMasterDTOList) {

        formMasterDao.saveAll(formMasterDTOList.stream()
                .map(this::convertToFormMaster)
                .collect(toList()));
    }

    public FormMasterDTO update(FormMasterDTO formMasterDTO) {
        return convertToFormMasterDTO(formMasterDao.save(convertToFormMaster(formMasterDTO)));
    }

    private FormMasterDTO convertToFormMasterDTO(FormMaster formMaster) {
        return mapper.map(formMaster, FormMasterDTO.class);
    }

    private FormMaster convertToFormMaster(FormMasterDTO formMasterDTO) {
        return mapper.map(formMasterDTO, FormMaster.class);
    }

}

我发现这种方法很有用,因为如果许多开发人员在工作和编写代码,他们就不能直接使用实体。

但我想知道,使用这种方法是不是不好?会,它会影响 JVM,因为每次如果有人点击该服务,我都会将其转换为 DTO。

【问题讨论】:

  • 除非你有一个实际负载的性能配置文件告诉你,你在创建对象的数量上有问题,有 99% 的机会只是猜测,假设它可能是问题。我建议使用飞行记录器运行您的应用程序,以查看您的应用程序在哪里花费时间。

标签: java performance memory jvm modelmapper


【解决方案1】:

如果您担心从纯 JPA 对象转换为 DTO 的时间成本,请不要担心。这就是原因。

与许多其他操作相比,对象分配确实很慢,但与 IO 相比一点也不慢。我确信您的 JPA 服务将从数据库中获取某些内容。如果我是正确的,那么你花在新对象分配上的时间(以及后来产生的 GC 成本)将不到你刚刚花在数据库操作本身上的时间的 0.01%。

如果您针对速度进行优化,减少内存分配是一个好主意,但应该不是您首先要做的事情。只有在优化了成本更高的操作(例如数据库查询)之后才有意义。

免责声明: 在某些情况下,您的 DTO 会被证明是昂贵的。如果您碰巧在您的 JPA 对象中使用延迟加载,那么您即将进行的 DTO 转换将完全解决这个问题。延迟加载将允许 JPA 不获取 JPA 对象图的某些子元素,但作为 DTO 转换的一部分,您将每次请求“可选”数据,这反过来又会让您回到你在开始使用Lazy之前就开始了。

【讨论】:

  • 我同意你的看法@Gergely,但在我的问题中,我正在使用模型映射器将每个实体转换回 A DTO .... 它真的会影响系统吗?实际上,我是在做一个单一的责任。例如,您只需提供 id,我将提供您使用它的实体的副本 DTO。但是每次提供副本都需要模型映射器。那么它真的会影响系统吗?我看到人们不必要地使用收藏。
  • 我不完全确定我是否理解您的评论,但是:您是否有一个返回完整对象的代码,每次给它一个 ID?如果是,那么这可能是一场性能噩梦。如果没有适当的缓存(这不是一件容易的事),您将不断地从数据库中获取内容。那(而不是 DTO 转换本身)将是一件非常缓慢的事情。如果您更新这个问题(或者更好地创建一个新问题),我们会找到比这更优化的解决方案。
猜你喜欢
  • 2012-05-17
  • 1970-01-01
  • 2020-03-16
  • 1970-01-01
  • 1970-01-01
  • 2012-09-16
  • 2010-09-26
  • 2012-02-06
  • 1970-01-01
相关资源
最近更新 更多