7. Integration of Spring Boot and jOQ

Posted by UrbanCondor on Wed, 04 Mar 2020 04:26:18 +0100

The Spring Boot or Spring Cloud-based micro-service system is the mainstream in the current situation of prevailing micro-services, and is also the new direction of selection in the current business scenario.

Using Spring Boot to integrate jOOQ is relatively simple compared to using Spring directly

Maven Dependency

Spring Boot officially has jOQ support, so simply refer to spring-boot-starter-jooq and the corresponding jdbc Driver

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.1.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jooq</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>org.jooq</groupId>
        <artifactId>jooq-codegen</artifactId>
        <scope>provided</scope>
    </dependency>
</dependencies>

To configure

One of the biggest features of Spring Boot is that there are many AutoConfiguration autoconfigurations. Spr-boot-starter-jooq relies on spring-boot-starter-jdbc, which automatically configures data sources, transaction managers, etc.

spring-boot-starter-jooq automatically configures the org.jooq.Configuration and org.jooq.DSLContext objects.We just need to write the data source configuration in src/main/resources/application.yml, everything else can be handled by Spring Boot

  • src/main/resources/application.yml
    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/learn-jooq?serverTimezone=GMT%2B8
        username: root
        password: root

Run/Test

Start the Spring Boot service directly through the main method

@SpringBootApplication
public class Section8Main {
    public static void main(String[] args) {
        SpringApplication.run(Section8Main.class);
    }
}

In the test case, use the SpringBootTest annotation

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Section8Main.class)
@Transactional
@Rollback
public class BaseTest {
    @Autowired
    DSLContext dslContext;

    @Autowired
    Configuration configuration;

    @Autowired
    TransactionManager transactionManager;

    @Test
    public void empty() {
        Assertions.assertNotNull(dslContext);
        Assertions.assertNotNull(configuration);
        Assertions.assertNotNull(transactionManager);
    }
}

 

JooqAutoConfiguration Source Parsing

Here is jOOQ's auto-configuration source code, copied from spring-boot-autoconfigure, and you can see that this configuration will be executed after data source and transaction configurations

For Bean dslContext and jooqConfiguration, the @ConditionalOnMissingBean annotation is used for most of the automatically configured beans, which identifies that the configuration labeled by the annotation will be performed without a Bean

  • org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration
/**
 * {@link EnableAutoConfiguration Auto-configuration} for JOOQ.
 *
 * @author Andreas Ahlenstorf
 * @author Michael Simons
 * @author Dmytro Nosan
 * @since 1.3.0
 */
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(DSLContext.class)
@ConditionalOnBean(DataSource.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, TransactionAutoConfiguration.class })
public class JooqAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean(ConnectionProvider.class)
	public DataSourceConnectionProvider dataSourceConnectionProvider(DataSource dataSource) {
		return new DataSourceConnectionProvider(new TransactionAwareDataSourceProxy(dataSource));
	}

	@Bean
	@ConditionalOnBean(PlatformTransactionManager.class)
	public SpringTransactionProvider transactionProvider(PlatformTransactionManager txManager) {
		return new SpringTransactionProvider(txManager);
	}

	@Bean
	@Order(0)
	public DefaultExecuteListenerProvider jooqExceptionTranslatorExecuteListenerProvider() {
		return new DefaultExecuteListenerProvider(new JooqExceptionTranslator());
	}

	@Configuration(proxyBeanMethods = false)
	@ConditionalOnMissingBean(DSLContext.class)
	@EnableConfigurationProperties(JooqProperties.class)
	public static class DslContextConfiguration {

		@Bean
		public DefaultDSLContext dslContext(org.jooq.Configuration configuration) {
			return new DefaultDSLContext(configuration);
		}

		@Bean
		@ConditionalOnMissingBean(org.jooq.Configuration.class)
		public DefaultConfiguration jooqConfiguration(JooqProperties properties, ConnectionProvider connectionProvider,
				DataSource dataSource, ObjectProvider<TransactionProvider> transactionProvider,
				ObjectProvider<RecordMapperProvider> recordMapperProvider,
				ObjectProvider<RecordUnmapperProvider> recordUnmapperProvider, ObjectProvider<Settings> settings,
				ObjectProvider<RecordListenerProvider> recordListenerProviders,
				ObjectProvider<ExecuteListenerProvider> executeListenerProviders,
				ObjectProvider<VisitListenerProvider> visitListenerProviders,
				ObjectProvider<TransactionListenerProvider> transactionListenerProviders,
				ObjectProvider<ExecutorProvider> executorProvider) {
			DefaultConfiguration configuration = new DefaultConfiguration();
			configuration.set(properties.determineSqlDialect(dataSource));
			configuration.set(connectionProvider);
			transactionProvider.ifAvailable(configuration::set);
			recordMapperProvider.ifAvailable(configuration::set);
			recordUnmapperProvider.ifAvailable(configuration::set);
			settings.ifAvailable(configuration::set);
			executorProvider.ifAvailable(configuration::set);
			configuration.set(recordListenerProviders.orderedStream().toArray(RecordListenerProvider[]::new));
			configuration.set(executeListenerProviders.orderedStream().toArray(ExecuteListenerProvider[]::new));
			configuration.set(visitListenerProviders.orderedStream().toArray(VisitListenerProvider[]::new));
			configuration.setTransactionListenerProvider(
					transactionListenerProviders.orderedStream().toArray(TransactionListenerProvider[]::new));
			return configuration;
		}
	}
}

If we need to use multiple data sources, we can use the exclude option in @SpringBootApplication in the boot entry to prevent Spring Boot from automatically configuring data sources and jOOQ configuration.Finally, refer to the previous article on multiple data sources and configure it the same way. Spring Boot is essentially just an integration of the Spring framework

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, 
                                  JooqAutoConfiguration.class, 
                                  TransactionAutoConfiguration.class})

Content Summary

Source code for this chapter: https://github.com/k55k32/learn-jooq/tree/master/section-8

In this chapter, you can see that the integration of Spring Boot saves a lot of work compared to using Spring directly, and many configurations are automatically configured by Spring Boot for us.So later articles will be based on this, and later source demonstrations will be expanded based on the source code in this chapter

In addition, this is the end of integrating the relevant chapters, and in the following chapters, it will solve some practical business problems.For example, jOOQ currently generates DAO s that contain only a few basic queries.Multi-conditional queries, paging queries, associated queries, etc., which are often encountered in business development, are not very supported.In the next chapters, we will explain some practical business issues

0 original articles published, 0 praised, 56 visits
Private letter follow

Topics: Spring JDBC MySQL Maven