4

在 Spring Data JDBC 示例中,如何在@Query注解中编写简单查询?

例如在LegoSet Repository中,我如何添加一个简单的findByName查询?

当我尝试

@Query("select * from lego_set where name = :name") List<LegoSet> findByName(@Param("name") String name); 它引发以下错误:

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) `

此外,参考文档似乎是从一些通用的 spring 数据文档中复制的,因为它提到了 spring data jdbc 中尚不存在的派生查询。

4

3 回答 3

2

就像@jens-schauder 的回答一样:

查询应该是:

    @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);

使用此方法,以下测试通过:

    @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");
    }
于 2019-11-26T11:24:27.427 回答
1

LegoSet实体与 a 具有 1:1 的关系Manual。Spring Data JDBC 使用连接选择这样的构造,并期望ResultSet.

请注意,它期望代表Manual实体本身的列加上形成对LegoSet. 此外,所有列名都应以属性名 + 为前缀_,即manual_在这种情况下。

错误消息实际上告诉您缺少的列(以缺少的空格为模)Column not found: manual_handbuch_id:.

或者,您也可以提供自己的 RowMapper

关于文档:

你是对的。(几乎)所有 Spring Data 模块的文档都包含一个通用部分,这很容易导致混淆。有一张票可以提出更好的解决方案

于 2018-10-25T05:37:03.517 回答
0

我认为您正在尝试执行本机查询。因此,请尝试如下

@Query(  value = "SELECT * FROM lego_set ls where ls.name = :name",
           nativeQuery = true)
  List<LegoSet> findByName(@Param("name") String name);

这应该有效。

于 2018-10-25T06:06:09.770 回答