[英]How to write a custom @Query in Spring Data JDBC?
In Spring Data JDBC examples, how do I write a simple query in @Query
annotation? 在Spring Data JDBC示例中,如何在
@Query
批注中编写一个简单查询?
eg In LegoSet Repository , how do I add a simple findByName
query? 例如在LegoSet Repository中 ,如何添加一个简单的
findByName
查询?
When I tried 当我尝试
@Query("select * from lego_set where name = :name") List<LegoSet> findByName(@Param("name") String name);
it throws following error: 它引发以下错误:
org.springframework.data.mapping.MappingException: Could not read property @org.springframework.data.annotation.Id() @org.springframework.data.relational.core.mapping.Column(value=handbuch_id, keyColumn=)private java.lang.Long example.springdata.jdbc.basics.aggregate.Manual.id from result set!
...
> Caused by: org.hsqldb.HsqlException: Column not found: manual_handbuch_idat org.hsqldb.error.Error.error(Unknown Source) at org.hsqldb.error.Error.error(Unknown Source) `
Also, the reference document seems to be copied from some generic spring data document since it mentioned derived query which doesn't exist in spring data jdbc yet. 另外,该参考文档似乎是从某些通用的Spring数据文档复制而来的,因为它提到了Spring数据jdbc中尚不存在的派生查询。
The LegoSet
entity has a 1:1 relationship to a Manual
. LegoSet
实体与Manual
具有1:1关系。 Spring Data JDBC selects such a construct using a join and expects the representative columns in the ResultSet
. Spring Data JDBC使用联接选择这种构造,并期望
ResultSet
的代表列。
Note that it expects the columns representing the Manual
entity itself plus the one forming the back-reference to the LegoSet
. 请注意,它期望代表
Manual
实体本身的列以及构成对LegoSet
的反向引用的LegoSet
。 Also, all column names are to be prefixed by the property name + _
, ie manual_
in this case. 同样,所有列名都应以属性名+
_
作为前缀,在这种情况下,即manual_
。
The error message actually tells you about the missing column (modulo a missing space): Column not found: manual_handbuch_id
. 错误消息实际上告诉您有关缺少的列(以空格为模):
Column not found: manual_handbuch_id
。
Alternatively, you can also provide your own RowMapper
另外, 您也可以提供自己的
RowMapper
Regarding the documentation: 关于文档:
You are kind of right. 你是对的。 The documentation of (almost) all Spring Data modules includes a generic part which easily leads to confusion.
(几乎)所有Spring Data模块的文档都包含一个通用部分,很容易引起混淆。 There is a ticket for comming up with a better solution .
有一个更好的解决方案的门票 。
I think you are trying to execute a native query.So,try as below 我认为您正在尝试执行本机查询。因此,请尝试以下操作
@Query( value = "SELECT * FROM lego_set ls where ls.name = :name",
nativeQuery = true)
List<LegoSet> findByName(@Param("name") String name);
This should work. 这应该工作。
Just as a completion of @jens-schauder's answer: 就像@ jens-schauder的答案一样:
The query should be: 查询应为:
@Query("SELECT ls.id, ls.name, ls.min_age, ls.max_age, " +
"h.handbuch_id AS manual_handbuch_id, h.author AS manual_author, h.text AS manual_text " +
"FROM lego_set ls JOIN handbuch h ON ls.id = h.handbuch_id " +
"WHERE name = :name")
List<LegoSet> findByName(@Param("name") String name);
Using this method the following test passes: 使用此方法,以下测试通过:
@Test
public void so_52978700() {
// prepare
LegoSet cars = createLegoSet("Small Car - 01", 5, 10);
cars.setManual(new Manual("Just put all the pieces together in the right order", "Jens Schauder"));
repository.save(cars);
// execute
List<LegoSet> actual = repository.findByName("Small Car - 01");
// verify
assertThat(actual).hasSize(1);
assertThat(actual.get(0).getName()).isEqualTo("Small Car - 01");
assertThat(actual.get(0).getManual().getText()).isEqualTo("Just put all the pieces together in the right order");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.