diff --git a/spring-boot-autoconfigure/pom.xml b/spring-boot-autoconfigure/pom.xml index 7de84e78c8..4ff4029fc0 100644 --- a/spring-boot-autoconfigure/pom.xml +++ b/spring-boot-autoconfigure/pom.xml @@ -510,6 +510,11 @@ aspectjweaver true + + org.jooq + jooq + true + org.springframework.boot diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfiguration.java new file mode 100644 index 0000000000..c4e747e3e8 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfiguration.java @@ -0,0 +1,137 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jooq; + +import javax.sql.DataSource; + +import org.jooq.ConnectionProvider; +import org.jooq.DSLContext; +import org.jooq.ExecuteListenerProvider; +import org.jooq.RecordListenerProvider; +import org.jooq.RecordMapperProvider; +import org.jooq.SQLDialect; +import org.jooq.TransactionProvider; +import org.jooq.VisitListenerProvider; +import org.jooq.conf.Settings; +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.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.util.StringUtils; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for JOOQ. + * + * @author Andreas Ahlenstorf + * @since 1.3.0 + */ +@Configuration +@ConditionalOnClass(DSLContext.class) +@ConditionalOnBean(DataSource.class) +@AutoConfigureAfter(DataSourceAutoConfiguration.class) +public class JooqAutoConfiguration { + + @Bean + @ConditionalOnMissingBean(DataSourceConnectionProvider.class) + public DataSourceConnectionProvider dataSourceConnectionProvider(DataSource dataSource) { + return new DataSourceConnectionProvider(new TransactionAwareDataSourceProxy( + dataSource)); + } + + @Bean + @ConditionalOnBean(PlatformTransactionManager.class) + public TransactionProvider transactionProvider(PlatformTransactionManager txManager) { + return new SpringTransactionProvider(txManager); + } + + @Bean + public ExecuteListenerProvider jooqExceptionTranslatorExecuteListenerProvider() { + return new DefaultExecuteListenerProvider(new JooqExceptionTranslator()); + } + + @Configuration + @ConditionalOnMissingBean(DSLContext.class) + @EnableConfigurationProperties(JooqProperties.class) + public static class DslContextConfiguration { + + @Autowired + private JooqProperties properties = new JooqProperties(); + + @Autowired + private ConnectionProvider connectionProvider; + + @Autowired(required = false) + private TransactionProvider transactionProvider; + + @Autowired(required = false) + private RecordMapperProvider recordMapperProvider; + + @Autowired(required = false) + private Settings settings; + + @Autowired(required = false) + private RecordListenerProvider[] recordListenerProviders; + + @Autowired + private ExecuteListenerProvider[] executeListenerProviders; + + @Autowired(required = false) + private VisitListenerProvider[] visitListenerProviders; + + @Bean + public DefaultDSLContext dslContext(org.jooq.Configuration configuration) { + return new DefaultDSLContext(configuration); + } + + @Bean + @ConditionalOnMissingBean(org.jooq.Configuration.class) + public DefaultConfiguration jooqConfiguration() { + DefaultConfiguration configuration = new DefaultConfiguration(); + if (!StringUtils.isEmpty(this.properties.getSqlDialect())) { + configuration.set(SQLDialect.valueOf(this.properties.getSqlDialect())); + } + configuration.set(this.connectionProvider); + if (this.transactionProvider != null) { + configuration.set(this.transactionProvider); + } + if (this.recordMapperProvider != null) { + configuration.set(this.recordMapperProvider); + } + if (this.settings != null) { + configuration.set(this.settings); + } + configuration.set(this.recordListenerProviders); + configuration.set(this.executeListenerProviders); + configuration.set(this.visitListenerProviders); + return configuration; + } + + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqExceptionTranslator.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqExceptionTranslator.java new file mode 100644 index 0000000000..addc5857ea --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqExceptionTranslator.java @@ -0,0 +1,90 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jooq; + +import java.sql.SQLException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jooq.ExecuteContext; +import org.jooq.SQLDialect; +import org.jooq.impl.DefaultExecuteListener; +import org.springframework.dao.DataAccessException; +import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator; +import org.springframework.jdbc.support.SQLExceptionTranslator; +import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator; + +/** + * Transforms {@link java.sql.SQLException} into a Spring-specific @{link + * DataAccessException}. + * + * @author Lukas Eder + * @author Andreas Ahlenstorf + * @author Phillip Webb + */ +class JooqExceptionTranslator extends DefaultExecuteListener { + + // Based on the jOOQ-spring-example from https://github.com/jOOQ/jOOQ + + private static final Log logger = LogFactory.getLog(JooqExceptionTranslator.class); + + @Override + public void exception(ExecuteContext context) { + SQLExceptionTranslator translator = getTranslator(context); + // The exception() callback is not only triggered for SQL exceptions but also for + // "normal" exceptions. In those cases sqlException() returns null. + SQLException exception = context.sqlException(); + while (exception != null) { + handle(context, translator, exception); + exception = exception.getNextException(); + } + } + + private SQLExceptionTranslator getTranslator(ExecuteContext context) { + SQLDialect dialect = context.configuration().dialect(); + if (dialect != null) { + return new SQLErrorCodeSQLExceptionTranslator(dialect.name()); + } + return new SQLStateSQLExceptionTranslator(); + } + + /** + * Handle a single exception in the chain. SQLExceptions might be nested multiple + * levels deep. The outermost exception is usually the least interesting one + * ("Call getNextException to see the cause."). Therefore the innermost exception is + * propagated and all other exceptions are logged. + * @param context the execute context + * @param translator the exception translator + * @param exception the exception + */ + private void handle(ExecuteContext context, SQLExceptionTranslator translator, + SQLException exception) { + DataAccessException translated = translate(context, translator, exception); + if (exception.getNextException() == null) { + context.exception(translated); + } + else { + logger.error("Execution of SQL statement failed.", translated); + } + } + + private DataAccessException translate(ExecuteContext context, + SQLExceptionTranslator translator, SQLException exception) { + return translator.translate("jOOQ", context.sql(), exception); + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqProperties.java new file mode 100644 index 0000000000..c68961bb71 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/JooqProperties.java @@ -0,0 +1,44 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jooq; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Configuration properties for the JOOQ database library. + * + * @author Andreas Ahlenstorf + * @since 1.3.0 + */ +@ConfigurationProperties(prefix = "spring.jooq") +public class JooqProperties { + + /** + * SQLDialect JOOQ used when communicating with the configured datasource, e.g. + * "POSTGRES". + */ + private String sqlDialect; + + public String getSqlDialect() { + return this.sqlDialect; + } + + public void setSqlDialect(String sqlDialect) { + this.sqlDialect = sqlDialect; + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransaction.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransaction.java new file mode 100644 index 0000000000..c766d20a69 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransaction.java @@ -0,0 +1,43 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jooq; + +import org.jooq.Transaction; +import org.springframework.transaction.TransactionStatus; + +/** + * Adapts a Spring transaction for JOOQ. + * + * @author Lukas Eder + * @author Andreas Ahlenstorf + * @author Phillip Webb + */ +class SpringTransaction implements Transaction { + + // Based on the jOOQ-spring-example from https://github.com/jOOQ/jOOQ + + private final TransactionStatus transactionStatus; + + public SpringTransaction(TransactionStatus transactionStatus) { + this.transactionStatus = transactionStatus; + } + + public TransactionStatus getTxStatus() { + return this.transactionStatus; + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransactionProvider.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransactionProvider.java new file mode 100644 index 0000000000..bfe80f1fc0 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/SpringTransactionProvider.java @@ -0,0 +1,66 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jooq; + +import org.jooq.TransactionContext; +import org.jooq.TransactionProvider; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.DefaultTransactionDefinition; + +/** + * Allows Spring Transaction to be used with JOOQ. + * + * @author Lukas Eder + * @author Andreas Ahlenstorf + * @author Phillip Webb + */ +class SpringTransactionProvider implements TransactionProvider { + + // Based on the jOOQ-spring-example from https://github.com/jOOQ/jOOQ + + private final PlatformTransactionManager transactionManager; + + SpringTransactionProvider(PlatformTransactionManager transactionManager) { + this.transactionManager = transactionManager; + } + + @Override + public void begin(TransactionContext context) { + TransactionDefinition definition = new DefaultTransactionDefinition( + TransactionDefinition.PROPAGATION_NESTED); + TransactionStatus status = this.transactionManager.getTransaction(definition); + context.transaction(new SpringTransaction(status)); + } + + @Override + public void commit(TransactionContext ctx) { + this.transactionManager.commit(getTransactionStatus(ctx)); + } + + @Override + public void rollback(TransactionContext ctx) { + this.transactionManager.rollback(getTransactionStatus(ctx)); + } + + private TransactionStatus getTransactionStatus(TransactionContext ctx) { + SpringTransaction transaction = (SpringTransaction) ctx.transaction(); + return transaction.getTxStatus(); + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/package-info.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/package-info.java new file mode 100644 index 0000000000..0ee259b983 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jooq/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for JOOQ. + */ +package org.springframework.boot.autoconfigure.jooq; \ No newline at end of file diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index 05834600d2..8fe06c5c4c 100644 --- a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -39,6 +39,7 @@ org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchDataAutoConfig org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\ org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\ org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\ +org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\ org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\ org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\ org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\ diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfigurationTests.java new file mode 100644 index 0000000000..b2003bbf9b --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/jooq/JooqAutoConfigurationTests.java @@ -0,0 +1,266 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.jooq; + +import javax.sql.DataSource; + +import org.hamcrest.Matcher; +import org.jooq.DSLContext; +import org.jooq.ExecuteListener; +import org.jooq.ExecuteListenerProvider; +import org.jooq.Record; +import org.jooq.RecordListener; +import org.jooq.RecordListenerProvider; +import org.jooq.RecordMapper; +import org.jooq.RecordMapperProvider; +import org.jooq.RecordType; +import org.jooq.SQLDialect; +import org.jooq.TransactionalRunnable; +import org.jooq.VisitListener; +import org.jooq.VisitListenerProvider; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; +import org.springframework.boot.test.EnvironmentTestUtils; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +/** + * Tests for {@link JooqAutoConfiguration}. + * + * @author Andreas Ahlenstorf + * @author Phillip Webb + */ +public class JooqAutoConfigurationTests { + + private static final String[] NO_BEANS = {}; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + + @Before + public void init() { + EnvironmentTestUtils.addEnvironment(this.context, + "spring.datasource.name:jooqtest"); + EnvironmentTestUtils.addEnvironment(this.context, "spring.jooq.sql-dialect:H2"); + } + + @After + public void close() { + if (this.context != null) { + this.context.close(); + } + } + + @Test + public void noDataSource() throws Exception { + registerAndRefresh(JooqAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + assertEquals(0, this.context.getBeanNamesForType(DSLContext.class).length); + } + + @Test + public void jooqWithoutTx() throws Exception { + registerAndRefresh(JooqDataSourceConfiguration.class, + JooqAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class); + assertThat(getBeanNames(PlatformTransactionManager.class), equalTo(NO_BEANS)); + assertThat(getBeanNames(SpringTransactionProvider.class), equalTo(NO_BEANS)); + DSLContext dsl = this.context.getBean(DSLContext.class); + dsl.execute("create table jooqtest (name varchar(255) primary key);"); + dsl.transaction(new AssertFetch(dsl, "select count(*) as total from jooqtest;", + equalTo("0"))); + dsl.transaction(new ExecuteSql(dsl, "insert into jooqtest (name) values ('foo');")); + dsl.transaction(new AssertFetch(dsl, "select count(*) as total from jooqtest;", + equalTo("1"))); + try { + dsl.transaction(new ExecuteSql(dsl, + "insert into jooqtest (name) values ('bar');", + "insert into jooqtest (name) values ('foo');")); + fail("An DataIntegrityViolationException should have been thrown."); + } + catch (DataIntegrityViolationException ex) { + } + dsl.transaction(new AssertFetch(dsl, "select count(*) as total from jooqtest;", + equalTo("2"))); + } + + @Test + public void jooqWithTx() throws Exception { + registerAndRefresh(JooqDataSourceConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, TxManagerConfiguration.class, + JooqAutoConfiguration.class); + this.context.getBean(PlatformTransactionManager.class); + DSLContext dsl = this.context.getBean(DSLContext.class); + assertEquals(SQLDialect.H2, dsl.configuration().dialect()); + dsl.execute("create table jooqtest_tx (name varchar(255) primary key);"); + dsl.transaction(new AssertFetch(dsl, + "select count(*) as total from jooqtest_tx;", equalTo("0"))); + dsl.transaction(new ExecuteSql(dsl, + "insert into jooqtest_tx (name) values ('foo');")); + dsl.transaction(new AssertFetch(dsl, + "select count(*) as total from jooqtest_tx;", equalTo("1"))); + try { + dsl.transaction(new ExecuteSql(dsl, + "insert into jooqtest (name) values ('bar');", + "insert into jooqtest (name) values ('foo');")); + fail("A DataIntegrityViolationException should have been thrown."); + } + catch (DataIntegrityViolationException ex) { + } + dsl.transaction(new AssertFetch(dsl, + "select count(*) as total from jooqtest_tx;", equalTo("1"))); + } + + @Test + public void customProvidersArePickedUp() { + registerAndRefresh(JooqDataSourceConfiguration.class, + PropertyPlaceholderAutoConfiguration.class, TxManagerConfiguration.class, + TestRecordMapperProvider.class, TestRecordListenerProvider.class, + TestExecuteListenerProvider.class, TestVisitListenerProvider.class, + JooqAutoConfiguration.class); + DSLContext dsl = this.context.getBean(DSLContext.class); + assertEquals(TestRecordMapperProvider.class, dsl.configuration() + .recordMapperProvider().getClass()); + assertThat(dsl.configuration().recordListenerProviders().length, equalTo(1)); + assertThat(dsl.configuration().executeListenerProviders().length, equalTo(2)); + assertThat(dsl.configuration().visitListenerProviders().length, equalTo(1)); + } + + private void registerAndRefresh(Class... annotatedClasses) { + this.context.register(annotatedClasses); + this.context.refresh(); + } + + private String[] getBeanNames(Class type) { + return this.context.getBeanNamesForType(type); + } + + private static class AssertFetch implements TransactionalRunnable { + + private final DSLContext dsl; + + private final String sql; + + private final Matcher matcher; + + public AssertFetch(DSLContext dsl, String sql, Matcher matcher) { + this.dsl = dsl; + this.sql = sql; + this.matcher = matcher; + } + + @Override + public void run(org.jooq.Configuration configuration) throws Exception { + assertThat(this.dsl.fetch(this.sql).getValue(0, 0).toString(), this.matcher); + } + + } + + private static class ExecuteSql implements TransactionalRunnable { + + private final DSLContext dsl; + + private final String[] sql; + + public ExecuteSql(DSLContext dsl, String... sql) { + this.dsl = dsl; + this.sql = sql; + } + + @Override + public void run(org.jooq.Configuration configuration) throws Exception { + for (String statement : this.sql) { + this.dsl.execute(statement); + } + } + + } + + @Configuration + protected static class JooqDataSourceConfiguration { + + @Bean + public DataSource jooqDataSource() { + return DataSourceBuilder.create().url("jdbc:hsqldb:mem:jooqtest") + .username("sa").build(); + } + + } + + @Configuration + protected static class TxManagerConfiguration { + + @Bean + public PlatformTransactionManager transactionManager(DataSource dataSource) { + return new DataSourceTransactionManager(dataSource); + } + + } + + protected static class TestRecordMapperProvider implements RecordMapperProvider { + + @Override + public RecordMapper provide(RecordType recordType, + Class aClass) { + return null; + } + + } + + protected static class TestRecordListenerProvider implements RecordListenerProvider { + + @Override + public RecordListener provide() { + return null; + } + + } + + protected static class TestExecuteListenerProvider implements ExecuteListenerProvider { + + @Override + public ExecuteListener provide() { + return null; + } + + } + + protected static class TestVisitListenerProvider implements VisitListenerProvider { + + @Override + public VisitListener provide() { + return null; + } + + } + +} diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml index 27afee588a..f686060fb7 100644 --- a/spring-boot-dependencies/pom.xml +++ b/spring-boot-dependencies/pom.xml @@ -100,6 +100,7 @@ 2.8.1 1.3.1 20141113 + 3.6.2 2.0.0 1.2 4.12 @@ -318,6 +319,11 @@ spring-boot-starter-jetty 1.3.0.BUILD-SNAPSHOT + + org.springframework.boot + spring-boot-starter-jooq + 1.3.0.BUILD-SNAPSHOT + org.springframework.boot spring-boot-starter-jta-atomikos @@ -1477,6 +1483,21 @@ json ${json.version} + + org.jooq + jooq + ${jooq.version} + + + org.jooq + jooq-meta + ${jooq.version} + + + org.jooq + jooq-codegen + ${jooq.version} + org.liquibase liquibase-core @@ -1836,6 +1857,11 @@ + + org.jooq + jooq-codegen-maven + ${jooq.version} + org.springframework.boot spring-boot-maven-plugin diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index 6395486b44..d81190c560 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -340,6 +340,9 @@ content into your application; rather pick only the properties that you need. spring.jta.log-dir= # transaction log dir spring.jta.*= # technology specific configuration + # JOOQ ({sc-spring-boot-autoconfigure}/jooq/JooqAutoConfiguration.{sc-ext}[JooqAutoConfiguration]) + spring.jooq.sql-dialect= + # ATOMIKOS spring.jta.atomikos.connectionfactory.borrow-connection-timeout=30 # Timeout, in seconds, for borrowing connections from the pool spring.jta.atomikos.connectionfactory.ignore-session-transacted-flag=true # Whether or not to ignore the transacted flag when creating session diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 14a9becd50..a94e15d3b4 100644 --- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -1998,6 +1998,114 @@ Hibernate autoconfig is active because the `ddl-auto` settings are more fine-gra +[[boot-features-jooq]] +== Using jOOQ +Java Object Oriented Querying (http://www.jooq.org/[jOOQ]) is a popular product from +http://www.datageekery.com/[Data Geekery] which generates Java code from your +database, and lets you build type safe SQL queries through its fluent API. Both the +commercial and open source editions can be used with Spring Boot. + + + +=== Code Generation +In oder to use jOOQ type-safe queries, you need to generate Java classes from your +database schema. You can follow the instructions in the +http://www.jooq.org/doc/3.6/manual-single-page/#jooq-in-7-steps-step3[jOOQ user manual]. +If you are using the `jooq-codegen-maven` plugin (and you also use the +`spring-boot-starter-parent` "`parent POM`") you can safely omit the plugin's `` +tag. You can also use Spring Boot defined version variables (e.g. `h2.version`) to +declare the plugin's database dependency. Here's an example: + +[source,xml,indent=0] +---- + + org.jooq + jooq-codegen-maven + + ... + + + + com.h2database + h2 + ${h2.version} + + + + + org.h2.Driver + jdbc:h2:~/yourdatabase + + + ... + + + +---- + + + +=== Using DSLContext +The fluent API offered by jOOQ is initiated via the `org.jooq.DSLContext` interface. +Spring Boot will auto-configure a `DSLContext` as a Spring Bean and connect it to your +application `DataSource`. To use the `DSLContext` you can just `@Autowire` it: + +[source,java,indent=0] +---- + @Component + public class JooqExample implements CommandLineRunner { + + private final DSLContext create; + + @Autowired + public JooqExample(DSLContext dlsContext) { + this.create = dlsContext; + } + + } +---- + +TIP: The jOOQ manual tends to use a variable named `create` to hold the `DSLContext`, +we've done the same for this example. + +You can then use the `DSLContext` to construct your queries: + +[source,java,indent=0] +---- + public List authorsBornAfter1980() { + return this.create.selectFrom(AUTHOR) + .where(AUTHOR.DATE_OF_BIRTH.greaterThan(new GregorianCalendar(1980, 0, 1))) + .fetch(AUTHOR.DATE_OF_BIRTH); + } +---- + + + +=== Customizing jOOQ +You can customize the SQL dialect used by jOOQ by setting `spring.jooq.sql-dialect` in +your `application.properties`. For example, to specify Postgres you would add: + +[source,properties,indent=0] +---- + spring.jooq.sql-dialect=Postgres +---- + +More advanced customizations can be achieved by defining your own `@Bean` definitions +which will be used when the jOOQ `Configuration` is created. You can define beans for +the following jOOQ Types: + +* `ConnectionProvider` +* `TransactionProvider` +* `RecordMapperProvider` +* `RecordListenerProvider` +* `ExecuteListenerProvider` +* `VisitListenerProvider` + +You can also create your own `org.jooq.Configuration` `@Bean` if you want to take +complete control of the jOOQ configuration. + + + [[boot-features-nosql]] == Working with NoSQL technologies Spring Data provides additional projects that help you access a variety of NoSQL diff --git a/spring-boot-samples/pom.xml b/spring-boot-samples/pom.xml index fa65e4bc82..fb39902274 100644 --- a/spring-boot-samples/pom.xml +++ b/spring-boot-samples/pom.xml @@ -33,6 +33,7 @@ spring-boot-sample-cache spring-boot-sample-data-elasticsearch spring-boot-sample-data-gemfire + spring-boot-sample-data-jooq spring-boot-sample-data-jpa spring-boot-sample-data-mongodb spring-boot-sample-data-redis diff --git a/spring-boot-samples/spring-boot-sample-jooq/README.adoc b/spring-boot-samples/spring-boot-sample-jooq/README.adoc new file mode 100644 index 0000000000..17e6be3742 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/README.adoc @@ -0,0 +1,9 @@ +== jOOQ Sample + +To rerun the code generator: + +[indent=0] +---- + $ rm -fr gensrc + $ mvn clean generate-sources -Pgenerate +---- diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Keys.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Keys.java new file mode 100644 index 0000000000..6a6fde5c32 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Keys.java @@ -0,0 +1,81 @@ +/** + * This class is generated by jOOQ + */ +package sample.jooq.domain; + + +import javax.annotation.Generated; + +import org.jooq.ForeignKey; +import org.jooq.UniqueKey; +import org.jooq.impl.AbstractKeys; + +import sample.jooq.domain.tables.Author; +import sample.jooq.domain.tables.Book; +import sample.jooq.domain.tables.BookStore; +import sample.jooq.domain.tables.BookToBookStore; +import sample.jooq.domain.tables.Language; +import sample.jooq.domain.tables.records.AuthorRecord; +import sample.jooq.domain.tables.records.BookRecord; +import sample.jooq.domain.tables.records.BookStoreRecord; +import sample.jooq.domain.tables.records.BookToBookStoreRecord; +import sample.jooq.domain.tables.records.LanguageRecord; + + +/** + * A class modelling foreign key relationships between tables of the PUBLIC + * schema + */ +@Generated( + value = { + "http://www.jooq.org", + "jOOQ version:3.6.2" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class Keys { + + // ------------------------------------------------------------------------- + // IDENTITY definitions + // ------------------------------------------------------------------------- + + + // ------------------------------------------------------------------------- + // UNIQUE and PRIMARY KEY definitions + // ------------------------------------------------------------------------- + + public static final UniqueKey CONSTRAINT_C = UniqueKeys0.CONSTRAINT_C; + public static final UniqueKey CONSTRAINT_7 = UniqueKeys0.CONSTRAINT_7; + public static final UniqueKey CONSTRAINT_1 = UniqueKeys0.CONSTRAINT_1; + public static final UniqueKey CONSTRAINT_F = UniqueKeys0.CONSTRAINT_F; + public static final UniqueKey CONSTRAINT_2 = UniqueKeys0.CONSTRAINT_2; + + // ------------------------------------------------------------------------- + // FOREIGN KEY definitions + // ------------------------------------------------------------------------- + + public static final ForeignKey FK_BOOK_AUTHOR = ForeignKeys0.FK_BOOK_AUTHOR; + public static final ForeignKey FK_BOOK_LANGUAGE = ForeignKeys0.FK_BOOK_LANGUAGE; + public static final ForeignKey FK_B2BS_BOOK_STORE = ForeignKeys0.FK_B2BS_BOOK_STORE; + public static final ForeignKey FK_B2BS_BOOK = ForeignKeys0.FK_B2BS_BOOK; + + // ------------------------------------------------------------------------- + // [#1459] distribute members to avoid static initialisers > 64kb + // ------------------------------------------------------------------------- + + private static class UniqueKeys0 extends AbstractKeys { + public static final UniqueKey CONSTRAINT_C = createUniqueKey(Language.LANGUAGE, Language.LANGUAGE.ID); + public static final UniqueKey CONSTRAINT_7 = createUniqueKey(Author.AUTHOR, Author.AUTHOR.ID); + public static final UniqueKey CONSTRAINT_1 = createUniqueKey(Book.BOOK, Book.BOOK.ID); + public static final UniqueKey CONSTRAINT_F = createUniqueKey(BookStore.BOOK_STORE, BookStore.BOOK_STORE.NAME); + public static final UniqueKey CONSTRAINT_2 = createUniqueKey(BookToBookStore.BOOK_TO_BOOK_STORE, BookToBookStore.BOOK_TO_BOOK_STORE.NAME, BookToBookStore.BOOK_TO_BOOK_STORE.BOOK_ID); + } + + private static class ForeignKeys0 extends AbstractKeys { + public static final ForeignKey FK_BOOK_AUTHOR = createForeignKey(sample.jooq.domain.Keys.CONSTRAINT_7, Book.BOOK, Book.BOOK.AUTHOR_ID); + public static final ForeignKey FK_BOOK_LANGUAGE = createForeignKey(sample.jooq.domain.Keys.CONSTRAINT_C, Book.BOOK, Book.BOOK.LANGUAGE_ID); + public static final ForeignKey FK_B2BS_BOOK_STORE = createForeignKey(sample.jooq.domain.Keys.CONSTRAINT_F, BookToBookStore.BOOK_TO_BOOK_STORE, BookToBookStore.BOOK_TO_BOOK_STORE.NAME); + public static final ForeignKey FK_B2BS_BOOK = createForeignKey(sample.jooq.domain.Keys.CONSTRAINT_1, BookToBookStore.BOOK_TO_BOOK_STORE, BookToBookStore.BOOK_TO_BOOK_STORE.BOOK_ID); + } +} diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Public.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Public.java new file mode 100644 index 0000000000..68dd8675b6 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Public.java @@ -0,0 +1,65 @@ +/** + * This class is generated by jOOQ + */ +package sample.jooq.domain; + + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.annotation.Generated; + +import org.jooq.Table; +import org.jooq.impl.SchemaImpl; + +import sample.jooq.domain.tables.Author; +import sample.jooq.domain.tables.Book; +import sample.jooq.domain.tables.BookStore; +import sample.jooq.domain.tables.BookToBookStore; +import sample.jooq.domain.tables.Language; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "http://www.jooq.org", + "jOOQ version:3.6.2" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class Public extends SchemaImpl { + + private static final long serialVersionUID = 1051839433; + + /** + * The reference instance of PUBLIC + */ + public static final Public PUBLIC = new Public(); + + /** + * No further instances allowed + */ + private Public() { + super("PUBLIC"); + } + + @Override + public final List> getTables() { + List result = new ArrayList(); + result.addAll(getTables0()); + return result; + } + + private final List> getTables0() { + return Arrays.>asList( + Language.LANGUAGE, + Author.AUTHOR, + Book.BOOK, + BookStore.BOOK_STORE, + BookToBookStore.BOOK_TO_BOOK_STORE); + } +} diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Tables.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Tables.java new file mode 100644 index 0000000000..e9888a06cd --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/Tables.java @@ -0,0 +1,53 @@ +/** + * This class is generated by jOOQ + */ +package sample.jooq.domain; + + +import javax.annotation.Generated; + +import sample.jooq.domain.tables.Author; +import sample.jooq.domain.tables.Book; +import sample.jooq.domain.tables.BookStore; +import sample.jooq.domain.tables.BookToBookStore; +import sample.jooq.domain.tables.Language; + + +/** + * Convenience access to all tables in PUBLIC + */ +@Generated( + value = { + "http://www.jooq.org", + "jOOQ version:3.6.2" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class Tables { + + /** + * The table PUBLIC.LANGUAGE + */ + public static final Language LANGUAGE = sample.jooq.domain.tables.Language.LANGUAGE; + + /** + * The table PUBLIC.AUTHOR + */ + public static final Author AUTHOR = sample.jooq.domain.tables.Author.AUTHOR; + + /** + * The table PUBLIC.BOOK + */ + public static final Book BOOK = sample.jooq.domain.tables.Book.BOOK; + + /** + * The table PUBLIC.BOOK_STORE + */ + public static final BookStore BOOK_STORE = sample.jooq.domain.tables.BookStore.BOOK_STORE; + + /** + * The table PUBLIC.BOOK_TO_BOOK_STORE + */ + public static final BookToBookStore BOOK_TO_BOOK_STORE = sample.jooq.domain.tables.BookToBookStore.BOOK_TO_BOOK_STORE; +} diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Author.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Author.java new file mode 100644 index 0000000000..5bef981db9 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Author.java @@ -0,0 +1,134 @@ +/** + * This class is generated by jOOQ + */ +package sample.jooq.domain.tables; + + +import java.sql.Date; +import java.util.Arrays; +import java.util.List; + +import javax.annotation.Generated; + +import org.jooq.Field; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.UniqueKey; +import org.jooq.impl.TableImpl; + +import sample.jooq.domain.Keys; +import sample.jooq.domain.Public; +import sample.jooq.domain.tables.records.AuthorRecord; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "http://www.jooq.org", + "jOOQ version:3.6.2" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class Author extends TableImpl { + + private static final long serialVersionUID = -1989221607; + + /** + * The reference instance of PUBLIC.AUTHOR + */ + public static final Author AUTHOR = new Author(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return AuthorRecord.class; + } + + /** + * The column PUBLIC.AUTHOR.ID. + */ + public final TableField ID = createField("ID", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, ""); + + /** + * The column PUBLIC.AUTHOR.FIRST_NAME. + */ + public final TableField FIRST_NAME = createField("FIRST_NAME", org.jooq.impl.SQLDataType.VARCHAR.length(50), this, ""); + + /** + * The column PUBLIC.AUTHOR.LAST_NAME. + */ + public final TableField LAST_NAME = createField("LAST_NAME", org.jooq.impl.SQLDataType.VARCHAR.length(50).nullable(false), this, ""); + + /** + * The column PUBLIC.AUTHOR.DATE_OF_BIRTH. + */ + public final TableField DATE_OF_BIRTH = createField("DATE_OF_BIRTH", org.jooq.impl.SQLDataType.DATE, this, ""); + + /** + * The column PUBLIC.AUTHOR.YEAR_OF_BIRTH. + */ + public final TableField YEAR_OF_BIRTH = createField("YEAR_OF_BIRTH", org.jooq.impl.SQLDataType.INTEGER, this, ""); + + /** + * The column PUBLIC.AUTHOR.DISTINGUISHED. + */ + public final TableField DISTINGUISHED = createField("DISTINGUISHED", org.jooq.impl.SQLDataType.TINYINT, this, ""); + + /** + * Create a PUBLIC.AUTHOR table reference + */ + public Author() { + this("AUTHOR", null); + } + + /** + * Create an aliased PUBLIC.AUTHOR table reference + */ + public Author(String alias) { + this(alias, AUTHOR); + } + + private Author(String alias, Table aliased) { + this(alias, aliased, null); + } + + private Author(String alias, Table aliased, Field[] parameters) { + super(alias, Public.PUBLIC, aliased, parameters, ""); + } + + /** + * {@inheritDoc} + */ + @Override + public UniqueKey getPrimaryKey() { + return Keys.CONSTRAINT_7; + } + + /** + * {@inheritDoc} + */ + @Override + public List> getKeys() { + return Arrays.>asList(Keys.CONSTRAINT_7); + } + + /** + * {@inheritDoc} + */ + @Override + public Author as(String alias) { + return new Author(alias, this); + } + + /** + * Rename this table + */ + public Author rename(String name) { + return new Author(name, null); + } +} diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Book.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Book.java new file mode 100644 index 0000000000..a4fb3fad4c --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Book.java @@ -0,0 +1,137 @@ +/** + * This class is generated by jOOQ + */ +package sample.jooq.domain.tables; + + +import java.util.Arrays; +import java.util.List; + +import javax.annotation.Generated; + +import org.jooq.Field; +import org.jooq.ForeignKey; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.UniqueKey; +import org.jooq.impl.TableImpl; + +import sample.jooq.domain.Keys; +import sample.jooq.domain.Public; +import sample.jooq.domain.tables.records.BookRecord; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "http://www.jooq.org", + "jOOQ version:3.6.2" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class Book extends TableImpl { + + private static final long serialVersionUID = 1858247563; + + /** + * The reference instance of PUBLIC.BOOK + */ + public static final Book BOOK = new Book(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return BookRecord.class; + } + + /** + * The column PUBLIC.BOOK.ID. + */ + public final TableField ID = createField("ID", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, ""); + + /** + * The column PUBLIC.BOOK.AUTHOR_ID. + */ + public final TableField AUTHOR_ID = createField("AUTHOR_ID", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, ""); + + /** + * The column PUBLIC.BOOK.TITLE. + */ + public final TableField TITLE = createField("TITLE", org.jooq.impl.SQLDataType.VARCHAR.length(400).nullable(false), this, ""); + + /** + * The column PUBLIC.BOOK.PUBLISHED_IN. + */ + public final TableField PUBLISHED_IN = createField("PUBLISHED_IN", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, ""); + + /** + * The column PUBLIC.BOOK.LANGUAGE_ID. + */ + public final TableField LANGUAGE_ID = createField("LANGUAGE_ID", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, ""); + + /** + * Create a PUBLIC.BOOK table reference + */ + public Book() { + this("BOOK", null); + } + + /** + * Create an aliased PUBLIC.BOOK table reference + */ + public Book(String alias) { + this(alias, BOOK); + } + + private Book(String alias, Table aliased) { + this(alias, aliased, null); + } + + private Book(String alias, Table aliased, Field[] parameters) { + super(alias, Public.PUBLIC, aliased, parameters, ""); + } + + /** + * {@inheritDoc} + */ + @Override + public UniqueKey getPrimaryKey() { + return Keys.CONSTRAINT_1; + } + + /** + * {@inheritDoc} + */ + @Override + public List> getKeys() { + return Arrays.>asList(Keys.CONSTRAINT_1); + } + + /** + * {@inheritDoc} + */ + @Override + public List> getReferences() { + return Arrays.>asList(Keys.FK_BOOK_AUTHOR, Keys.FK_BOOK_LANGUAGE); + } + + /** + * {@inheritDoc} + */ + @Override + public Book as(String alias) { + return new Book(alias, this); + } + + /** + * Rename this table + */ + public Book rename(String name) { + return new Book(name, null); + } +} diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/BookStore.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/BookStore.java new file mode 100644 index 0000000000..988cdbeba5 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/BookStore.java @@ -0,0 +1,100 @@ +/** + * This class is generated by jOOQ + */ +package sample.jooq.domain.tables; + + +import java.util.Arrays; +import java.util.List; + +import javax.annotation.Generated; + +import org.jooq.Field; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.UniqueKey; +import org.jooq.impl.TableImpl; + +import sample.jooq.domain.Keys; +import sample.jooq.domain.Public; +import sample.jooq.domain.tables.records.BookStoreRecord; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "http://www.jooq.org", + "jOOQ version:3.6.2" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class BookStore extends TableImpl { + + private static final long serialVersionUID = 1437758195; + + /** + * The reference instance of PUBLIC.BOOK_STORE + */ + public static final BookStore BOOK_STORE = new BookStore(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return BookStoreRecord.class; + } + + /** + * The column PUBLIC.BOOK_STORE.NAME. + */ + public final TableField NAME = createField("NAME", org.jooq.impl.SQLDataType.VARCHAR.length(400).nullable(false), this, ""); + + /** + * Create a PUBLIC.BOOK_STORE table reference + */ + public BookStore() { + this("BOOK_STORE", null); + } + + /** + * Create an aliased PUBLIC.BOOK_STORE table reference + */ + public BookStore(String alias) { + this(alias, BOOK_STORE); + } + + private BookStore(String alias, Table aliased) { + this(alias, aliased, null); + } + + private BookStore(String alias, Table aliased, Field[] parameters) { + super(alias, Public.PUBLIC, aliased, parameters, ""); + } + + /** + * {@inheritDoc} + */ + @Override + public List> getKeys() { + return Arrays.>asList(Keys.CONSTRAINT_F); + } + + /** + * {@inheritDoc} + */ + @Override + public BookStore as(String alias) { + return new BookStore(alias, this); + } + + /** + * Rename this table + */ + public BookStore rename(String name) { + return new BookStore(name, null); + } +} diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/BookToBookStore.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/BookToBookStore.java new file mode 100644 index 0000000000..71f2e2cac8 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/BookToBookStore.java @@ -0,0 +1,127 @@ +/** + * This class is generated by jOOQ + */ +package sample.jooq.domain.tables; + + +import java.util.Arrays; +import java.util.List; + +import javax.annotation.Generated; + +import org.jooq.Field; +import org.jooq.ForeignKey; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.UniqueKey; +import org.jooq.impl.TableImpl; + +import sample.jooq.domain.Keys; +import sample.jooq.domain.Public; +import sample.jooq.domain.tables.records.BookToBookStoreRecord; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "http://www.jooq.org", + "jOOQ version:3.6.2" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class BookToBookStore extends TableImpl { + + private static final long serialVersionUID = -557222072; + + /** + * The reference instance of PUBLIC.BOOK_TO_BOOK_STORE + */ + public static final BookToBookStore BOOK_TO_BOOK_STORE = new BookToBookStore(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return BookToBookStoreRecord.class; + } + + /** + * The column PUBLIC.BOOK_TO_BOOK_STORE.NAME. + */ + public final TableField NAME = createField("NAME", org.jooq.impl.SQLDataType.VARCHAR.length(400).nullable(false), this, ""); + + /** + * The column PUBLIC.BOOK_TO_BOOK_STORE.BOOK_ID. + */ + public final TableField BOOK_ID = createField("BOOK_ID", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, ""); + + /** + * The column PUBLIC.BOOK_TO_BOOK_STORE.STOCK. + */ + public final TableField STOCK = createField("STOCK", org.jooq.impl.SQLDataType.INTEGER, this, ""); + + /** + * Create a PUBLIC.BOOK_TO_BOOK_STORE table reference + */ + public BookToBookStore() { + this("BOOK_TO_BOOK_STORE", null); + } + + /** + * Create an aliased PUBLIC.BOOK_TO_BOOK_STORE table reference + */ + public BookToBookStore(String alias) { + this(alias, BOOK_TO_BOOK_STORE); + } + + private BookToBookStore(String alias, Table aliased) { + this(alias, aliased, null); + } + + private BookToBookStore(String alias, Table aliased, Field[] parameters) { + super(alias, Public.PUBLIC, aliased, parameters, ""); + } + + /** + * {@inheritDoc} + */ + @Override + public UniqueKey getPrimaryKey() { + return Keys.CONSTRAINT_2; + } + + /** + * {@inheritDoc} + */ + @Override + public List> getKeys() { + return Arrays.>asList(Keys.CONSTRAINT_2); + } + + /** + * {@inheritDoc} + */ + @Override + public List> getReferences() { + return Arrays.>asList(Keys.FK_B2BS_BOOK_STORE, Keys.FK_B2BS_BOOK); + } + + /** + * {@inheritDoc} + */ + @Override + public BookToBookStore as(String alias) { + return new BookToBookStore(alias, this); + } + + /** + * Rename this table + */ + public BookToBookStore rename(String name) { + return new BookToBookStore(name, null); + } +} diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Language.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Language.java new file mode 100644 index 0000000000..e34784d859 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/Language.java @@ -0,0 +1,118 @@ +/** + * This class is generated by jOOQ + */ +package sample.jooq.domain.tables; + + +import java.util.Arrays; +import java.util.List; + +import javax.annotation.Generated; + +import org.jooq.Field; +import org.jooq.Table; +import org.jooq.TableField; +import org.jooq.UniqueKey; +import org.jooq.impl.TableImpl; + +import sample.jooq.domain.Keys; +import sample.jooq.domain.Public; +import sample.jooq.domain.tables.records.LanguageRecord; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "http://www.jooq.org", + "jOOQ version:3.6.2" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class Language extends TableImpl { + + private static final long serialVersionUID = -192479483; + + /** + * The reference instance of PUBLIC.LANGUAGE + */ + public static final Language LANGUAGE = new Language(); + + /** + * The class holding records for this type + */ + @Override + public Class getRecordType() { + return LanguageRecord.class; + } + + /** + * The column PUBLIC.LANGUAGE.ID. + */ + public final TableField ID = createField("ID", org.jooq.impl.SQLDataType.INTEGER.nullable(false), this, ""); + + /** + * The column PUBLIC.LANGUAGE.CD. + */ + public final TableField CD = createField("CD", org.jooq.impl.SQLDataType.CHAR.length(2).nullable(false), this, ""); + + /** + * The column PUBLIC.LANGUAGE.DESCRIPTION. + */ + public final TableField DESCRIPTION = createField("DESCRIPTION", org.jooq.impl.SQLDataType.VARCHAR.length(50), this, ""); + + /** + * Create a PUBLIC.LANGUAGE table reference + */ + public Language() { + this("LANGUAGE", null); + } + + /** + * Create an aliased PUBLIC.LANGUAGE table reference + */ + public Language(String alias) { + this(alias, LANGUAGE); + } + + private Language(String alias, Table aliased) { + this(alias, aliased, null); + } + + private Language(String alias, Table aliased, Field[] parameters) { + super(alias, Public.PUBLIC, aliased, parameters, ""); + } + + /** + * {@inheritDoc} + */ + @Override + public UniqueKey getPrimaryKey() { + return Keys.CONSTRAINT_C; + } + + /** + * {@inheritDoc} + */ + @Override + public List> getKeys() { + return Arrays.>asList(Keys.CONSTRAINT_C); + } + + /** + * {@inheritDoc} + */ + @Override + public Language as(String alias) { + return new Language(alias, this); + } + + /** + * Rename this table + */ + public Language rename(String name) { + return new Language(name, null); + } +} diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/AuthorRecord.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/AuthorRecord.java new file mode 100644 index 0000000000..b6190a7286 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/AuthorRecord.java @@ -0,0 +1,339 @@ +/** + * This class is generated by jOOQ + */ +package sample.jooq.domain.tables.records; + + +import java.sql.Date; + +import javax.annotation.Generated; + +import org.jooq.Field; +import org.jooq.Record1; +import org.jooq.Record6; +import org.jooq.Row6; +import org.jooq.impl.UpdatableRecordImpl; + +import sample.jooq.domain.tables.Author; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "http://www.jooq.org", + "jOOQ version:3.6.2" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class AuthorRecord extends UpdatableRecordImpl implements Record6 { + + private static final long serialVersionUID = -983051550; + + /** + * Setter for PUBLIC.AUTHOR.ID. + */ + public void setId(Integer value) { + setValue(0, value); + } + + /** + * Getter for PUBLIC.AUTHOR.ID. + */ + public Integer getId() { + return (Integer) getValue(0); + } + + /** + * Setter for PUBLIC.AUTHOR.FIRST_NAME. + */ + public void setFirstName(String value) { + setValue(1, value); + } + + /** + * Getter for PUBLIC.AUTHOR.FIRST_NAME. + */ + public String getFirstName() { + return (String) getValue(1); + } + + /** + * Setter for PUBLIC.AUTHOR.LAST_NAME. + */ + public void setLastName(String value) { + setValue(2, value); + } + + /** + * Getter for PUBLIC.AUTHOR.LAST_NAME. + */ + public String getLastName() { + return (String) getValue(2); + } + + /** + * Setter for PUBLIC.AUTHOR.DATE_OF_BIRTH. + */ + public void setDateOfBirth(Date value) { + setValue(3, value); + } + + /** + * Getter for PUBLIC.AUTHOR.DATE_OF_BIRTH. + */ + public Date getDateOfBirth() { + return (Date) getValue(3); + } + + /** + * Setter for PUBLIC.AUTHOR.YEAR_OF_BIRTH. + */ + public void setYearOfBirth(Integer value) { + setValue(4, value); + } + + /** + * Getter for PUBLIC.AUTHOR.YEAR_OF_BIRTH. + */ + public Integer getYearOfBirth() { + return (Integer) getValue(4); + } + + /** + * Setter for PUBLIC.AUTHOR.DISTINGUISHED. + */ + public void setDistinguished(Byte value) { + setValue(5, value); + } + + /** + * Getter for PUBLIC.AUTHOR.DISTINGUISHED. + */ + public Byte getDistinguished() { + return (Byte) getValue(5); + } + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + /** + * {@inheritDoc} + */ + @Override + public Record1 key() { + return (Record1) super.key(); + } + + // ------------------------------------------------------------------------- + // Record6 type implementation + // ------------------------------------------------------------------------- + + /** + * {@inheritDoc} + */ + @Override + public Row6 fieldsRow() { + return (Row6) super.fieldsRow(); + } + + /** + * {@inheritDoc} + */ + @Override + public Row6 valuesRow() { + return (Row6) super.valuesRow(); + } + + /** + * {@inheritDoc} + */ + @Override + public Field field1() { + return Author.AUTHOR.ID; + } + + /** + * {@inheritDoc} + */ + @Override + public Field field2() { + return Author.AUTHOR.FIRST_NAME; + } + + /** + * {@inheritDoc} + */ + @Override + public Field field3() { + return Author.AUTHOR.LAST_NAME; + } + + /** + * {@inheritDoc} + */ + @Override + public Field field4() { + return Author.AUTHOR.DATE_OF_BIRTH; + } + + /** + * {@inheritDoc} + */ + @Override + public Field field5() { + return Author.AUTHOR.YEAR_OF_BIRTH; + } + + /** + * {@inheritDoc} + */ + @Override + public Field field6() { + return Author.AUTHOR.DISTINGUISHED; + } + + /** + * {@inheritDoc} + */ + @Override + public Integer value1() { + return getId(); + } + + /** + * {@inheritDoc} + */ + @Override + public String value2() { + return getFirstName(); + } + + /** + * {@inheritDoc} + */ + @Override + public String value3() { + return getLastName(); + } + + /** + * {@inheritDoc} + */ + @Override + public Date value4() { + return getDateOfBirth(); + } + + /** + * {@inheritDoc} + */ + @Override + public Integer value5() { + return getYearOfBirth(); + } + + /** + * {@inheritDoc} + */ + @Override + public Byte value6() { + return getDistinguished(); + } + + /** + * {@inheritDoc} + */ + @Override + public AuthorRecord value1(Integer value) { + setId(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public AuthorRecord value2(String value) { + setFirstName(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public AuthorRecord value3(String value) { + setLastName(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public AuthorRecord value4(Date value) { + setDateOfBirth(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public AuthorRecord value5(Integer value) { + setYearOfBirth(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public AuthorRecord value6(Byte value) { + setDistinguished(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public AuthorRecord values(Integer value1, String value2, String value3, Date value4, Integer value5, Byte value6) { + value1(value1); + value2(value2); + value3(value3); + value4(value4); + value5(value5); + value6(value6); + return this; + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached AuthorRecord + */ + public AuthorRecord() { + super(Author.AUTHOR); + } + + /** + * Create a detached, initialised AuthorRecord + */ + public AuthorRecord(Integer id, String firstName, String lastName, Date dateOfBirth, Integer yearOfBirth, Byte distinguished) { + super(Author.AUTHOR); + + setValue(0, id); + setValue(1, firstName); + setValue(2, lastName); + setValue(3, dateOfBirth); + setValue(4, yearOfBirth); + setValue(5, distinguished); + } +} diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookRecord.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookRecord.java new file mode 100644 index 0000000000..f55c6509df --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookRecord.java @@ -0,0 +1,296 @@ +/** + * This class is generated by jOOQ + */ +package sample.jooq.domain.tables.records; + + +import javax.annotation.Generated; + +import org.jooq.Field; +import org.jooq.Record1; +import org.jooq.Record5; +import org.jooq.Row5; +import org.jooq.impl.UpdatableRecordImpl; + +import sample.jooq.domain.tables.Book; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "http://www.jooq.org", + "jOOQ version:3.6.2" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class BookRecord extends UpdatableRecordImpl implements Record5 { + + private static final long serialVersionUID = 220424682; + + /** + * Setter for PUBLIC.BOOK.ID. + */ + public void setId(Integer value) { + setValue(0, value); + } + + /** + * Getter for PUBLIC.BOOK.ID. + */ + public Integer getId() { + return (Integer) getValue(0); + } + + /** + * Setter for PUBLIC.BOOK.AUTHOR_ID. + */ + public void setAuthorId(Integer value) { + setValue(1, value); + } + + /** + * Getter for PUBLIC.BOOK.AUTHOR_ID. + */ + public Integer getAuthorId() { + return (Integer) getValue(1); + } + + /** + * Setter for PUBLIC.BOOK.TITLE. + */ + public void setTitle(String value) { + setValue(2, value); + } + + /** + * Getter for PUBLIC.BOOK.TITLE. + */ + public String getTitle() { + return (String) getValue(2); + } + + /** + * Setter for PUBLIC.BOOK.PUBLISHED_IN. + */ + public void setPublishedIn(Integer value) { + setValue(3, value); + } + + /** + * Getter for PUBLIC.BOOK.PUBLISHED_IN. + */ + public Integer getPublishedIn() { + return (Integer) getValue(3); + } + + /** + * Setter for PUBLIC.BOOK.LANGUAGE_ID. + */ + public void setLanguageId(Integer value) { + setValue(4, value); + } + + /** + * Getter for PUBLIC.BOOK.LANGUAGE_ID. + */ + public Integer getLanguageId() { + return (Integer) getValue(4); + } + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + /** + * {@inheritDoc} + */ + @Override + public Record1 key() { + return (Record1) super.key(); + } + + // ------------------------------------------------------------------------- + // Record5 type implementation + // ------------------------------------------------------------------------- + + /** + * {@inheritDoc} + */ + @Override + public Row5 fieldsRow() { + return (Row5) super.fieldsRow(); + } + + /** + * {@inheritDoc} + */ + @Override + public Row5 valuesRow() { + return (Row5) super.valuesRow(); + } + + /** + * {@inheritDoc} + */ + @Override + public Field field1() { + return Book.BOOK.ID; + } + + /** + * {@inheritDoc} + */ + @Override + public Field field2() { + return Book.BOOK.AUTHOR_ID; + } + + /** + * {@inheritDoc} + */ + @Override + public Field field3() { + return Book.BOOK.TITLE; + } + + /** + * {@inheritDoc} + */ + @Override + public Field field4() { + return Book.BOOK.PUBLISHED_IN; + } + + /** + * {@inheritDoc} + */ + @Override + public Field field5() { + return Book.BOOK.LANGUAGE_ID; + } + + /** + * {@inheritDoc} + */ + @Override + public Integer value1() { + return getId(); + } + + /** + * {@inheritDoc} + */ + @Override + public Integer value2() { + return getAuthorId(); + } + + /** + * {@inheritDoc} + */ + @Override + public String value3() { + return getTitle(); + } + + /** + * {@inheritDoc} + */ + @Override + public Integer value4() { + return getPublishedIn(); + } + + /** + * {@inheritDoc} + */ + @Override + public Integer value5() { + return getLanguageId(); + } + + /** + * {@inheritDoc} + */ + @Override + public BookRecord value1(Integer value) { + setId(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public BookRecord value2(Integer value) { + setAuthorId(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public BookRecord value3(String value) { + setTitle(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public BookRecord value4(Integer value) { + setPublishedIn(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public BookRecord value5(Integer value) { + setLanguageId(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public BookRecord values(Integer value1, Integer value2, String value3, Integer value4, Integer value5) { + value1(value1); + value2(value2); + value3(value3); + value4(value4); + value5(value5); + return this; + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached BookRecord + */ + public BookRecord() { + super(Book.BOOK); + } + + /** + * Create a detached, initialised BookRecord + */ + public BookRecord(Integer id, Integer authorId, String title, Integer publishedIn, Integer languageId) { + super(Book.BOOK); + + setValue(0, id); + setValue(1, authorId); + setValue(2, title); + setValue(3, publishedIn); + setValue(4, languageId); + } +} diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookStoreRecord.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookStoreRecord.java new file mode 100644 index 0000000000..c119cc5527 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookStoreRecord.java @@ -0,0 +1,119 @@ +/** + * This class is generated by jOOQ + */ +package sample.jooq.domain.tables.records; + + +import javax.annotation.Generated; + +import org.jooq.Field; +import org.jooq.Record1; +import org.jooq.Row1; +import org.jooq.impl.TableRecordImpl; + +import sample.jooq.domain.tables.BookStore; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "http://www.jooq.org", + "jOOQ version:3.6.2" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class BookStoreRecord extends TableRecordImpl implements Record1 { + + private static final long serialVersionUID = -1969224219; + + /** + * Setter for PUBLIC.BOOK_STORE.NAME. + */ + public void setName(String value) { + setValue(0, value); + } + + /** + * Getter for PUBLIC.BOOK_STORE.NAME. + */ + public String getName() { + return (String) getValue(0); + } + + // ------------------------------------------------------------------------- + // Record1 type implementation + // ------------------------------------------------------------------------- + + /** + * {@inheritDoc} + */ + @Override + public Row1 fieldsRow() { + return (Row1) super.fieldsRow(); + } + + /** + * {@inheritDoc} + */ + @Override + public Row1 valuesRow() { + return (Row1) super.valuesRow(); + } + + /** + * {@inheritDoc} + */ + @Override + public Field field1() { + return BookStore.BOOK_STORE.NAME; + } + + /** + * {@inheritDoc} + */ + @Override + public String value1() { + return getName(); + } + + /** + * {@inheritDoc} + */ + @Override + public BookStoreRecord value1(String value) { + setName(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public BookStoreRecord values(String value1) { + value1(value1); + return this; + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached BookStoreRecord + */ + public BookStoreRecord() { + super(BookStore.BOOK_STORE); + } + + /** + * Create a detached, initialised BookStoreRecord + */ + public BookStoreRecord(String name) { + super(BookStore.BOOK_STORE); + + setValue(0, name); + } +} diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookToBookStoreRecord.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookToBookStoreRecord.java new file mode 100644 index 0000000000..2da6f1f9e8 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/BookToBookStoreRecord.java @@ -0,0 +1,214 @@ +/** + * This class is generated by jOOQ + */ +package sample.jooq.domain.tables.records; + + +import javax.annotation.Generated; + +import org.jooq.Field; +import org.jooq.Record2; +import org.jooq.Record3; +import org.jooq.Row3; +import org.jooq.impl.UpdatableRecordImpl; + +import sample.jooq.domain.tables.BookToBookStore; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "http://www.jooq.org", + "jOOQ version:3.6.2" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class BookToBookStoreRecord extends UpdatableRecordImpl implements Record3 { + + private static final long serialVersionUID = 1124329527; + + /** + * Setter for PUBLIC.BOOK_TO_BOOK_STORE.NAME. + */ + public void setName(String value) { + setValue(0, value); + } + + /** + * Getter for PUBLIC.BOOK_TO_BOOK_STORE.NAME. + */ + public String getName() { + return (String) getValue(0); + } + + /** + * Setter for PUBLIC.BOOK_TO_BOOK_STORE.BOOK_ID. + */ + public void setBookId(Integer value) { + setValue(1, value); + } + + /** + * Getter for PUBLIC.BOOK_TO_BOOK_STORE.BOOK_ID. + */ + public Integer getBookId() { + return (Integer) getValue(1); + } + + /** + * Setter for PUBLIC.BOOK_TO_BOOK_STORE.STOCK. + */ + public void setStock(Integer value) { + setValue(2, value); + } + + /** + * Getter for PUBLIC.BOOK_TO_BOOK_STORE.STOCK. + */ + public Integer getStock() { + return (Integer) getValue(2); + } + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + /** + * {@inheritDoc} + */ + @Override + public Record2 key() { + return (Record2) super.key(); + } + + // ------------------------------------------------------------------------- + // Record3 type implementation + // ------------------------------------------------------------------------- + + /** + * {@inheritDoc} + */ + @Override + public Row3 fieldsRow() { + return (Row3) super.fieldsRow(); + } + + /** + * {@inheritDoc} + */ + @Override + public Row3 valuesRow() { + return (Row3) super.valuesRow(); + } + + /** + * {@inheritDoc} + */ + @Override + public Field field1() { + return BookToBookStore.BOOK_TO_BOOK_STORE.NAME; + } + + /** + * {@inheritDoc} + */ + @Override + public Field field2() { + return BookToBookStore.BOOK_TO_BOOK_STORE.BOOK_ID; + } + + /** + * {@inheritDoc} + */ + @Override + public Field field3() { + return BookToBookStore.BOOK_TO_BOOK_STORE.STOCK; + } + + /** + * {@inheritDoc} + */ + @Override + public String value1() { + return getName(); + } + + /** + * {@inheritDoc} + */ + @Override + public Integer value2() { + return getBookId(); + } + + /** + * {@inheritDoc} + */ + @Override + public Integer value3() { + return getStock(); + } + + /** + * {@inheritDoc} + */ + @Override + public BookToBookStoreRecord value1(String value) { + setName(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public BookToBookStoreRecord value2(Integer value) { + setBookId(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public BookToBookStoreRecord value3(Integer value) { + setStock(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public BookToBookStoreRecord values(String value1, Integer value2, Integer value3) { + value1(value1); + value2(value2); + value3(value3); + return this; + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached BookToBookStoreRecord + */ + public BookToBookStoreRecord() { + super(BookToBookStore.BOOK_TO_BOOK_STORE); + } + + /** + * Create a detached, initialised BookToBookStoreRecord + */ + public BookToBookStoreRecord(String name, Integer bookId, Integer stock) { + super(BookToBookStore.BOOK_TO_BOOK_STORE); + + setValue(0, name); + setValue(1, bookId); + setValue(2, stock); + } +} diff --git a/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/LanguageRecord.java b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/LanguageRecord.java new file mode 100644 index 0000000000..bb23679ce7 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/gensrc/main/java/sample/jooq/domain/tables/records/LanguageRecord.java @@ -0,0 +1,214 @@ +/** + * This class is generated by jOOQ + */ +package sample.jooq.domain.tables.records; + + +import javax.annotation.Generated; + +import org.jooq.Field; +import org.jooq.Record1; +import org.jooq.Record3; +import org.jooq.Row3; +import org.jooq.impl.UpdatableRecordImpl; + +import sample.jooq.domain.tables.Language; + + +/** + * This class is generated by jOOQ. + */ +@Generated( + value = { + "http://www.jooq.org", + "jOOQ version:3.6.2" + }, + comments = "This class is generated by jOOQ" +) +@SuppressWarnings({ "all", "unchecked", "rawtypes" }) +public class LanguageRecord extends UpdatableRecordImpl implements Record3 { + + private static final long serialVersionUID = -1003202585; + + /** + * Setter for PUBLIC.LANGUAGE.ID. + */ + public void setId(Integer value) { + setValue(0, value); + } + + /** + * Getter for PUBLIC.LANGUAGE.ID. + */ + public Integer getId() { + return (Integer) getValue(0); + } + + /** + * Setter for PUBLIC.LANGUAGE.CD. + */ + public void setCd(String value) { + setValue(1, value); + } + + /** + * Getter for PUBLIC.LANGUAGE.CD. + */ + public String getCd() { + return (String) getValue(1); + } + + /** + * Setter for PUBLIC.LANGUAGE.DESCRIPTION. + */ + public void setDescription(String value) { + setValue(2, value); + } + + /** + * Getter for PUBLIC.LANGUAGE.DESCRIPTION. + */ + public String getDescription() { + return (String) getValue(2); + } + + // ------------------------------------------------------------------------- + // Primary key information + // ------------------------------------------------------------------------- + + /** + * {@inheritDoc} + */ + @Override + public Record1 key() { + return (Record1) super.key(); + } + + // ------------------------------------------------------------------------- + // Record3 type implementation + // ------------------------------------------------------------------------- + + /** + * {@inheritDoc} + */ + @Override + public Row3 fieldsRow() { + return (Row3) super.fieldsRow(); + } + + /** + * {@inheritDoc} + */ + @Override + public Row3 valuesRow() { + return (Row3) super.valuesRow(); + } + + /** + * {@inheritDoc} + */ + @Override + public Field field1() { + return Language.LANGUAGE.ID; + } + + /** + * {@inheritDoc} + */ + @Override + public Field field2() { + return Language.LANGUAGE.CD; + } + + /** + * {@inheritDoc} + */ + @Override + public Field field3() { + return Language.LANGUAGE.DESCRIPTION; + } + + /** + * {@inheritDoc} + */ + @Override + public Integer value1() { + return getId(); + } + + /** + * {@inheritDoc} + */ + @Override + public String value2() { + return getCd(); + } + + /** + * {@inheritDoc} + */ + @Override + public String value3() { + return getDescription(); + } + + /** + * {@inheritDoc} + */ + @Override + public LanguageRecord value1(Integer value) { + setId(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public LanguageRecord value2(String value) { + setCd(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public LanguageRecord value3(String value) { + setDescription(value); + return this; + } + + /** + * {@inheritDoc} + */ + @Override + public LanguageRecord values(Integer value1, String value2, String value3) { + value1(value1); + value2(value2); + value3(value3); + return this; + } + + // ------------------------------------------------------------------------- + // Constructors + // ------------------------------------------------------------------------- + + /** + * Create a detached LanguageRecord + */ + public LanguageRecord() { + super(Language.LANGUAGE); + } + + /** + * Create a detached, initialised LanguageRecord + */ + public LanguageRecord(Integer id, String cd, String description) { + super(Language.LANGUAGE); + + setValue(0, id); + setValue(1, cd); + setValue(2, description); + } +} diff --git a/spring-boot-samples/spring-boot-sample-jooq/pom.xml b/spring-boot-samples/spring-boot-sample-jooq/pom.xml new file mode 100644 index 0000000000..dfa84d7cb2 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/pom.xml @@ -0,0 +1,171 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-samples + 1.3.0.BUILD-SNAPSHOT + + spring-boot-sample-jooq + Spring Boot jOOQ Sample + Spring Boot jOOQ Sample + http://projects.spring.io/spring-boot/ + + Pivotal Software, Inc. + http://www.spring.io + + + ${basedir}/../.. + + + + org.springframework.boot + spring-boot-starter-jooq + + + com.h2database + h2 + runtime + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + generate-sources + + add-source + + + + gensrc/main/java + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + org.jooq + + jooq-codegen-maven + + + [3.6.2,) + + + generate + + + + + + + + + + + + + + + + generate + + + + org.codehaus.mojo + sql-maven-plugin + 1.5 + + + generate-sources + + execute + + + + + + com.h2database + h2 + ${h2.version} + + + + org.h2.Driver + jdbc:h2:~/springbootjooq + + ${basedir}/src/main/resources/reset.sql + ${basedir}/src/main/resources/schema.sql + + + + + org.jooq + jooq-codegen-maven + + + + generate + + + + + + com.h2database + h2 + ${h2.version} + + + + + org.h2.Driver + jdbc:h2:~/springbootjooq + + + org.jooq.util.DefaultGenerator + + org.jooq.util.h2.H2Database + .* + + PUBLIC + + + sample.jooq.domain + ${basedir}/gensrc/main/java + + + + + + + + + diff --git a/spring-boot-samples/spring-boot-sample-jooq/src/main/java/sample/jooq/JooqExamples.java b/spring-boot-samples/spring-boot-sample-jooq/src/main/java/sample/jooq/JooqExamples.java new file mode 100644 index 0000000000..46fdb74af6 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/src/main/java/sample/jooq/JooqExamples.java @@ -0,0 +1,80 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample.jooq; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +import org.jooq.DSLContext; +import org.jooq.Query; +import org.jooq.Record; +import org.jooq.Result; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.stereotype.Component; + +import static sample.jooq.domain.tables.Author.AUTHOR; +import static sample.jooq.domain.tables.Book.BOOK; + +@Component +public class JooqExamples implements CommandLineRunner { + + private final DSLContext dsl; + + private final JdbcTemplate jdbc; + + @Autowired + public JooqExamples(DSLContext dsl, JdbcTemplate jdbc) { + this.dsl = dsl; + this.jdbc = jdbc; + } + + @Override + public void run(String... args) throws Exception { + jooqFetch(); + jooqSql(); + } + + private void jooqFetch() { + Result results = this.dsl.select().from(AUTHOR).fetch(); + for (Record result : results) { + Integer id = result.getValue(AUTHOR.ID); + String firstName = result.getValue(AUTHOR.FIRST_NAME); + String lastName = result.getValue(AUTHOR.LAST_NAME); + System.out.println("jOOQ Fetch " + id + " " + firstName + " " + lastName); + } + } + + private void jooqSql() { + Query query = this.dsl.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME) + .from(BOOK).join(AUTHOR).on(BOOK.AUTHOR_ID.equal(AUTHOR.ID)) + .where(BOOK.PUBLISHED_IN.equal(2015)); + Object[] bind = query.getBindValues().toArray(new Object[] {}); + List list = this.jdbc.query(query.getSQL(), bind, + new RowMapper() { + @Override + public String mapRow(ResultSet rs, int rowNum) throws SQLException { + return rs.getString(1) + " : " + rs.getString(2) + " " + + rs.getString(3); + } + }); + System.out.println("jOOQ SQL " + list); + } +} diff --git a/spring-boot-samples/spring-boot-sample-jooq/src/main/java/sample/jooq/SampleJooqApplication.java b/spring-boot-samples/spring-boot-sample-jooq/src/main/java/sample/jooq/SampleJooqApplication.java new file mode 100644 index 0000000000..aa0dcac00e --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/src/main/java/sample/jooq/SampleJooqApplication.java @@ -0,0 +1,29 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample.jooq; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SampleJooqApplication { + + public static void main(String[] args) { + SpringApplication.run(SampleJooqApplication.class, args); + } + +} diff --git a/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/data.sql b/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/data.sql new file mode 100644 index 0000000000..8e8994e9d0 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/data.sql @@ -0,0 +1,12 @@ +INSERT INTO language VALUES (1, 'EN', 'English'); + +INSERT INTO author VALUES (1, 'Greg', 'Turnquest', '1804-09-17', 1804, 1); +INSERT INTO author VALUES (2, 'Craig', 'Walls', '1804-09-18', 1804, 1); + +INSERT INTO book VALUES (1, 1, 'Learning Spring Boot', 2015, 1); +INSERT INTO book VALUES (2, 2, 'Spring Boot in Action', 2015, 1); + +INSERT INTO book_store VALUES ('Barnes & Noble'); + +INSERT INTO book_to_book_store VALUES ('Barnes & Noble', 1, 10); +INSERT INTO book_to_book_store VALUES ('Barnes & Noble', 2, 3); diff --git a/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/reset.sql b/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/reset.sql new file mode 100644 index 0000000000..fc9a4f21da --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/reset.sql @@ -0,0 +1 @@ +DROP ALL OBJECTS; \ No newline at end of file diff --git a/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/schema.sql b/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/schema.sql new file mode 100644 index 0000000000..0cc7aee7e4 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/src/main/resources/schema.sql @@ -0,0 +1,39 @@ +CREATE TABLE language ( + id NUMBER(7) NOT NULL PRIMARY KEY, + cd CHAR(2) NOT NULL, + description VARCHAR2(50) +); + +CREATE TABLE author ( + id NUMBER(7) NOT NULL PRIMARY KEY, + first_name VARCHAR2(50), + last_name VARCHAR2(50) NOT NULL, + date_of_birth DATE, + year_of_birth NUMBER(7), + distinguished NUMBER(1) +); + +CREATE TABLE book ( + id NUMBER(7) NOT NULL PRIMARY KEY, + author_id NUMBER(7) NOT NULL, + title VARCHAR2(400) NOT NULL, + published_in NUMBER(7) NOT NULL, + language_id NUMBER(7) NOT NULL, + + CONSTRAINT fk_book_author FOREIGN KEY (author_id) REFERENCES author(id), + CONSTRAINT fk_book_language FOREIGN KEY (language_id) REFERENCES language(id) +); + +CREATE TABLE book_store ( + name VARCHAR2(400) NOT NULL UNIQUE +); + +CREATE TABLE book_to_book_store ( + name VARCHAR2(400) NOT NULL, + book_id INTEGER NOT NULL, + stock INTEGER, + + PRIMARY KEY(name, book_id), + CONSTRAINT fk_b2bs_book_store FOREIGN KEY (name) REFERENCES book_store (name) ON DELETE CASCADE, + CONSTRAINT fk_b2bs_book FOREIGN KEY (book_id) REFERENCES book (id) ON DELETE CASCADE +); diff --git a/spring-boot-samples/spring-boot-sample-jooq/src/test/java/sample/jooq/SampleJooqApplicationTests.java b/spring-boot-samples/spring-boot-sample-jooq/src/test/java/sample/jooq/SampleJooqApplicationTests.java new file mode 100644 index 0000000000..4b3bdaae13 --- /dev/null +++ b/spring-boot-samples/spring-boot-sample-jooq/src/test/java/sample/jooq/SampleJooqApplicationTests.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package sample.jooq; + +import org.junit.Rule; +import org.junit.Test; +import org.springframework.boot.test.OutputCapture; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertThat; + +/** + * Integration tests for {@link SampleJooqApplication}. + */ +public class SampleJooqApplicationTests { + + private static final String[] NO_ARGS = {}; + + @Rule + public OutputCapture out = new OutputCapture(); + + @Test + public void outputResults() throws Exception { + SampleJooqApplication.main(NO_ARGS); + assertThat(this.out.toString(), containsString("jOOQ Fetch 1 Greg Turnquest")); + assertThat(this.out.toString(), containsString("jOOQ Fetch 2 Craig Walls")); + assertThat(this.out.toString(), containsString("jOOQ SQL " + + "[Learning Spring Boot : Greg Turnquest, " + + "Spring Boot in Action : Craig Walls]")); + } + +} diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml index c683196be9..d43c5dc262 100644 --- a/spring-boot-starters/pom.xml +++ b/spring-boot-starters/pom.xml @@ -41,6 +41,7 @@ spring-boot-starter-jdbc spring-boot-starter-jersey spring-boot-starter-jetty + spring-boot-starter-jooq spring-boot-starter-jta-atomikos spring-boot-starter-jta-bitronix spring-boot-starter-logging diff --git a/spring-boot-starters/spring-boot-starter-jooq/pom.xml b/spring-boot-starters/spring-boot-starter-jooq/pom.xml new file mode 100644 index 0000000000..40cf8f370c --- /dev/null +++ b/spring-boot-starters/spring-boot-starter-jooq/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starters + 1.3.0.BUILD-SNAPSHOT + + spring-boot-starter-jooq + Spring Boot JOOQ Starter + Spring Boot JOOQ Starter + http://projects.spring.io/spring-boot/ + + Pivotal Software, Inc. + http://www.spring.io + + + ${basedir}/../.. + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-jdbc + + + org.springframework + spring-tx + + + org.jooq + jooq + + + diff --git a/spring-boot-starters/spring-boot-starter-jooq/src/main/resources/META-INF/spring.provides b/spring-boot-starters/spring-boot-starter-jooq/src/main/resources/META-INF/spring.provides new file mode 100644 index 0000000000..062b6d60d2 --- /dev/null +++ b/spring-boot-starters/spring-boot-starter-jooq/src/main/resources/META-INF/spring.provides @@ -0,0 +1 @@ +provides: jooq \ No newline at end of file