Неверный текст JSON в аргументе 2 - json_contains с использованием Spring JPA - PullRequest
0 голосов
/ 21 ноября 2018

в моих элементах таблицы есть столбец json с именем tag.сохраняя данные как ["tag1", "tag2"].

Я хочу выбрать из этой таблицы фильтр с заданным тегом.
в командной строке mysql, json_contains работает.

select * from items where json_contains(tags, '"tag1"');

но как я могу использовать его в Spring JPA?

@Query(value = "select * from items where json_contains(tags, ?1))", nativeQuery = true)
Page<ItemDO> list(String query, Pageable pageable);

получил ошибку

TRACE 21469 --- [           main] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [VARCHAR] - [desc]
WARN 21469 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 1064, SQLState: 42000
ERROR 21469 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') limit 10' at line 1

так как я могу использовать json_contains в Spring JPA?

1 Ответ

0 голосов
/ 26 ноября 2018

Есть две проблемы с вашей реализацией:

  • Там, в качестве дополнительной скобки в конце запроса SQL), посмотрите, что говорят журналы.Вместо этого вы должны написать это следующим образом:

    @Query(value = "select * from items where json_contains(tags, ?1)", nativeQuery = true)
    
  • Сделав это, вам также необходимо заключить параметр метода (переменную вашего запроса) в двойные кавычки, чтобы точно соответствовать тому, что выпробовал в консоли командной строки MySQL.Таким образом, вы будете вызывать метод следующим образом:

    yourRepository.list("\"tag1\"", PageRequest.of(,10) );
    

Альтернативное решение

Вы можете использовать API данных Spring Data API чтобы избежать нативных запросов.

Таким образом, вы можете сделать следующее:

@Repository
public interface ItemRepository extends JpaRepository<ItemDao, Integer> , JpaSpecificationExecutor<ItemDao> {

    default Page<ItemDao> findItemsByJsonTagValue(String jsonTagValue, Pageable pageable){
       return findAll((root, query, builder) -> {
            final String CONTAINS_FUNCTION = "JSON_CONTAINS";
            final String JSON_COLUMN_NAME = "tags" ;
            final int TRUE_BIT = 1;
            return builder.equal(
                    builder.function(
                            CONTAINS_FUNCTION,
                            String.class,
                            root.<String>get(JSON_COLUMN_NAME),
                            builder.literal(String.format("\"%s\"", jsonTagValue))),TRUE_BIT);
    }, pageable);
}

}

И затем где-нибудь в своем коде вы вызовете метод следующим образом:

itemRepository.findItemsByJsonTagValue("tag1", PageRequest.of(0  ,10));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...