Spring / JPA-最佳查询方式

时间:2018-12-06 21:44:31

标签: java spring rest jpa jackson

我对使用Spring非常陌生。我用它来提供Restful服务。 我在问自己如何使用关系进行简单查询,而又不从相关项目中获取所有信息。

例如:

class Foo {
    @Id
    Long id;

    String name;
    String bar1, bar2, bar3...barN;

    //My approach to avoid get unused data in the json serialization
    @JsonIgnoreProperties({"bar1", "bar2"..., "name", "fooMother", foo"Father"})
    Foo fooFather;

    @JsonIgnoreProperties({"bar1", "bar2"..., "name", "fooMother", foo"Father"})
    Foo fooMother;

//Constructors, getters, setters
}

//Here is where I want to get the data of a Foo instance (just FK in the relationships)
@GetContoller
public Foo getFoo(@RequestParam(value = "id") String id) {
    return fooRespository.findById(id).orElseThrow(() -> new DataNotFoundException());
}

据我所读:

  • 我应该使用惰性获取来避免在数据库中进行自动关系搜索,但是当我的控制器返回Foo jackson时,会看到关系获取器,即使它是惰性获取,它也会映射它们。
  • 我的方法太可怕了,实际上我有一个带有10个属性的类,并管理那可怕的事情。
  • 我看到的其他选项是创建一个DAO或DTO来映射来自JPA的查询结果,但似乎我已经有一个“ FooDTO”作为请求内容,而且如果我的应用程序将以这种方式发展,我会以FooQuery1Dto,FooQuery2Dto等结尾。
  • 我本来想创建自定义查询,但是让Spring对所有内容都进行自定义查询似乎是不可原谅的,即使我尝试过,Jackson也会发挥自己的魔力。
  • 自定义反序列化,同样的问题,很多习惯。
  • 也许是一种动态的查询和映射方式(无需创建类和类)?

因此,我不确定如何采取行动。也许我应该选择其中之一,或者我没有找到其他方法,所以问题是(我很确定不会有绝对的答案,Spring不会解决我的所有问题,但我需要发表意见)我要扩展性和性能该怎么办?

如果有人在春季向我推荐这种良好实践的好消息源,我将非常感激,因为在搜索中我发现很多材料具有不同的实践和观点。

编辑:嗯,似乎我希望没有“完美”的答案,但是我发现JsonView可以帮助管理它。

1 个答案:

答案 0 :(得分:1)

我建议不要将Json配置与实体配置混用:在Json和JPA实体之间分配职责。

仅使用您的实体来检索数据库信息。创建另一个类,例如FooJson(或FooResponseFooDto等),并在FooJson实体上的Foo上填写所需的信息,并在控制器上返回此FooJson。您可以使用Introduction to the Dependency Mechanism之类的lib来帮助您。

要从数据库中检索信息,您始终可以使用Foo实体并将其信息映射到不同的Foo Json类,例如:FooCreateJonFooUpdateJsonFooFindByIdJson等等。如果不影响应用程序的性能,则可以使用此策略始终返回Foo实体。

关于代码,您将遇到类似这样的事情:

@GetContoller
public FooJson getFoo(@RequestParam(value = "id") String id) {
    return fooService.findById(id).orElseThrow(() -> new DataNotFoundException());
}

FooService

class FooService {

    FooJson findById(String id) {
        Foo foo = fooRepository.findById(id);
        return new ModelMapper().map(FooJson.class, foo);
    }
}