首页 > 解决方案 > 使用 Spring Boot 进行 JOOQ SQL 语法转换

问题描述

我有一个 SQL CE 语法的 SQL 脚本导出。当我的应用程序启动时,jooq 应该读取此脚本,将其解析为与 h2 兼容的 sql,然后将 create 和 insert 语句读取到我的 h2 db 中。不幸的是,我似乎无法让 JOOQ 在 Spring Boot 下运行。

我阅读了一些教程,但到目前为止,我最好阅读 Baeldung 的 Spring Boot 教程。但是这次它不起作用,因为我的 Autowired dataSource 始终为空。但显然spring boot应该自己配置它。

我坚持这篇教程帖子:https ://www.baeldung.com/spring-boot-support-for-jooq

有人知道这里缺少什么吗?

POM.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.example</groupId>
    <artifactId>hotcueconverter</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>hotcueconverter</name>
    <description>hotcueconverter</description>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jooq</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

应用程序属性

# Own settings
server.port=${8080}
# H2 Database
spring.datasource.url=jdbc:h2:file:./db/MIKStore
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=test
spring.datasource.password=test
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=none
# H2 Console
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.h2.console.settings.trace=false
spring.h2.console.settings.web-allow-others=false
spring.jooq.sql-dialect=H2

应用程序配置.java

package com.example.hotcueconverter;

import javax.sql.DataSource;

import org.jooq.impl.DataSourceConnectionProvider;
import org.jooq.impl.DefaultConfiguration;
import org.jooq.impl.DefaultDSLContext;
import org.jooq.impl.DefaultExecuteListenerProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;

@Configuration
public class ApplicationConfiguration {

    @Autowired
    ExceptionTranslator exceptionTranslator;

    @Autowired
    private DataSource dataSource;

    @Bean
    public DefaultDSLContext defaultDSLContext() {
        return new DefaultDSLContext(this.configuration());
    }

    @Bean
    public DataSourceConnectionProvider dataSourceConnectionProvider() {
        return new DataSourceConnectionProvider(new TransactionAwareDataSourceProxy(this.dataSource));
    }

    public DefaultConfiguration configuration() {
        final DefaultConfiguration jooqConfiguration = new DefaultConfiguration();
        jooqConfiguration.set(this.dataSourceConnectionProvider());
        jooqConfiguration.set(new DefaultExecuteListenerProvider(this.exceptionTranslator));

        return jooqConfiguration;
    }
}

由于教程中没有提到exceptionTransformer,所以我自己写了exceptionTranslator:

package com.example.hotcueconverter;

import javax.sql.DataSource;

import org.jooq.impl.DataSourceConnectionProvider;
import org.jooq.impl.DefaultConfiguration;
import org.jooq.impl.DefaultDSLContext;
import org.jooq.impl.DefaultExecuteListenerProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;

@Configuration
public class ApplicationConfiguration {

    @Autowired
    ExceptionTranslator exceptionTranslator;

    @Autowired
    private DataSource dataSource;

    @Bean
    public DefaultDSLContext defaultDSLContext() {
        return new DefaultDSLContext(this.configuration());
    }

    @Bean
    public DataSourceConnectionProvider dataSourceConnectionProvider() {
        return new DataSourceConnectionProvider(new TransactionAwareDataSourceProxy(this.dataSource));
    }

    public DefaultConfiguration configuration() {
        final DefaultConfiguration jooqConfiguration = new DefaultConfiguration();
        jooqConfiguration.set(this.dataSourceConnectionProvider());
        jooqConfiguration.set(new DefaultExecuteListenerProvider(this.exceptionTranslator));

        return jooqConfiguration;
    }
}

我的 TestModule/Service 数据 PS: this.loadFile 只是加载 sql 脚本。

@Service
public class TestModule {

    private static final Logger LOGGER = LoggerFactory.getLogger(TestModule.class);
    private static final String MIKSTORE_FILENAME = "mikstore_export.sql";

    @Autowired
    DefaultDSLContext dslContext;

    public void test() throws Exception {
        final String fileAsString = this.loadFile(MIKSTORE_FILENAME);

        final Parser parser = this.dslContext.parser();
        final Queries queries = parser.parse(fileAsString);

        this.dslContext.execute(queries.toString());
    }

任何帮助,即使它是实现这一目标的另一种方式,将不胜感激!:)

谢谢!

标签: springspring-bootdatasourceh2jooq

解决方案


升级版:

我发现了问题:DI 使用的是不是由 spring 管理的 DSL,因此它为空,因为我没有自己初始化它。

我还在应用程序属性中设置了错误的休眠 DDL 属性。因为我想使用 jooq 创建模式和数据,所以我不得不将 hibernate auto ddl 设置为 none


推荐阅读