我需要一个JSON 端点,它直接从stored procedure返回数据。例如:
@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+"}";
}
最简单的情况是没有参数的GET端点...返回的数据是(blabck-box)JSON,与Spring 实体无关,并且没有特殊数据 - type(一个"外来数据类型"对于我的Spring应用程序)...
如果您需要一个例子,假设一个简单的控制器为
templateResult
如何实施?也就是说,实现控制器方法的最简单方法(调用存储过程)?
编辑:清理冗余代码片段,转移到answer-Wiki below。
答案 0 :(得分:4)
我不确定我是否理解你的问题,但这是我的解决方案。
我在oracle
数据库上创建了一个简单的程序:
PROCEDURE TESTPROCOUTPUT
(param2 OUT VARCHAR2)
IS
GETPARAM VARCHAR2(100);
BEGIN
param2 := 'procedure Called';
END TESTPROCOUTPUT;
要在Spring环境中使用@Procedure
,您需要Entity
和Repository
。所以我创建了一个简单的Entity
及其Repository
:
@Entity
public class City {
@Id
private String cityCode;
//...getter/setter
}
存储库:
public interface LandRepository extends CrudRepository<City, String> {
@Procedure(name="TESTPROCOUTPUT", outputParameterName="param2")
String TESTPROCOUTPUT();
}
重要的是方法名称与过程具有相同的名称。 (不确定它是否仅适用于oracle的情况。也可以在camelCase中我认为)
因此,在您的控制器中,您现在可以轻松地自动装配存储库(或者如果您有接口的实现,则使用此方法)。
@Controller
public class CityController {
private CityRepository cityRepository;
@RequestMapping(value="/howto", method=RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public String howto() {
String s = cityRepository.TESTPROCOUTPUT();
return "{\"result\":" + s + "}";
}
public CityRepository getCityRepository () {
return cityRepository;
}
@Autowired
public void setCityRepository (CityRepository cityRepository) {
this.cityRepository= cityRepository;
}
}
结果是:
因此,您无法在非存储库方法上使用@Procedure
注释。
用于直接在存储库方法上声明JPA 2.1存储过程映射的注释。
答案 1 :(得分:2)
我正在努力回应......对于我的观点和我的基本测试来说,这只是“最简单的”,你可以展示另一种获得赏金的解决方案。
以“https://stackoverflow.com/q/41880120/287948”上下文开头....而且,当我使用PostgreSQL(SELECT f(x)
有效时),@Query
(nativeQuery = true
)是@Procedure
...
有这个问题的问题:未使用@Procedure
...在Patrick的回答之后,我看到(并编辑了这一行)您可以将@Query
替换为@Procedure
(以及指定的其他内容)帕特里克)这个方法是一样的!
@Query
”的3个步骤任何Spring 域都可以使用任何@Query
,因此域选择只是一种“内部组织”和语义,对本机SQL代码没有约束,{{1}选择。
在域的domain/repository
包文件中,添加一个方法domain.repository
和其他导入添加所有查询上下文导入(QueryAnnotation,JpaRepository,query.Param)等,如果需要);
在域的@Query
包文件中,添加新的自定义“find”方法定义。
在controll的方法中,调用服务中定义的方法。
Step1 :将新的service
添加到现有的存储库文件中,例如。 @Query
myprj/address/domain/repository/ICityRepository.java
外星人就在那里!
Step2 :导入存储库并将已定义的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();
}
添加到现有服务文件中,例如。 findCustom()
myprj/address/service/CityService.java
Step3 :将已定义的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!!
}
添加到现有的控制器文件中,例如。 cityService.findCustom()
...这是一个虚拟端点来测试和显示查询结果,
myprj/address/controller/CityController.java
如Patrick所示,您可以将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+"}";
}
}
添加到存储库进行设置,并直接在@Autowired
文件中使用repository.findCustom()
。