如何在Spring数据休息中创建自定义本机查询而不复制其ResourceAssembler?

时间:2015-11-20 16:39:42

标签: spring rest spring-data-rest spring-hateoas

我有一个看起来像

的控制器
@RestController
public class LocationsController {

    @Autowired
    private EntityManager manager;

    private String withinQuery =
            "WITH L as\n" +
            "\n" +
            "(SELECT *\n" +
            "FROM location\n" +
            "\n" +
            "WHERE ST_Distance(ST_FlipCoordinates(location.shape), ST_FlipCoordinates(ST_GeomFromGeoJSON('%s'\n" +
            "        )))=0)\n" +
            "\n" +
            "SELECT *\n" +
            "FROM L\n" +
            "WHERE id NOT IN (\n" +
            "SELECT metalocation_id FROM location\n" +
            "WHERE metalocation_id IS NOT NULL\n" +
            ")";

    private String nearestQuery =
            "select * from location order by ST_Distance(ST_FlipCoordinates(location.shape), ST_FlipCoordinates(St_GeomFromGeoJSON('%s'))) limit 1";

    @RequestMapping(value="near", method = RequestMethod.GET)
    public List<Location> getNearestLocations(@RequestParam(value = "point") String pointAsString) throws IOException {
        List<Location> locationCloseToPoint = manager.createNativeQuery(String.format(withinQuery, pointAsString), Location.class).getResultList();
        if (locationCloseToPoint.size() == 0) {
            List<Location> closesLocation = manager.createNativeQuery(String.format(nearestQuery, pointAsString), Location.class)
                    .getResultList();
            locationCloseToPoint.addAll(closesLocation);
        }
        return locationCloseToPoint;
    }
}

如您所见,它会返回位置列表。

@Entity
public class Location {

    public Geometry getShape() {
        return shape;
    }

    public void setShape(Geometry shape) {
        this.shape = shape;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @NotNull
    private Geometry shape;

    @ManyToOne(cascade = CascadeType.ALL)
    private Location metalocation;

问题是我希望以春天数据休息用于所有hateoas字段和东西的位置资源的格式返回此列表。更具体地说,我希望在输出中有一个指向metalocation的链接。

我已经读过spring-hateoas和ResourceAssembler以及@RepositoryRestController,我想我可以通过编写自定义ResourceAssembler来复制spring-data-rest正在做什么,但我不想,因为你知道,为什么我会想编写spring-data-rest编写的代码,对吧?

他们自动完成所有这些组装工作,对吧?因为我在http输出中看到它。所以我认为应该有一种方法来使用它。

1 个答案:

答案 0 :(得分:0)

您可以尝试以下操作。

首先使用var foo = (function () { var bar = false; function switchbar () { if(bar){ bar = false} else { bar = true } ; }; function show { switchbar(); console.log(bar) }; function noshow { switchbar(); console.log(bar) }; return { showTheBar: show, hideTheBar: noshow, whatIsBar: bar } }()); foo.showTheBar() //true foo.whatIsBar //false --> should be true 代替@RepositoryRestController注释您的控制器。

然后,您可以使用spring数据休息在内部使用的资源汇编程序 - PersistentEntityResourceAssembler

以下示例适合我。

@RestController

@RepositoryRestController public class DemoController { private final ProductRepository productRepository; private final PagedResourcesAssembler<Object> pagedResourcesAssembler; @Autowired public DemoController(ProductRepository productRepository, PagedResourcesAssembler<Object> pagedResourcesAssembler) { this.productRepository = productRepository; this.pagedResourcesAssembler = pagedResourcesAssembler; } //use PersistentEntityResourceAssembler and PagedResourcesAssembler to return a resource with paging links @RequestMapping(method = GET, path="/products/search/listProductsPage", produces = HAL_JSON_VALUE) public ResponseEntity<PagedResources<PersistentEntityResource>> getAllPage(Pageable pageable, PersistentEntityResourceAssembler persistentEntityResourceAssembler) { Iterable<?> all = productRepository.findAll(pageable); return ResponseEntity.ok(pagedResourcesAssembler.toResource((Page<Object>) all, persistentEntityResourceAssembler)); } //return Resources of entity resources @RequestMapping(method = GET, path="/products/search/listProducts", produces = HAL_JSON_VALUE) public ResponseEntity<Resources<PersistentEntityResource>> getAll(Pageable pageable, PersistentEntityResourceAssembler persistentEntityResourceAssembler) { return ResponseEntity.ok(new Resources<PersistentEntityResource>(productRepository.findAll().stream() .map(persistentEntityResourceAssembler::toResource) .collect(Collectors.toList()))); } } 方法可能就是你想要的。

我还添加了将Page转换为PagedResource的getAll变体 - 如果获得集合资源,这就是spring数据休息生成的内容。在这里,您还必须使用PagedResourcesAssembler来生成页面链接。

这是你在寻找什么?

在您的情况下,我也会尝试避免自定义控制器 - 如果您可以将您的本机查询表示为存储库查找器,则弹出数据会自动显示查找器。 Spring数据jpa似乎通过注释支持本机查询 - http://docs.spring.io/spring-data/jpa/docs/1.9.1.RELEASE/reference/html/#jpa.query-methods.at-query