简体   繁体   English

如何在 Spring Boot 应用程序中手动注册非标准化 SQL 函数?

[英]How to register non-standarized SQL functions manually in Spring Boot application?

I'm using JPA query in my current spring-boot project.我在当前的 spring-boot 项目中使用 JPA 查询。 How can I add non-standardized SQL functions like GROUP_CONCAT ?如何添加非标准化 SQL 函数,如GROUP_CONCAT

Prior, to my previous problem : How to show a column result in a one line comma separated list in JPA query之前,我以前的问题: 如何在 JPA 查询中的一行逗号分隔列表中显示列结果

I found that GROUP_CONCAT is not a registered function in JPA query but could be accessed by registering it manually.我发现 GROUP_CONCAT 不是 JPA 查询中的注册函数,但可以通过手动注册来访问它。 I already tried following links but didn't work for me :我已经尝试过以下链接,但对我不起作用:

How to add non-standardized sql functions in Spring Boot application? 如何在 Spring Boot 应用程序中添加非标准化的 sql 函数?

Registering a SQL function with JPA and Hibernate 使用 JPA 和 Hibernate 注册 SQL 函数

https://thoughts-on-java.org/database-functions/ https://thoughts-on-java.org/database-functions/

https://vladmihalcea.com/hibernate-sql-function-jpql-criteria-api-query/ https://vladmihalcea.com/hibernate-sql-function-jpql-criteria-api-query/

1. 1.

public class SqlFunctionsMetadataBuilderContributor
        implements MetadataBuilderContributor {

    @Override
    public void contribute(MetadataBuilder metadataBuilder) {
        metadataBuilder.applySqlFunction(
                "group_concat",
                new StandardSQLFunction(
                        "group_concat",
                        StandardBasicTypes.STRING
                )
        );
    }
}

2. 2.

 public String render(Type firstArgumentType, List arguments, SessionFactoryImplementor factory)
            throws QueryException {
        if (arguments.size() < 1) {
            throw new QueryException(new IllegalArgumentException("group_concat should have at least one arg"));
        }

        StringBuilder builder = new StringBuilder();
        if (arguments.size() > 1 && arguments.get(0).equals("'distinct'")) {
            builder.append("distinct ");
            builder.append(arguments.get(1));
        } else {
            builder.append(arguments.get(0));
        }

        return "group_concat(" + builder.toString() + ")";
    }

3. 3.

@Configuration
public class DataSource {
    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        AbstractJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        adapter.setShowSql(true);
        adapter.setDatabase(Database.MYSQL);
        // package to CustomMysqlDialect
        adapter.setDatabasePlatform("com.myprojet.admin.configuration.RegisterSqlFunction");
        adapter.setGenerateDdl(false);
        return adapter;
    }
}

    public RegisterSqlFunction() {
        super();

         registerFunction("group_concat, new StandardSQLFunction("group_concat", 
       StandardBasicTypes.STRING));
    }


I except using group_concat with JPA query.我除了将 group_concat 与 JPA 查询一起使用。

You can find a fully functional example in my High-Performance Java Persistence GitHub repository .您可以在我的High-Performance Java Persistence GitHub 存储库 中找到一个功能齐全的示例。

In your case, you don't need to customize the JpaPlatform .在您的情况下,您不需要自定义JpaPlatform That should be set to the HibernateJpaPlatform .那应该设置为HibernateJpaPlatform

You can register the MetadataBuilderContributer either programaticallly via the application.properties configuration file:您可以通过application.properties配置文件以编程方式注册MetadataBuilderContributer

hibernate.metadata_builder_contributor=com.vladmihalcea.book.hpjp.SqlFunctionsMetadataBuilderContributor

Create a class and add mySql Function you need to use in the overridden method:创建一个类并添加需要在重写方法中使用的 mySql 函数:

public class SqlFunctionsMetadataBuilderContributor implements MetadataBuilderContributor{

 @Override
    public void contribute(MetadataBuilder metadataBuilder) {
        metadataBuilder.applySqlFunction(
            "group_concat",
            new StandardSQLFunction(
                "group_concat",
                StandardBasicTypes.STRING
            )
        );
    }
}

After that, provide your metadata_builder_contributor via application.properties:之后,通过 application.properties 提供您的 metadata_builder_contributor:

spring.jpa.properties.hibernate.metadata_builder_contributor = qualifiedClassName

In case someone is having issues when registering this in a SpringBoot app this is the right way:如果有人在 SpringBoot 应用程序中注册时遇到问题,这是正确的方法:

Create a class that implements: MetadataBuilderContributor interface.创建一个实现:MetadataBuilderContributor 接口的类。

package com.application.config;

public class SqlFunctionsMetadataBuilderContributor implements MetadataBuilderContributor {

  @Override
  public void contribute(MetadataBuilder metadataBuilder) {
    metadataBuilder.applySqlFunction(
        "STRING_AGG",
        new StandardSQLFunction(
            "STRING_AGG",
            StandardBasicTypes.STRING
        )
    );
  }
}

In your application .yml (or .properties) refer to the previously created class in the following properties path: spring.jpa.properties.hibernate.metadata_builder_contributor在您的应用程序中,.yml(或 .properties)在以下属性路径中引用先前创建的类: spring.jpa.properties.hibernate.metadata_builder_contributor

  spring:      
    jpa:
      properties:
        hibernate:
          metadata_builder_contributor: com.application.config.SqlFunctionsMetadataBuilderContributor

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM