Web 服务如何独立于 DAL 实现?

How can web services be independant from the DAL implementations?

我正在研究 a project,它可以与两个数据访问层实现一起使用:

实现的选择取决于 Tomcat 启动时的 Spring 活动配置文件(spring.profiles.active=图形数据库,或 spring.profiles.active=关系数据库) .这很好用。

我正在服务层上添加 REST 服务。目前,我只注释了 retrieveAllCategories 方法,它响应“/rest/resources/categories” URL。它按预期显示 JSON,但我的问题是,当服务器使用 DAL 图数据库实现时,输出与使用关系数据库模块时不同。

差异涉及与 "ResourceCategory" class 关联的对象集合。我已经不得不使用 @JsonIgnore@JsonManagedReference@JsonBackReference (example) 等注释来注释我的 "JPA" 域 bean,以避免无限递归。这是一项漫长而乏味的工作,我不希望在我的整个项目中都这样做。

我的问题:有没有更好的方法(比非常耐心地注释每个 "relational database" bean)来确保我的 Web 服务将独立地提供完全相同的数据使用的 DAL 实现?

您的问题最常见的解决方案是使用数据传输对象 (DTO)。

基本上,您创建一个新的 class,它准确地表示您的 Web 服务的 commands/responses 应该如何。

那么,这只是一个与class相互转换的问题。

示例:

public class JpaMovie {

    @OneToMany
    private List<Actor> actors;

    // Whatever you need in JPA DAL.
}

public class GraphMovie {
    // Whatever you need in Graph DAL.
}

public class MovieDTO {
    // Structure of the web service response.
    // Always convert to this type before returning.
    // This way, no matter the DAL, your response
    // structure will always be the same.
}

这里是如何在你的案例中使用它们(你正在为你的域模型使用 setter/getter 接口):

@Controller
public class MovieController {

    @Autowired
    private MovieService movieService;

    @RequestMapping("/movies")
    public @ResponseBody MovieDTO findById(@RequestParam String id) {
        MovieInterface movie = movieService.findById(id);
        return MovieDTO.from(movie);
    }

}