gpt4 book ai didi

spring-mvc - Spring Data JPA - Java 8 流支持和事务最佳实践

转载 作者:行者123 更新时间:2023-12-03 16:34:47 25 4
gpt4 key购买 nike

我有一个非常标准的 MVC 设置,其中包含用于我的 DAO 层的 Spring Data JPA 存储库、一个处理事务问题和实现业务逻辑的服务层,以及一个具有一些可爱的基于 REST 的 JSON 端点的 View 层。

我的问题是关于 Java 8 的大规模采用 Stream进入这个可爱的架构:如果我所有的 DAO 都返回 Stream s,我的服务返回相同的 Stream s(但做事务性工作),而我的观点则作用于并处理这些 Stream s,然后当我的 View 开始处理我的 Stream 中的模型对象时s,Service层创建的事务将被关闭。如果底层数据存储还没有实现我所有的模型对象(毕竟它是一个 Stream,尽可能懒惰),那么我的 View 将在尝试访问事务之外的新结果时出错。以前这不是问题,因为我会将结果完全具体化到列表中 - 但现在我们进入了 Stream 的美丽新世界。 s。

那么,处理这种情况的最佳方法是什么?将Service层内部的结果完全物化为List并交还? View 层是否将完成块交给服务层,以便可以在事务内部完成进一步处理?

谢谢您的帮助!

最佳答案

考虑到这一点,我决定尝试我在问题中提到的完成块解决方案。我所有的服务方法现在都有一个结果转换器作为它们的最终参数,它接受模型对象的流并将其转换为 View 层需要/请求的任何结果类型。我很高兴地报告它就像一种魅力,并且有一些很好的副作用。

这是我的服务基类:

public class ReadOnlyServiceImpl<MODEL extends AbstractSyncableEntity, DAO extends AbstractSyncableDAO<MODEL>> implements ReadOnlyService<MODEL> {

@Autowired
protected DAO entityDAO;

protected <S> S resultsTransformer(Supplier<Stream<MODEL>> resultsSupplier, Function<Stream<MODEL>, S> resultsTransform) {
try (Stream<MODEL> results = resultsSupplier.get()) {
return resultsTransform.apply(results);
}
}

@Override
@Transactional(readOnly = true)
public <S> S getAll(Function<Stream<MODEL>, S> resultsTransform) {
return resultsTransformer(entityDAO::findAll, resultsTransform);
}

}
resultsTransformer这里的方法温和地提醒子类不要忘记 try-with-resources 模式。

这是调用服务基类的示例 Controller :
public abstract class AbstractReadOnlyController<MODEL extends AbstractSyncableEntity, 
DTO extends AbstractSyncableDTOV2,
SERVICE extends ReadOnlyService<MODEL>>
{

@Autowired
protected SERVICE entityService;

protected Function<MODEL, DTO> modelToDTO;

protected AbstractReadOnlyController(Function<MODEL, DTO> modelToDTO) {
this.modelToDTO = modelToDTO;
}

protected List<DTO> modelStreamToDTOList(Stream<MODEL> s) {
return s.map(modelToDTO).collect(Collectors.toList());
}

// Read All
protected List<DTO> getAll(Optional<String> lastUpdate)
{
if (!lastUpdate.isPresent()) {
return entityService.getAll(this::modelStreamToDTOList);
} else {
Date since = new TimeUtility(lastUpdate.get()).getTime();
return entityService.getAllUpdatedSince(since, this::modelStreamToDTOList);
}
}
}

我认为让 Controller 通过 Java 8 lambda 来决定服务的返回类型是对泛型的一种非常巧妙的使用。虽然我看到 Controller 直接返回 Service 调用的结果很奇怪,但我很欣赏这段代码的紧凑性和表现力。

我想说这是尝试大规模切换到 Java 8 Streams 的积极因素。希望这可以帮助有类似问题的人。

关于spring-mvc - Spring Data JPA - Java 8 流支持和事务最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36734581/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com