我需要一个直接从存储过程返回数据的JSONendpoint。示例:
@Procedure("complex")
String complexStoredProcedure();
最简单的情况是不带参数的GETendpoint...返回的数据是一个(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+"}";
}
如何实施?也就是说,实现控制器方法的最简单方法(调用存储过程)?
编辑:清理了多余的代码片段,转移到下面的回答-Wiki。
我不确定我是否很好地理解你的问题,但这是我的解决方案。
我在oracle
DB上创建了一个简单的过程:
PROCEDURE TESTPROCOUTPUT
(param2 OUT VARCHAR2)
IS
GETPARAM VARCHAR2(100);
BEGIN
param2 := 'procedure Called';
END TESTPROCOUTPUT;
要在Spring环境中使用@过程
,您需要一个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;
}
}
结果是:
所以您不能在非存储库方法上使用< code>@Procedure注释。
注释直接在存储库方法上声明JPA 2.1存储过程映射。
我正在努力回应。。。对于我的观点和基本测试来说,这只是“最简单的”,你可以展示另一种解决方案来获得奖励。
以“https://stackoverflow.com/q/41880120/287948“上下文……而且,当我使用PostgreSQL时(SELECT f(x)
有效),@Query
(nativeQuery=true
)是@过程
的一种变通方法。。。
这个答案的问题:未使用@Procedure
...在帕特里克的回答之后,我看到(并编辑了这一行)你可以@Query
替换@Procedure
(以及帕特里克指定的其他东西)方法是一样的!
任何Spring域都可以使用任何@Query
,因此域选择只是一种“内部组织”和语义,对本机SQL代码和域/存储库
选择没有限制。
>
在域的domain. repository
包文件中,使用@Query
添加一个方法,并使用其他导入添加所有查询上下文导入(QueryAnnoation、JpaRepository、query.Param等,如果需要);
在域的service
包文件中,添加新的自定义“find”方法定义。
在Controlll的方法中,调用服务中定义的方法。
步骤1:将新的< code>@Query添加到现有的存储库文件中,例如< code > 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();
}
外星人在那里!
步骤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!!
}
Step3:将定义的cityService. findCustom()
添加到现有的控制器文件中,例如。myprj/address/控制器/CityController.java
…它是一个虚拟endpoint来测试和显示查询结果,
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+"}";
}
}
如Patrick所示,您可以将@Autowired
添加到存储库中进行设置,并直接在Controller.java
文件中使用repository.findCustom()
。