如何在REST Web服务中实现最简单的外星人?

Pet*_*uss 7 rest stored-procedures spring-boot

我需要一个JSON 端点,直接从存储过程返回数据.例:

@Procedure("complex")
String complexStoredProcedure();
Run Code Online (Sandbox Code Playgroud)

最简单的情况是没有参数的GET端点...返回的数据是一个(blabck-box)JSON,与Spring 实体没有任何关系,也没有特殊的数据类型(我的Spring应用程序的"外来数据类型") ...

如果你需要一个例子,假设一个简单的控制器为

@RequestMapping(value="/howto", method=RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
@Procedure(name = "MyRandom.random")  // ?? not work
public String howto() { 
    double x = random();  // from stored-procedure call, how to do it?
    return "{\"result\":"+x+"}";
}
Run Code Online (Sandbox Code Playgroud)

怎么实现呢?也就是说, 实现控制器方法的最简单方法(调用存储过程)?


编辑:清理冗余的代码片段,转移到下面的答案-Wiki.

Pet*_*uss 2

我正在尝试回应...对于我的观点和我的基本测试来说这只是“最简单的”,您可以展示另一种解决方案来获得赏金。

从“ /sf/ask/2931608431/ ”上下文开始...并且,由于我使用 PostgreSQL(其中 aSELECT f(x)有效),@Query(with ) 是...nativeQuery = true的解决方法@Procedure

此答案的问题:未使用@Procedure...在帕特里克的回答之后,我看到(并编辑了这一行)您可以替换@Query@Procedure(以及帕特里克指定的其他内容)该方法是相同的!


@Query在现有域中添加“alien”的 3 个步骤

任何 Spring都可以使用 any @Query,因此域选择只是一种“内部组织”和语义,对您的本机 SQL 代码和domain/repository选择没有任何限制。

  1. 在域的包文件中,添加一个带有其他导入的domain.repository方法,@Query并添加所有查询上下文导入(QueryAnnotation、JpaRepository、query.Param 等,如果需要);

  2. 在域的service包文件中,添加新的自定义“查找”方法定义。

  3. 在controll的方法中,调用服务中定义的方法。


用真实的文件来说明

步骤1:将新的添加@Query到现有的存储库文件中,例如。myprj/address/domain/repository/ICityRepository.java

package com.myprj.address.domain.repository;  // old

import com.myprj.address.domain.entity.City;   //old
// ... other project's specific (old)
import org.springframework.data.jpa.repository.JpaRepository; 
import org.springframework.data.jpa.repository.Query; // new
import org.springframework.data.repository.query.Param; // new
import org.springframework.data.jpa.repository.query.Procedure; // new

@Repository
public interface ICityRepository extends BaseRepository<City, Long> { //old
    Page<City> findByState(State state, Pageable pageable); //old

    // here an alien example! (simplest is a call to a constant value)
    @Query(nativeQuery = true, value= "SELECT 1234.5678") // NEW! 
    Double findCustom();

}
Run Code Online (Sandbox Code Playgroud)

外星人就在那里

步骤2:导入存储库并将定义添加findCustom()到现有服务文件中,例如。myprj/address/service/CityService.java

package com.myprj.address.service; // old

import com.myprj.address.domain.entity.City;
// ... other project's specific (old)

@Service   
public class CityService 
       extends BaseService<City, ICityRepository, Long> {   // old

    @Autowired
    public CityService(ICityRepository repository) {super(repository);} // old

    public Page<City> findByState(State state, Pageable pageable) {
        return repository.findByState(state, pageable);
    } // old

    public Double findCustom() { return repository.findCustom(); }  // NEW!!

}
Run Code Online (Sandbox Code Playgroud)

步骤3:将定义添加cityService.findCustom()到现有的控制器文件中,例如。myprj/address/controller/CityController.java ...它是一个虚拟端点,用于测试和显示查询结果,

package com.myprj.address.controller;  // old

import com.myprj.address.service.CityService;  // reuse old
// ... other project's specific (old)

@RestController   // old
@RequestMapping(value = "/zip", produces = "application/json")  // old
public class ZipController {   // old

    @Autowired  // old
    private CityService cityService;  // old, so reuse it

    // .. many many endpoints ... OLD    

    // NEW!!
    @RequestMapping(value="/dummy", method=RequestMethod.GET)
    @ResponseStatus(HttpStatus.OK)
    public String dummy() {
        double x = cityService.findCustom();
        return "{\"success\":"+x+"}";
    }
}
Run Code Online (Sandbox Code Playgroud)

减少至 2 个步骤和 2 个文件

正如 Patrick 所示,您可以添加@Autowired到存储库中进行设置,并repository.findCustom()直接在Controller.java文件中使用。