Spring Boot的JOOQ SQL语法转换

问题描述

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

我阅读了一些教程,但到目前为止,我最好还是阅读Baeldung的spring boot教程。但是这一次不起作用,因为我的Autowired dataSource始终为null。但是,弹簧靴显然应该自行配置。

我坚持了本教程文章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>

application.properties

# 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

ApplicationConfiguration.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());
    }

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

谢谢!

解决方法

UPD:

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

我还将appliciation属性中的休眠DDL属性设置为错误。由于我想使用jooq创建架构和数据,因此不得不将hibernate auto ddl设置为none