Моя база данных Oracle не поддерживает кодировку utf-8, однако значения столбцов некоторых таблиц по-прежнему состоят из символов utf-8. он вставляется с использованием текстового литерала N. Итак, моя цель — иметь возможность фильтровать эти символы utf-8 из приложения весенней загрузки. В настоящее время, когда я пытаюсь фильтровать данные, символы utf-8 читаются как '?' знаки вопроса в базе данных. Моя первоначальная мысль, которую нужно исправить, заключалась в том, чтобы добиться следующего запроса оракула в моем загрузочном приложении Spring.
SELECT * FROM entity WHERE text like N'%utf-8-characters%'
(этот запрос корректно работает в базе данных)
Мне не удалось найти код hql для замены строкового литерала N.
@Query("SELECT e FROM Entity e WHERE " + "(:filter is null or :filter = '' or "
+ "LOWER(e.text) LIKE CONCAT('%',LOWER(:filter), '%') "
+ "ORDER BY e.modifiedDate DESC")
Page<Entity> findAllByOrderByModifiedDateDesc(@Nullable String filter, Pageable pageable);
Я также попробовал собственный запрос, он работал, например, если я жестко запрограммировал фильтр, но не мог соединиться с входящим аргументом.
работает, но жестко запрограммировано -> WHERE text LIKE N'%აა%'
недействительно -> WHERE text LIKE N:filter
@Query(value = "SELECT * FROM entity WHERE text LIKE CONCAT('%',CONCAT(:filter,'%')) ORDER BY modified_date",nativeQuery = true)
Page<Entity> findAllByOrderByModifiedDateDesc(@Nullable String filter, Pageable pageable);
добавление свойств кодировки не будет работать, потому что, как я уже сказал, сама база данных не читает символы utf-8.
spring.datasource.url=jdbc:oracle:thin:@111.11.1.111:1111:DB?useUnicode=true&characterEncoding=UTF-8
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true
ни такие bean-компоненты, как CharacterEncodingFilter.
для базы данных обычных символов используется кодировка CL8MSWIN1251. а для национальных символов с префиксом N используется UTF-16.
но дело в том, что даже при использовании собственного запроса я не могу использовать префикс N. запрос -> @Query(value = "SELECT * FROM объект WHERE message_prefix LIKE '%' || N:text || '%' ORDER BY Modified_date",nativeQuery = true) следующее исключение -> Исключение JDBC, выполняющее SQL [select * from (SELECT * FROM объект WHERE text LIKE '%' || N? || '%' ORDER BY Modified_date), где rownum<=?]
Сначала вам нужно добавить свойство в признанные национализированные поля в базе данных:
spring.jpa.properties.hibernate.use_nationalized_character_data=true
тогда все, что мне нужно было сделать, это не использовать функции оракула. Я не знаю почему, но
@Query("SELECT e FROM Entity e WHERE e.text LIKE %:messagePrefix% ")
этот запрос работает правильно с символами utf-8. однако при использовании функций оракула, таких как Concat, это не сработало @Query("SELECT e FROM Entity e WHERE e.text LIKE CONCAT('%',:text,'%') ") Даже для @Query("SELECT e FROM Entity e WHERE Lower(e.text) LIKE %:text% ") это не работает
@Query ожидает запросы JPQL, а не собственные запросы, вот почему.
Какую кодировку вы используете в базе данных. А если ваша база данных не поддерживает UTF-8 или любую другую кодировку Unicode,
LIKE
,LOWER
и т. д. не имеют особого смысла: движок не может правильно выполнить работу и может повредить символы, например если он считает, что какая-то буква с акцентом находится в латинице 1 (или производной), она может уменьшиться, что приведет к повреждению кодировки UTF-8.