我想運行一些本機查詢并通過端點公開結果,但我想這樣做而不必創建所有物體。我只是希望從資料庫中獲得的資料在它到來時被公開。
我在以下位置找到了一些建議:Create spring repository without entity
但是,我無法讓它們作業。我對春天很陌生。
我嘗試了這樣的 Maciej Kowalski 解決方案:
界面:
public interface CustomNativeRepository {
Object runNativeQuery();
}
執行:
@Repository
public class CustomNativeRepositoryImpl implements CustomNativeRepository {
@Autowired
private EntityManager entityManager;
@Override
public Object runNativeQuery() {
return entityManager.createNativeQuery(
"""
SELECT 1 as col1, 2 as col2, 3 as col3
UNION ALL SELECT 4, 5, 6
UNION ALL SELECT 7, 8, 9
"""
)
.getResultList();
}
}
但是,沒有暴露端點,就像擴展 CrudRepository 時一樣。我應該用 CustomNativeRepositoryImpl 做點別的嗎?我不知道該怎么做。
我還嘗試了 Gagarwa 的解決方案:
根物體:
@Entity
public class RootEntity {
@Id
private Integer id;
}
根物體存盤庫:
@Repository
public interface RootEntityRepository extends JpaRepository<RootEntity, Integer> {
@Query(value = """
SELECT 1 as col1, 2 as col2, 3 as col3
UNION ALL SELECT 4, 5, 6
UNION ALL SELECT 7, 8, 9""",
nativeQuery = true)
public Collection<Object> findFromCustomQuery();
}
The endpoint http://localhost:8080/rootEntities was exposed, but when I accessed it, I got the exception: "Relation root_entity does not exist". So, I created the table in the database:
create table root_entity(
id SERIAL PRIMARY KEY
)
After that, the endpoint worked, and returned an empty array (the table root_entity is empty in the database).
I tried to access the endpoint: http://localhost:8080/rootEntities/search/findFromCustomQuery, but I got an exception (Couldn't find PersistentEntity for type class).
Again, I was not able to make it work.
After trying a lot, I made some progress doing the following:
@RestController
public class CustomQueryController {
@Autowired
private EntityManager entityManager;
@GetMapping("/myEndpoint")
@ResponseBody
public Object runNativeQuery() {
return ResponseEntity
.ok()
.body(
entityManager.createNativeQuery(
"""
SELECT 1 as col1, 2 as col2, 3 as col3
UNION ALL SELECT 4, 5, 6
UNION ALL SELECT 7, 8, 9
"""
).getResultList()
);
}
}
With the code above, I can access http://localhost:8080/myEndpoint and see the result of the query.
However, the endpoint didn't appear in the endpoints listing that is showed in http://localhost:8080/. I had to type it manually in the browser. I would like the endpoint to be exposed in order to see it in Swagger.
Also, I have a feeling that there must be a better way to do this. And I want to learn.
I would like help to:
- Get a solution that works and exposes the endpoint.
- Understand what I did wrong and how to implement Kowalski's and Gagarwa's solutions.
- Being able to expose the endpoint for the last solution (CustomQueryController).
Thanks in advance!
uj5u.com熱心網友回復:
嘗試改變你CustomQueryController的實施RepresentationModelProcessor
public class CustomQueryController implements RepresentationModelProcessor<RepresentationModel<RepositoryLinksResource>> {
并通過以下方式實作該process方法:
@Override
public RepresentationModel<RepositoryLinksResource> process(RepresentationModel<RepositoryLinksResource> model) {
if (model instanceof RepositoryLinksResource) {
model.add(Link.of( "http://localhost:8080" "/myEndpoint", "myEndpoint"));
}
return model;
}
https://docs.spring.io/spring-data/rest/docs/current/reference/html/#customizing-sdr.customizing-json-output.representation-model-processor
uj5u.com熱心網友回復:
我嘗試了你放在這里的第一個例子,它對我有用。但是有一點變化。我用過 PersistenceContext。
要回傳一個鏈接作為回應,我使用Link了WebMvcLinkBuilder。
解決方案在下面的示例中,
我使用了兩個表Employee和Address. PostgresSQL兩者有area_code共同之處。
界面
public interface CustomNativeRepository {
List<Object> runNativeQuery(Integer name);
}
存盤庫
@Repository
public class CustomNativeRepositoryImpl implements CustomNativeRepository {
Logger logger = LoggerFactory.getLogger(this.getClass());
@PersistenceContext
private EntityManager entityManager;
@Override
public List<Object> runNativeQuery(Integer areaCode) {
Query query = entityManager.createNativeQuery(
"Select e.first_name as name from employees e where e.area_code = ? "
"union all "
"Select a.address as address from address a where a.area_code = ?");
query.setParameter(1, areaCode);
query.setParameter(2, areaCode);
List<Object> response = query.getResultList();
logger.info("Response from database: {}", response);
return response;
}
}
休息端點層
@GetMapping(path ="/employee/{areaCode}")
public ResponseEntity<?> getEmployeeByCode(@PathVariable(value = "areaCode") Integer areaCode) throws NoSuchMethodException {
List<Object> response = customCustomerRepository.runNativeQuery(areaCode);
Link link = WebMvcLinkBuilder.linkTo(WebMvcLinkBuilder.methodOn(EmployeeController.class).getEmployeeByCode(areaCode)).withSelfRel();
return ResponseEntity.ok().body(CollectionModel.of(response, link));
}
幾個例子可能會有所幫助。link1 ? link2
注意:我沒有在我的代碼庫中創建任何物體類。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/424546.html
標籤:java spring jpa spring-data spring-data-rest
