как вызвать функцию, которая использовала ключевые слова mysql в качестве параметров по запросу критерия? - PullRequest
0 голосов
/ 05 ноября 2019

Я использую mysql с запросом спецификации jpa. Я хочу знать, как я могу вызвать функцию, которая использовала ключевые слова mysql в качестве параметров.

Вот пример:

select * from schema3.countries order by convert(name using GBK);

Метод convert с использованием using и GBK ключевые слова в качестве параметров.

Я хочу вызвать функцию convert по запросу критерия.

Я попробовал следующее, но у меня это не работает.

Expression expression = join.get(Country_.NAME);
                Expression orderExpression = builder.function(
                        "convert",
                        String.class,
                        expression,
                        builder.literal("USING GBK")
                );

и

Path path = join.get(Country_.NAME);

                String countryNameAlias = path.getAlias();
                Expression orderExpression = builder.function(
                        "convert",
                        String.class,
                        builder.literal(countryNameAlias + " USING GBK")
                );

Переменная countryNameAlias равна нулю, поэтому она не работает.

Вот ошибка:

Hibernate: select expert0_.id as id1_14_, expert0_.code as code2_14_, expert0_.created_at as created_3_14_, expert0_.expert_information as expert_i4_14_, expert0_.meta_data_of_the_expert_information as meta_dat5_14_, expert0_.motherland as motherla8_14_, expert0_.number_of_applications as number_o6_14_, expert0_.updated_at as updated_7_14_, JSON_EXTRACT(expert0_.expert_information, '$.basicInformation.birthDate') as formula4_, case
           when
               JSON_EXTRACT(expert0_.expert_information, '$.basicInformation.gender') = 'MALE'
            then 0
else 1 end as formula5_, JSON_EXTRACT(expert0_.expert_information, '$.basicInformation.nameEN') as formula6_, convert(JSON_EXTRACT(expert0_.expert_information, '$.basicInformation.nameZH') using GBK) as formula7_ from expert expert0_ left outer join expert_application_record expertappl1_ on expert0_.id=expertappl1_.expert_id left outer join countries country2_ on expert0_.motherland=country2_.id where expertappl1_.latest=? order by convert(?) desc limit ?
2019-11-05 18:58:41.281 TRACE 15252 --- [nio-8080-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [BOOLEAN] - [true]
2019-11-05 18:58:41.281 TRACE 15252 --- [nio-8080-exec-2] o.h.type.descriptor.sql.BasicBinder      : binding parameter [2] as [VARCHAR] - [null USING GBK]
2019-11-05 18:58:41.282  WARN 15252 --- [nio-8080-exec-2] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 1064, SQLState: 42000
2019-11-05 18:58:41.282 ERROR 15252 --- [nio-8080-exec-2] 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 ') desc limit 10' at line 5
2019-11-05 18:58:41.285 ERROR 15252 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause

java.sql.SQLSyntaxErrorException: 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 ') desc limit 10' at line 5
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:118) ~[mysql-connector-java-8.0.11.jar:8.0.11]
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:95) ~[mysql-connector-java-8.0.11.jar:8.0.11]
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) ~[mysql-connector-java-8.0.11.jar:8.0.11]
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:960) ~[mysql-connector-java-8.0.11.jar:8.0.11]
    at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:1019) ~[mysql-connector-java-8.0.11.jar:8.0.11]
    at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeQuery(ProxyPreparedStatement.java:52) ~[HikariCP-2.7.9.jar:na]

Спасибо всем вам.

1 Ответ

0 голосов
/ 08 ноября 2019

Я изменил sql ниже:

select *, convert(name using GBK) as nameGBK from schema3.countries order by nameGBK;

Так что следующий вопрос - как добавить вычисляемый столбец в выборку. Мы можем добавить колонку к модели страны. Имя поля nameGBK и используется аннотация @Formula;вот код

    @Column(nullable = false, unique = true)
    private String name;

    @Formula("convert(name using GBK)")
    private String nameGBK;

, а затем в запросе критериев мы можем заказать по nameGBK. Вот код:

builder.desc(join.get(Country_.NAME_GBK));

Но используемый мной jpa не может проанализировать ключевые слова using и GBK, поэтому мы должны расширить диалект, который вы используете, и зарегистрировать ключевые слова.

Вот код:

public class CustomMariaDB53Dialect extends MariaDB53Dialect {
    private static final Logger LOG = LoggerFactory.getLogger(CustomMariaDB53Dialect.class);

    public CustomMariaDB53Dialect() {
        super();
        registerKeyword("using");
        registerKeyword("USING");
        registerKeyword("GBK");
        registerKeyword("gbk");
    }
}

И измените конфигурацию, чтобы сообщить спящему режиму, что вы используете новый диалект. Если вы используете данные весны jpa. Тогда вот конфиг:

spring:
  h2:
    console:
      enabled: true
  datasource:
    url: jdbc:mysql://dev:13306/schema3?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=GMT%2B8&zeroDateTimeBehavior=CONVERT_TO_NULL&nullCatalogMeansCurrent=true
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
    initialization-mode: always
  liquibase:
    enabled: false
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    properties:
      hibernate:
        order_inserts: true
        #here to tell the hibernate you are using a new dialect.
        dialect: com.hide.hide.CustomMariaDB53Dialect
        jdbc:
          batch_size: 100

Если это помогло, пожалуйста, дайте мне право голоса. Спасибо.

...