From 0e2521fa5ecf82871fbad1f6a6c555f6ba598435 Mon Sep 17 00:00:00 2001 From: Jeff Butler Date: Wed, 22 May 2019 14:59:53 -0400 Subject: [PATCH 1/8] Add support for schema/catalog suppliers --- .../org/mybatis/dynamic/sql/SqlTable.java | 56 +++++- .../schema_supplier/SchemaSupplier.java | 26 +++ .../schema_supplier/SchemaSupplierTest.java | 155 +++++++++++++++++ .../java/examples/schema_supplier/User.java | 37 ++++ .../UserDynamicSqlSupport.java | 36 ++++ .../examples/schema_supplier/UserMapper.java | 61 +++++++ .../org/mybatis/dynamic/sql/SqlTableTest.java | 161 ++++++++++++++++++ .../examples/schema_supplier/CreateDB.sql | 32 ++++ 8 files changed, 559 insertions(+), 5 deletions(-) create mode 100644 src/test/java/examples/schema_supplier/SchemaSupplier.java create mode 100644 src/test/java/examples/schema_supplier/SchemaSupplierTest.java create mode 100644 src/test/java/examples/schema_supplier/User.java create mode 100644 src/test/java/examples/schema_supplier/UserDynamicSqlSupport.java create mode 100644 src/test/java/examples/schema_supplier/UserMapper.java create mode 100644 src/test/java/org/mybatis/dynamic/sql/SqlTableTest.java create mode 100644 src/test/resources/examples/schema_supplier/CreateDB.sql diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlTable.java b/src/main/java/org/mybatis/dynamic/sql/SqlTable.java index ba55b2da8..1b4d81cfa 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlTable.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlTable.java @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 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. @@ -17,17 +17,63 @@ import java.sql.JDBCType; import java.util.Objects; +import java.util.Optional; +import java.util.function.Supplier; public class SqlTable { - - private String name; + + private Supplier nameSupplier; protected SqlTable(String name) { - this.name = Objects.requireNonNull(name); + Objects.requireNonNull(name); + + this.nameSupplier = () -> name; + } + + protected SqlTable(Supplier> schemaSupplier, String tableName) { + Objects.requireNonNull(schemaSupplier); + Objects.requireNonNull(tableName); + + this.nameSupplier = () -> compose(schemaSupplier, tableName); + } + + protected SqlTable(Supplier> catalogSupplier, Supplier> schemaSupplier, String tableName) { + Objects.requireNonNull(catalogSupplier); + Objects.requireNonNull(schemaSupplier); + Objects.requireNonNull(tableName); + + this.nameSupplier = () -> compose(catalogSupplier, schemaSupplier, tableName); + } + + private String compose(Supplier> catalogSupplier, Supplier> schemaSupplier, String tableName) { + return catalogSupplier.get().map(c -> compose(c, schemaSupplier, tableName)) + .orElse(compose(schemaSupplier, tableName)); + } + + private String compose(String catalog, Supplier> schemaSupplier, String tableName) { + return schemaSupplier.get().map(s -> composeCatalogSchemaAndAndTable(catalog, s, tableName)) + .orElse(composeCatalogAndTable(catalog, tableName)); + } + + private String compose(Supplier> schemaSupplier, String tableName) { + return schemaSupplier.get().map(s -> composeSchemaAndTable(s, tableName)) + .orElse(tableName); + } + + private String composeCatalogAndTable(String catalog, String tableName) { + return catalog + ".." + tableName; //$NON-NLS-1$ } + private String composeSchemaAndTable(String schema, String tableName) { + return schema + "." + tableName; //$NON-NLS-1$ + } + + private String composeCatalogSchemaAndAndTable(String catalog, String schema, String tableName) { + return catalog + "." + schema + "." + tableName; //$NON-NLS-1$ //$NON-NLS-2$ + } + public String name() { - return name; + return nameSupplier.get(); } public SqlColumn allColumns() { diff --git a/src/test/java/examples/schema_supplier/SchemaSupplier.java b/src/test/java/examples/schema_supplier/SchemaSupplier.java new file mode 100644 index 000000000..6c40e5707 --- /dev/null +++ b/src/test/java/examples/schema_supplier/SchemaSupplier.java @@ -0,0 +1,26 @@ +/** + * Copyright 2016-2019 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 examples.schema_supplier; + +import java.util.Optional; + +public class SchemaSupplier { + public static final String schema_property = "schemaToUse"; + + public static Optional schemaPropertyReader() { + return Optional.ofNullable(System.getProperty(schema_property)); + } +} diff --git a/src/test/java/examples/schema_supplier/SchemaSupplierTest.java b/src/test/java/examples/schema_supplier/SchemaSupplierTest.java new file mode 100644 index 000000000..99e82f58d --- /dev/null +++ b/src/test/java/examples/schema_supplier/SchemaSupplierTest.java @@ -0,0 +1,155 @@ +/** + * Copyright 2016-2019 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 examples.schema_supplier; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.sql.Connection; +import java.sql.DriverManager; +import java.util.List; + +import org.apache.ibatis.datasource.unpooled.UnpooledDataSource; +import org.apache.ibatis.exceptions.PersistenceException; +import org.apache.ibatis.jdbc.ScriptRunner; +import org.apache.ibatis.mapping.Environment; +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.apache.ibatis.session.SqlSessionFactoryBuilder; +import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class SchemaSupplierTest { + + private static final String JDBC_URL = "jdbc:hsqldb:mem:aname"; + private static final String JDBC_DRIVER = "org.hsqldb.jdbcDriver"; + + private SqlSessionFactory sqlSessionFactory; + + @BeforeEach + public void setup() throws Exception { + Class.forName(JDBC_DRIVER); + InputStream is = getClass().getResourceAsStream("/examples/schema_supplier/CreateDB.sql"); + try (Connection connection = DriverManager.getConnection(JDBC_URL, "sa", "")) { + ScriptRunner sr = new ScriptRunner(connection); + sr.setLogWriter(null); + sr.runScript(new InputStreamReader(is)); + } + + UnpooledDataSource ds = new UnpooledDataSource(JDBC_DRIVER, JDBC_URL, "sa", ""); + Environment environment = new Environment("test", new JdbcTransactionFactory(), ds); + Configuration config = new Configuration(environment); + config.addMapper(UserMapper.class); + sqlSessionFactory = new SqlSessionFactoryBuilder().build(config); + } + + @Test + public void testUnsetSchemaProperty() { + System.clearProperty(SchemaSupplier.schema_property); + + try (SqlSession session = sqlSessionFactory.openSession()) { + UserMapper mapper = session.getMapper(UserMapper.class); + + assertThrows(PersistenceException.class, () -> { + User user = new User(); + user.setId(1); + user.setName("Fred"); + + int rows = mapper.insert(user); + + assertThat(rows).isEqualTo(1); + }); + } + } + + @Test + public void testSchemaProperty() { + System.setProperty(SchemaSupplier.schema_property, "schema1"); + + try (SqlSession session = sqlSessionFactory.openSession()) { + UserMapper mapper = session.getMapper(UserMapper.class); + + insertFlintstones(mapper); + + List records = mapper.selectByExample() + .build() + .execute(); + assertThat(records.size()).isEqualTo(2); + } + } + + @Test + public void testSchemaSwitchingProperty() { + try (SqlSession session = sqlSessionFactory.openSession()) { + UserMapper mapper = session.getMapper(UserMapper.class); + + System.setProperty(SchemaSupplier.schema_property, "schema1"); + insertFlintstones(mapper); + + List records = mapper.selectByExample() + .build() + .execute(); + assertThat(records.size()).isEqualTo(2); + + + System.setProperty(SchemaSupplier.schema_property, "schema2"); + insertRubbles(mapper); + + records = mapper.selectByExample() + .build() + .execute(); + assertThat(records.size()).isEqualTo(3); + } + } + + private void insertFlintstones(UserMapper mapper) { + User user = new User(); + user.setId(1); + user.setName("Fred"); + int rows = mapper.insert(user); + assertThat(rows).isEqualTo(1); + + user = new User(); + user.setId(2); + user.setName("Wilma"); + rows = mapper.insert(user); + assertThat(rows).isEqualTo(1); + } + + private void insertRubbles(UserMapper mapper) { + User user = new User(); + user.setId(1); + user.setName("Barney"); + int rows = mapper.insert(user); + assertThat(rows).isEqualTo(1); + + user = new User(); + user.setId(2); + user.setName("Betty"); + rows = mapper.insert(user); + assertThat(rows).isEqualTo(1); + + user = new User(); + user.setId(3); + user.setName("Bamm Bamm"); + rows = mapper.insert(user); + assertThat(rows).isEqualTo(1); + } +} diff --git a/src/test/java/examples/schema_supplier/User.java b/src/test/java/examples/schema_supplier/User.java new file mode 100644 index 000000000..4585d7f19 --- /dev/null +++ b/src/test/java/examples/schema_supplier/User.java @@ -0,0 +1,37 @@ +/** + * Copyright 2016-2019 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 examples.schema_supplier; + +public class User { + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/src/test/java/examples/schema_supplier/UserDynamicSqlSupport.java b/src/test/java/examples/schema_supplier/UserDynamicSqlSupport.java new file mode 100644 index 000000000..9467b551f --- /dev/null +++ b/src/test/java/examples/schema_supplier/UserDynamicSqlSupport.java @@ -0,0 +1,36 @@ +/** + * Copyright 2016-2019 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 examples.schema_supplier; + +import java.sql.JDBCType; + +import org.mybatis.dynamic.sql.SqlColumn; +import org.mybatis.dynamic.sql.SqlTable; + +public class UserDynamicSqlSupport { + public static final User user = new User(); + public static final SqlColumn id = user.id; + public static final SqlColumn name = user.name; + + public static final class User extends SqlTable { + public final SqlColumn id = column("user_id", JDBCType.INTEGER); + public final SqlColumn name = column("user_name", JDBCType.VARCHAR); + + public User() { + super(SchemaSupplier::schemaPropertyReader, "User"); + } + } +} diff --git a/src/test/java/examples/schema_supplier/UserMapper.java b/src/test/java/examples/schema_supplier/UserMapper.java new file mode 100644 index 000000000..700d31f15 --- /dev/null +++ b/src/test/java/examples/schema_supplier/UserMapper.java @@ -0,0 +1,61 @@ +/** + * Copyright 2016-2019 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 examples.schema_supplier; + +import static examples.schema_supplier.UserDynamicSqlSupport.*; + +import java.util.List; + +import org.apache.ibatis.annotations.InsertProvider; +import org.apache.ibatis.annotations.Result; +import org.apache.ibatis.annotations.Results; +import org.apache.ibatis.annotations.SelectProvider; +import org.apache.ibatis.type.JdbcType; +import org.mybatis.dynamic.sql.SqlBuilder; +import org.mybatis.dynamic.sql.insert.render.InsertStatementProvider; +import org.mybatis.dynamic.sql.render.RenderingStrategy; +import org.mybatis.dynamic.sql.select.MyBatis3SelectModelAdapter; +import org.mybatis.dynamic.sql.select.QueryExpressionDSL; +import org.mybatis.dynamic.sql.select.SelectDSL; +import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; +import org.mybatis.dynamic.sql.util.SqlProviderAdapter; + +public interface UserMapper { + + @InsertProvider(type=SqlProviderAdapter.class, method="insert") + int insert(InsertStatementProvider insertStatement); + + @SelectProvider(type=SqlProviderAdapter.class, method="select") + @Results(id="UserResult", value= { + @Result(column="USER_ID", property="id", jdbcType=JdbcType.INTEGER, id=true), + @Result(column="USER_NAME", property="name", jdbcType=JdbcType.VARCHAR) + }) + List selectMany(SelectStatementProvider selectStatement); + + default QueryExpressionDSL>> selectByExample() { + return SelectDSL.selectWithMapper(this::selectMany, id, name) + .from(user); + } + + default int insert(User record) { + return insert(SqlBuilder.insert(record) + .into(user) + .map(id).toProperty("id") + .map(name).toProperty("name") + .build() + .render(RenderingStrategy.MYBATIS3)); + } +} diff --git a/src/test/java/org/mybatis/dynamic/sql/SqlTableTest.java b/src/test/java/org/mybatis/dynamic/sql/SqlTableTest.java new file mode 100644 index 000000000..a1a28e585 --- /dev/null +++ b/src/test/java/org/mybatis/dynamic/sql/SqlTableTest.java @@ -0,0 +1,161 @@ +/** + * Copyright 2016-2019 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.mybatis.dynamic.sql; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Optional; +import java.util.function.Supplier; + +import org.junit.jupiter.api.Test; + +public class SqlTableTest { + + @Test + public void testSchemaSupplierEmpty() { + SqlTable table = new SqlTable(Optional::empty, "my_table"); + assertThat(table.name()).isEqualTo("my_table"); + } + + @Test + public void testSchemaSupplierWithValue() { + SqlTable table = new SqlTable(() -> Optional.of("my_schema"), "my_table"); + assertThat(table.name()).isEqualTo("my_schema.my_table"); + } + + @Test + public void testSingletonSchemaSupplier() { + SqlTable table = new SqlTable(MySchemaSupplier.instance(), "my_table"); + assertThat(table.name()).isEqualTo("first_schema.my_table"); + } + + @Test + public void testThatSchemaSupplierDoesDelay() { + MySchemaSupplier schemaSupplier = new MySchemaSupplier(); + SqlTable table = new SqlTable(schemaSupplier, "my_table"); + assertThat(table.name()).isEqualTo("first_schema.my_table"); + + schemaSupplier.setFirst(false); + assertThat(table.name()).isEqualTo("second_schema.my_table"); + } + + @Test + public void testCatalogAndSchemaSupplierEmpty() { + SqlTable table = new SqlTable(Optional::empty, Optional::empty, "my_table"); + assertThat(table.name()).isEqualTo("my_table"); + } + + @Test + public void testCatalogSupplierWithValue() { + SqlTable table = new SqlTable(() -> Optional.of("my_catalog"), Optional::empty, "my_table"); + assertThat(table.name()).isEqualTo("my_catalog..my_table"); + } + + @Test + public void testThatCatalogSupplierDoesDelay() { + MyCatalogSupplier catalogSupplier = new MyCatalogSupplier(); + SqlTable table = new SqlTable(catalogSupplier, Optional::empty, "my_table"); + assertThat(table.name()).isEqualTo("first_catalog..my_table"); + + catalogSupplier.setFirst(false); + assertThat(table.name()).isEqualTo("second_catalog..my_table"); + } + + @Test + public void testThatCatalogSupplierAndSchemaSupplierBothDelay() { + MyCatalogSupplier catalogSupplier = new MyCatalogSupplier(); + MySchemaSupplier schemaSupplier = new MySchemaSupplier(); + SqlTable table = new SqlTable(catalogSupplier, schemaSupplier, "my_table"); + assertThat(table.name()).isEqualTo("first_catalog.first_schema.my_table"); + + catalogSupplier.setFirst(false); + assertThat(table.name()).isEqualTo("second_catalog.first_schema.my_table"); + + catalogSupplier.setFirst(true); + schemaSupplier.setFirst(false); + assertThat(table.name()).isEqualTo("first_catalog.second_schema.my_table"); + + catalogSupplier.setFirst(false); + assertThat(table.name()).isEqualTo("second_catalog.second_schema.my_table"); + + catalogSupplier.setEmpty(true); + assertThat(table.name()).isEqualTo("second_schema.my_table"); + + schemaSupplier.setEmpty(true); + assertThat(table.name()).isEqualTo("my_table"); + + catalogSupplier.setEmpty(false); + assertThat(table.name()).isEqualTo("second_catalog..my_table"); + } + + public static class MySchemaSupplier implements Supplier> { + private static MySchemaSupplier instance = new MySchemaSupplier(); + + public static MySchemaSupplier instance() { + return instance; + } + + private boolean first = true; + private boolean empty; + + public void setFirst(boolean first) { + this.first = first; + } + + public void setEmpty(boolean empty) { + this.empty = empty; + } + + @Override + public Optional get() { + if (empty) { + return Optional.empty(); + } + + if (first) { + return Optional.of("first_schema"); + } else { + return Optional.of("second_schema"); + } + } + } + + public static class MyCatalogSupplier implements Supplier> { + private boolean first = true; + private boolean empty; + + public void setFirst(boolean first) { + this.first = first; + } + + public void setEmpty(boolean empty) { + this.empty = empty; + } + + @Override + public Optional get() { + if (empty) { + return Optional.empty(); + } + + if (first) { + return Optional.of("first_catalog"); + } else { + return Optional.of("second_catalog"); + } + } + } +} diff --git a/src/test/resources/examples/schema_supplier/CreateDB.sql b/src/test/resources/examples/schema_supplier/CreateDB.sql new file mode 100644 index 000000000..59fe21efd --- /dev/null +++ b/src/test/resources/examples/schema_supplier/CreateDB.sql @@ -0,0 +1,32 @@ +-- +-- Copyright 2016-2019 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. +-- + +drop schema schema1 if exists cascade; +drop schema schema2 if exists cascade; + +create schema schema1 + create table User ( + user_id int not null, + user_name varchar(30) not null, + primary key (user_id) + ); + +create schema schema2 + create table User ( + user_id int not null, + user_name varchar(30) not null, + primary key (user_id) + ); From c9bd50e0389127c5ab3628d492b2ee7e1513543a Mon Sep 17 00:00:00 2001 From: Jeff Butler Date: Wed, 22 May 2019 21:06:33 -0400 Subject: [PATCH 2/8] Update dependencies --- pom.xml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index ab6939a15..bc3cbf3c2 100644 --- a/pom.xml +++ b/pom.xml @@ -40,8 +40,8 @@ 1.8 ${java.version} ${java.version} - 5.4.1 - 1.4.1 + 5.4.2 + 1.4.2 4.1.2.RELEASE 1.1.0 org.mybatis.dynamic.sql @@ -144,7 +144,7 @@ org.springframework spring-jdbc - 5.1.6.RELEASE + 5.1.7.RELEASE test @@ -171,6 +171,13 @@ 1.2.3 test + + + org.hamcrest + hamcrest + 2.1 + test + From 33b63535128b93b1bf17ed541d37534c509f129e Mon Sep 17 00:00:00 2001 From: Jeff Butler Date: Wed, 22 May 2019 21:06:43 -0400 Subject: [PATCH 3/8] Update change log --- CHANGELOG.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0662eb2f6..b1f158cbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,16 @@ This log will detail notable changes to MyBatis Dynamic SQL. Full details are available on the GitHub milestone pages. -## Release 1.1.1 +## Release 1.1.2 - Unreleased + +GitHub milestone: [https://github.com/mybatis/mybatis-dynamic-sql/issues?q=milestone%3A1.1.2+](https://github.com/mybatis/mybatis-dynamic-sql/issues?q=milestone%3A1.1.2+) + +### Added + +- Changed the public SQLBuilder API to accept Collection instead of List for in conditions and batch record inserts. This should have no impact on existing code, but allow for some future flexibility + + +## Release 1.1.1 - April 7, 2019 GitHub milestone: [https://github.com/mybatis/mybatis-dynamic-sql/issues?q=milestone%3A1.1.1+](https://github.com/mybatis/mybatis-dynamic-sql/issues?q=milestone%3A1.1.1+) @@ -19,7 +28,7 @@ GitHub milestone: [https://github.com/mybatis/mybatis-dynamic-sql/issues?q=miles - Fixed self joins -## Release 1.1.0 +## Release 1.1.0 - April 24, 2018 GitHub milestone: [https://github.com/mybatis/mybatis-dynamic-sql/issues?q=milestone%3A1.1.0+](https://github.com/mybatis/mybatis-dynamic-sql/issues?q=milestone%3A1.1.0+) From 8d701fe302b984077a93a699b7cd64d0e84a6af9 Mon Sep 17 00:00:00 2001 From: Jeff Butler Date: Wed, 22 May 2019 21:06:52 -0400 Subject: [PATCH 4/8] Better method names --- .../springbatch/cursor/CursorReaderBatchConfiguration.java | 2 +- .../springbatch/paging/PagingReaderBatchConfiguration.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test/java/examples/springbatch/cursor/CursorReaderBatchConfiguration.java b/src/test/java/examples/springbatch/cursor/CursorReaderBatchConfiguration.java index 9a1796139..626bdf517 100644 --- a/src/test/java/examples/springbatch/cursor/CursorReaderBatchConfiguration.java +++ b/src/test/java/examples/springbatch/cursor/CursorReaderBatchConfiguration.java @@ -82,7 +82,7 @@ public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Excepti } @Bean - public PlatformTransactionManager dtm(DataSource dataSource) { + public PlatformTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } diff --git a/src/test/java/examples/springbatch/paging/PagingReaderBatchConfiguration.java b/src/test/java/examples/springbatch/paging/PagingReaderBatchConfiguration.java index 42acb7743..9bdafdb7e 100644 --- a/src/test/java/examples/springbatch/paging/PagingReaderBatchConfiguration.java +++ b/src/test/java/examples/springbatch/paging/PagingReaderBatchConfiguration.java @@ -45,6 +45,7 @@ import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; +import org.springframework.transaction.PlatformTransactionManager; import examples.springbatch.common.Person; import examples.springbatch.mapper.PersonMapper; @@ -80,7 +81,7 @@ public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Excepti } @Bean - public DataSourceTransactionManager dtm(DataSource dataSource) { + public PlatformTransactionManager transactionManager(DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } From e43a4b20472a63f1255dd1a24617215e6ee0ebb3 Mon Sep 17 00:00:00 2001 From: Jeff Butler Date: Thu, 23 May 2019 15:47:24 -0400 Subject: [PATCH 5/8] Documentation for new SqlTable constructors --- CHANGELOG.md | 1 + src/site/markdown/docs/databaseObjects.md | 102 ++++++++++++++++++++++ src/site/site.xml | 1 + 3 files changed, 104 insertions(+) create mode 100644 src/site/markdown/docs/databaseObjects.md diff --git a/CHANGELOG.md b/CHANGELOG.md index b1f158cbe..49ae77c14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ GitHub milestone: [https://github.com/mybatis/mybatis-dynamic-sql/issues?q=miles ### Added - Changed the public SQLBuilder API to accept Collection instead of List for in conditions and batch record inserts. This should have no impact on existing code, but allow for some future flexibility +- Added the ability have have table catalog and/or schema calculated at query runtime. This is useful for situations where there are different database schemas for different environments, or in some sharding situations ## Release 1.1.1 - April 7, 2019 diff --git a/src/site/markdown/docs/databaseObjects.md b/src/site/markdown/docs/databaseObjects.md new file mode 100644 index 000000000..851a0459a --- /dev/null +++ b/src/site/markdown/docs/databaseObjects.md @@ -0,0 +1,102 @@ +# Database Object Representation +MyBatis Dynamic SQL works with Java objects that represent relational tables or views. + +## Table or View Representation + +The class `SqlTable` is used to represent a table or view in a database. An `SqlTable` holds a name, and a collection of `SqlColumn` objects that represent the columns in a table or view. + +A fully qualified name has three parts: + +1. The catalog - which is rarely used outside of Microsoft SQL Server +1. The schema - which is often specified, but may be left blank if you are operating on tables in the default schema +1. The name - which is required + +Typical examples of fully qualified names are as follows: + +- `"dbo..bar"` - a fully qualified name with a catalog (dbo) and a name (bar). This is typical for SQL Server +- `"foo.bar"` - a fully qualified name with a schema (foo) and a name (bar). This is typical in many databases when you want to access tables that are not in the default schema +- `"bar"` - a fully qualified name with just a name (bar). This will access a table or view in the default catalog and schema for a connection + + +In MyBatis Dynamic SQL, the fully qualified name can be specified in different ways: + +1. The fully qualified table name can be a constant String +1. The fully qualified table name can be calculated at runtime based on a dynamic catalog and/or schema and a constant table name + +### Constant Names + +Constant names are used when you use the `SqlTable` constructor with a single String argument. For example: + +```java +public class MyTable extends SqlTable { + public MyTable() { + super("MyTable"); + } +} +``` + +Or + +```java +public class MyTable extends SqlTable { + public MyTable() { + super("MySchema.MyTable"); + } +} +``` + + +### Dynamic Names +MyBatis Dynamic SQL allows you to dynamically specify a catalog and/or schema. This is useful for applications where the schema may change for different users or environments, or if you are using different schemas to shard the database. Dynamic names are used when you use a `SqlTable` constructor that accepts one or more `java.util.function.Supplier` arguments. + +For example, suppose you wanted to change the schema based on the value of a system property. You could write a class like this: + +```java +public class SchemaSupplier { + public static final String schema_property = "schemaToUse"; + + public static Optional schemaPropertyReader() { + return Optional.ofNullable(System.getProperty(schema_property)); + } +} +``` + +This class has a static method `schemaPropertyReader` that will return an `Optional` containing the value of a system property. You could then reference this method in the constructor of the `SqlTable` like this: + +```java +public static final class User extends SqlTable { + public User() { + super(SchemaSupplier::schemaPropertyReader, "User"); + } +} +``` + +Whenever the table is referenced for rendering SQL, the name will be calculated based on the current value of the system property. + +There are two constructors that can be used for dynamic names: + +1. A constructor that accepts `Supplier>` for the schema, and `String` for the name. This constructor assumes that the catalog is always empty or not used +1. A constructor that accepts `Supplier>` for the catalog, `Supplier>` for the schema, and `String` for the name + +If you are using Microsoft SQL Server and want to use a dynamic catalog name and ignore the schema, then you should use the second constructor like this: + +```java +public static final class User extends SqlTable { + public User() { + super(CatalogSupplier::catalogPropertyReader, Optional::empty, "User"); + } +} +``` + +The following table shows how the name is calculated in all combinations of suppliers: + +Catalog Supplier Value | Schema Supplier Value | Name | Fully Qualified Name +---|---|---|--- +"MyCatalog" | "MySchema" | "MyTable" | "MyCatalog.MySchema.MyTable" +<empty> | "MySchema" | "MyTable" | "MySchema.MyTable" +"MyCatalog" | <empty> | "MyTable" | "MyCatalog..MyTable" +<empty> | <empty> | "MyTable" | "MyTable" + + + +## Column Representation diff --git a/src/site/site.xml b/src/site/site.xml index d2bebddef..fe302fde9 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -37,6 +37,7 @@ + From ad7254ebbc6728c1dccbfdafc58769848f8624ab Mon Sep 17 00:00:00 2001 From: Jeff Butler Date: Thu, 23 May 2019 15:47:54 -0400 Subject: [PATCH 6/8] Change SqlTable name attribute to better match the documentation --- .../org/mybatis/dynamic/sql/SqlTable.java | 13 +++----- .../sql/delete/render/DeleteRenderer.java | 2 +- .../insert/render/BatchInsertRenderer.java | 2 +- .../sql/insert/render/InsertRenderer.java | 2 +- .../insert/render/InsertSelectRenderer.java | 2 +- .../GuaranteedTableAliasCalculator.java | 2 +- .../sql/select/QueryExpressionModel.java | 2 +- .../sql/update/render/UpdateRenderer.java | 2 +- .../org/mybatis/dynamic/sql/SqlTableTest.java | 32 +++++++++---------- 9 files changed, 28 insertions(+), 31 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlTable.java b/src/main/java/org/mybatis/dynamic/sql/SqlTable.java index 1b4d81cfa..781679821 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlTable.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlTable.java @@ -24,17 +24,14 @@ public class SqlTable { private Supplier nameSupplier; - protected SqlTable(String name) { - Objects.requireNonNull(name); + protected SqlTable(String fullyQualifiedTableName) { + Objects.requireNonNull(fullyQualifiedTableName); - this.nameSupplier = () -> name; + this.nameSupplier = () -> fullyQualifiedTableName; } protected SqlTable(Supplier> schemaSupplier, String tableName) { - Objects.requireNonNull(schemaSupplier); - Objects.requireNonNull(tableName); - - this.nameSupplier = () -> compose(schemaSupplier, tableName); + this(Optional::empty, schemaSupplier, tableName); } protected SqlTable(Supplier> catalogSupplier, Supplier> schemaSupplier, String tableName) { @@ -72,7 +69,7 @@ private String composeCatalogSchemaAndAndTable(String catalog, String schema, St return catalog + "." + schema + "." + tableName; //$NON-NLS-1$ //$NON-NLS-2$ } - public String name() { + public String fullyQualifiedTableName() { return nameSupplier.get(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/delete/render/DeleteRenderer.java b/src/main/java/org/mybatis/dynamic/sql/delete/render/DeleteRenderer.java index 2987e186e..c10ba2799 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/render/DeleteRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/render/DeleteRenderer.java @@ -58,7 +58,7 @@ private Optional renderWhereClause(WhereModel whereModel) { private String calculateDeleteStatement(Optional whereClause) { return "delete from" //$NON-NLS-1$ - + spaceBefore(deleteModel.table().name()) + + spaceBefore(deleteModel.table().fullyQualifiedTableName()) + spaceBefore(whereClause.map(WhereClauseProvider::getWhereClause)); } diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsertRenderer.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsertRenderer.java index de904779e..1727cc1fd 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsertRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsertRenderer.java @@ -54,7 +54,7 @@ private FieldAndValue toFieldAndValue(ValuePhraseVisitor visitor, InsertMapping private String calculateInsertStatement(FieldAndValueCollector collector) { return "insert into" //$NON-NLS-1$ - + spaceBefore(model.table().name()) + + spaceBefore(model.table().fullyQualifiedTableName()) + spaceBefore(collector.columnsPhrase()) + spaceBefore(collector.valuesPhrase()); } diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertRenderer.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertRenderer.java index d9f26bd56..bf59f17d7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertRenderer.java @@ -46,7 +46,7 @@ public InsertStatementProvider render() { private String calculateInsertStatement(FieldAndValueCollector collector) { return "insert into" //$NON-NLS-1$ - + spaceBefore(model.table().name()) + + spaceBefore(model.table().fullyQualifiedTableName()) + spaceBefore(collector.columnsPhrase()) + spaceBefore(collector.valuesPhrase()); } diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertSelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertSelectRenderer.java index 5e109c8c0..ac61e9f75 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertSelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertSelectRenderer.java @@ -47,7 +47,7 @@ public InsertSelectStatementProvider render() { private String calculateInsertStatement(SelectStatementProvider selectStatement) { return "insert into" //$NON-NLS-1$ - + spaceBefore(model.table().name()) + + spaceBefore(model.table().fullyQualifiedTableName()) + spaceBefore(calculateColumnsPhrase()) + spaceBefore(selectStatement.getSelectStatement()); } diff --git a/src/main/java/org/mybatis/dynamic/sql/render/GuaranteedTableAliasCalculator.java b/src/main/java/org/mybatis/dynamic/sql/render/GuaranteedTableAliasCalculator.java index 0692f22b1..0817de7c4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/GuaranteedTableAliasCalculator.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/GuaranteedTableAliasCalculator.java @@ -37,7 +37,7 @@ private GuaranteedTableAliasCalculator(Map aliases) { public Optional aliasForColumn(SqlTable table) { return super.aliasForColumn(table) .map(Optional::of) - .orElse(Optional.of(table.name())); + .orElse(Optional.of(table.fullyQualifiedTableName())); } public static TableAliasCalculator of(Map aliases) { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionModel.java b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionModel.java index 188a9c93b..0ebeb4551 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionModel.java @@ -88,7 +88,7 @@ public Optional groupByModel() { } public String calculateTableNameIncludingAlias(SqlTable table) { - return table.name() + return table.fullyQualifiedTableName() + spaceBefore(tableAliasCalculator.aliasForTable(table)); } diff --git a/src/main/java/org/mybatis/dynamic/sql/update/render/UpdateRenderer.java b/src/main/java/org/mybatis/dynamic/sql/update/render/UpdateRenderer.java index 88374165b..ca9599e17 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/render/UpdateRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/render/UpdateRenderer.java @@ -65,7 +65,7 @@ private FragmentCollector calculateColumnMappings() { private String calculateUpdateStatement(FragmentCollector fc, Optional whereClause) { return "update" //$NON-NLS-1$ - + spaceBefore(updateModel.table().name()) + + spaceBefore(updateModel.table().fullyQualifiedTableName()) + spaceBefore(calculateSetPhrase(fc)) + spaceBefore(whereClause.map(WhereClauseProvider::getWhereClause)); } diff --git a/src/test/java/org/mybatis/dynamic/sql/SqlTableTest.java b/src/test/java/org/mybatis/dynamic/sql/SqlTableTest.java index a1a28e585..a88a19eeb 100644 --- a/src/test/java/org/mybatis/dynamic/sql/SqlTableTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/SqlTableTest.java @@ -27,51 +27,51 @@ public class SqlTableTest { @Test public void testSchemaSupplierEmpty() { SqlTable table = new SqlTable(Optional::empty, "my_table"); - assertThat(table.name()).isEqualTo("my_table"); + assertThat(table.fullyQualifiedTableName()).isEqualTo("my_table"); } @Test public void testSchemaSupplierWithValue() { SqlTable table = new SqlTable(() -> Optional.of("my_schema"), "my_table"); - assertThat(table.name()).isEqualTo("my_schema.my_table"); + assertThat(table.fullyQualifiedTableName()).isEqualTo("my_schema.my_table"); } @Test public void testSingletonSchemaSupplier() { SqlTable table = new SqlTable(MySchemaSupplier.instance(), "my_table"); - assertThat(table.name()).isEqualTo("first_schema.my_table"); + assertThat(table.fullyQualifiedTableName()).isEqualTo("first_schema.my_table"); } @Test public void testThatSchemaSupplierDoesDelay() { MySchemaSupplier schemaSupplier = new MySchemaSupplier(); SqlTable table = new SqlTable(schemaSupplier, "my_table"); - assertThat(table.name()).isEqualTo("first_schema.my_table"); + assertThat(table.fullyQualifiedTableName()).isEqualTo("first_schema.my_table"); schemaSupplier.setFirst(false); - assertThat(table.name()).isEqualTo("second_schema.my_table"); + assertThat(table.fullyQualifiedTableName()).isEqualTo("second_schema.my_table"); } @Test public void testCatalogAndSchemaSupplierEmpty() { SqlTable table = new SqlTable(Optional::empty, Optional::empty, "my_table"); - assertThat(table.name()).isEqualTo("my_table"); + assertThat(table.fullyQualifiedTableName()).isEqualTo("my_table"); } @Test public void testCatalogSupplierWithValue() { SqlTable table = new SqlTable(() -> Optional.of("my_catalog"), Optional::empty, "my_table"); - assertThat(table.name()).isEqualTo("my_catalog..my_table"); + assertThat(table.fullyQualifiedTableName()).isEqualTo("my_catalog..my_table"); } @Test public void testThatCatalogSupplierDoesDelay() { MyCatalogSupplier catalogSupplier = new MyCatalogSupplier(); SqlTable table = new SqlTable(catalogSupplier, Optional::empty, "my_table"); - assertThat(table.name()).isEqualTo("first_catalog..my_table"); + assertThat(table.fullyQualifiedTableName()).isEqualTo("first_catalog..my_table"); catalogSupplier.setFirst(false); - assertThat(table.name()).isEqualTo("second_catalog..my_table"); + assertThat(table.fullyQualifiedTableName()).isEqualTo("second_catalog..my_table"); } @Test @@ -79,26 +79,26 @@ public void testThatCatalogSupplierAndSchemaSupplierBothDelay() { MyCatalogSupplier catalogSupplier = new MyCatalogSupplier(); MySchemaSupplier schemaSupplier = new MySchemaSupplier(); SqlTable table = new SqlTable(catalogSupplier, schemaSupplier, "my_table"); - assertThat(table.name()).isEqualTo("first_catalog.first_schema.my_table"); + assertThat(table.fullyQualifiedTableName()).isEqualTo("first_catalog.first_schema.my_table"); catalogSupplier.setFirst(false); - assertThat(table.name()).isEqualTo("second_catalog.first_schema.my_table"); + assertThat(table.fullyQualifiedTableName()).isEqualTo("second_catalog.first_schema.my_table"); catalogSupplier.setFirst(true); schemaSupplier.setFirst(false); - assertThat(table.name()).isEqualTo("first_catalog.second_schema.my_table"); + assertThat(table.fullyQualifiedTableName()).isEqualTo("first_catalog.second_schema.my_table"); catalogSupplier.setFirst(false); - assertThat(table.name()).isEqualTo("second_catalog.second_schema.my_table"); + assertThat(table.fullyQualifiedTableName()).isEqualTo("second_catalog.second_schema.my_table"); catalogSupplier.setEmpty(true); - assertThat(table.name()).isEqualTo("second_schema.my_table"); + assertThat(table.fullyQualifiedTableName()).isEqualTo("second_schema.my_table"); schemaSupplier.setEmpty(true); - assertThat(table.name()).isEqualTo("my_table"); + assertThat(table.fullyQualifiedTableName()).isEqualTo("my_table"); catalogSupplier.setEmpty(false); - assertThat(table.name()).isEqualTo("second_catalog..my_table"); + assertThat(table.fullyQualifiedTableName()).isEqualTo("second_catalog..my_table"); } public static class MySchemaSupplier implements Supplier> { From 1d31a17ce30ebfcf5d4361c37c41b42924fe77c1 Mon Sep 17 00:00:00 2001 From: Jeff Butler Date: Thu, 23 May 2019 16:05:09 -0400 Subject: [PATCH 7/8] Misc code cleanup --- .../sql/insert/InsertStatementTest.java | 4 +- .../sql/mybatis3/CriterionRendererTest.java | 52 +------------------ .../where/render/CriterionRendererTest.java | 48 +---------------- .../render/OptionalCriterionRenderTest.java | 6 ++- 4 files changed, 9 insertions(+), 101 deletions(-) diff --git a/src/test/java/org/mybatis/dynamic/sql/insert/InsertStatementTest.java b/src/test/java/org/mybatis/dynamic/sql/insert/InsertStatementTest.java index bfa6cccc1..cb5b63995 100644 --- a/src/test/java/org/mybatis/dynamic/sql/insert/InsertStatementTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/insert/InsertStatementTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 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. @@ -137,7 +137,7 @@ public void testParallelStream() { FieldAndValueCollector collector = mappings.parallelStream().collect(Collector.of( - () -> new FieldAndValueCollector<>(), + FieldAndValueCollector::new, FieldAndValueCollector::add, FieldAndValueCollector::merge)); diff --git a/src/test/java/org/mybatis/dynamic/sql/mybatis3/CriterionRendererTest.java b/src/test/java/org/mybatis/dynamic/sql/mybatis3/CriterionRendererTest.java index 584a2a0c9..e4046d56f 100644 --- a/src/test/java/org/mybatis/dynamic/sql/mybatis3/CriterionRendererTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/mybatis3/CriterionRendererTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 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. @@ -86,54 +86,6 @@ public void testAliasWithoutIgnore() { ); } - @Test - public void testNoAliasWithIgnore() { - SqlTable table = SqlTable.of("foo"); - SqlColumn column = table.column("id", JDBCType.INTEGER); - IsEqualTo condition = IsEqualTo.of(() -> 3); - SqlCriterion criterion = SqlCriterion.withColumn(column) - .withCondition(condition) - .build(); - AtomicInteger sequence = new AtomicInteger(1); - FragmentAndParameters fp = CriterionRenderer.withCriterion(criterion) - .withSequence(sequence) - .withRenderingStrategy(RenderingStrategy.MYBATIS3) - .withTableAliasCalculator(TableAliasCalculator.empty()) - .build() - .render() - .get() - .renderWithInitialConnector(); - - assertAll( - () -> assertThat(fp.fragment()).isEqualTo("id = #{parameters.p1,jdbcType=INTEGER}"), - () -> assertThat(fp.parameters().size()).isEqualTo(1) - ); - } - - @Test - public void testNoAliasWithoutIgnore() { - SqlTable table = SqlTable.of("foo"); - SqlColumn column = table.column("id", JDBCType.INTEGER); - IsEqualTo condition = IsEqualTo.of(() -> 3); - SqlCriterion criterion = SqlCriterion.withColumn(column) - .withCondition(condition) - .build(); - AtomicInteger sequence = new AtomicInteger(1); - FragmentAndParameters fp = CriterionRenderer.withCriterion(criterion) - .withSequence(sequence) - .withRenderingStrategy(RenderingStrategy.MYBATIS3) - .withTableAliasCalculator(TableAliasCalculator.empty()) - .build() - .render() - .get() - .renderWithInitialConnector(); - - assertAll( - () -> assertThat(fp.fragment()).isEqualTo("id = #{parameters.p1,jdbcType=INTEGER}"), - () -> assertThat(fp.parameters().size()).isEqualTo(1) - ); - } - @Test public void testTypeHandler() { SqlTable table = SqlTable.of("foo"); @@ -142,7 +94,7 @@ public void testTypeHandler() { .withJdbcType(JDBCType.DATE) .withTypeHandler("foo.Bar") .build(); - IsEqualTo condition = IsEqualTo.of(() -> new Date()); + IsEqualTo condition = IsEqualTo.of(Date::new); SqlCriterion criterion = SqlCriterion.withColumn(column) .withCondition(condition) .build(); diff --git a/src/test/java/org/mybatis/dynamic/sql/where/render/CriterionRendererTest.java b/src/test/java/org/mybatis/dynamic/sql/where/render/CriterionRendererTest.java index 3d60b5118..086e2cfb3 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/render/CriterionRendererTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/render/CriterionRendererTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 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. @@ -83,50 +83,4 @@ public void testAliasWithoutIgnore() { assertThat(fp.parameters().size()).isEqualTo(1); assertThat(fp.parameters().get("p1")).isEqualTo(3); } - - @Test - public void testNoAliasWithIgnore() { - SqlTable table = SqlTable.of("foo"); - SqlColumn column = table.column("id", JDBCType.INTEGER); - IsEqualTo condition = IsEqualTo.of(() -> 3); - SqlCriterion criterion = SqlCriterion.withColumn(column) - .withCondition(condition) - .build(); - AtomicInteger sequence = new AtomicInteger(1); - FragmentAndParameters fp = CriterionRenderer.withCriterion(criterion) - .withSequence(sequence) - .withRenderingStrategy(RenderingStrategy.MYBATIS3) - .withTableAliasCalculator(TableAliasCalculator.empty()) - .build() - .render() - .get() - .renderWithInitialConnector(); - - assertThat(fp.fragment()).isEqualTo("id = #{parameters.p1,jdbcType=INTEGER}"); - assertThat(fp.parameters().size()).isEqualTo(1); - assertThat(fp.parameters().get("p1")).isEqualTo(3); - } - - @Test - public void testNoAliasWithoutIgnore() { - SqlTable table = SqlTable.of("foo"); - SqlColumn column = table.column("id", JDBCType.INTEGER); - IsEqualTo condition = IsEqualTo.of(() -> 3); - SqlCriterion criterion = SqlCriterion.withColumn(column) - .withCondition(condition) - .build(); - AtomicInteger sequence = new AtomicInteger(1); - FragmentAndParameters fp = CriterionRenderer.withCriterion(criterion) - .withSequence(sequence) - .withRenderingStrategy(RenderingStrategy.MYBATIS3) - .withTableAliasCalculator(TableAliasCalculator.empty()) - .build() - .render() - .get() - .renderWithInitialConnector(); - - assertThat(fp.fragment()).isEqualTo("id = #{parameters.p1,jdbcType=INTEGER}"); - assertThat(fp.parameters().size()).isEqualTo(1); - assertThat(fp.parameters().get("p1")).isEqualTo(3); - } } diff --git a/src/test/java/org/mybatis/dynamic/sql/where/render/OptionalCriterionRenderTest.java b/src/test/java/org/mybatis/dynamic/sql/where/render/OptionalCriterionRenderTest.java index d9c80399b..75039e559 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/render/OptionalCriterionRenderTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/render/OptionalCriterionRenderTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 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. @@ -19,6 +19,8 @@ import static org.junit.jupiter.api.Assertions.assertAll; import static org.mybatis.dynamic.sql.SqlBuilder.*; +import java.util.Objects; + import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.SqlTable; @@ -48,7 +50,7 @@ public void testNoRenderableCriteria() { public void testNoRenderableCriteriaWithIf() { Integer nullId = null; - WhereClauseProvider whereClause = where(id, isEqualTo(nullId).when(v -> v != null)) + WhereClauseProvider whereClause = where(id, isEqualTo(nullId).when(Objects::nonNull)) .build() .render(RenderingStrategy.SPRING_NAMED_PARAMETER); From 0b9b087fe6fbeca1ba8735dcc200ebbbb15b6760 Mon Sep 17 00:00:00 2001 From: Jeff Butler Date: Thu, 23 May 2019 16:05:21 -0400 Subject: [PATCH 8/8] Misc code cleanup --- .../dynamic/sql/render/GuaranteedTableAliasCalculator.java | 2 +- .../org/mybatis/dynamic/sql/select/QueryExpressionModel.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/render/GuaranteedTableAliasCalculator.java b/src/main/java/org/mybatis/dynamic/sql/render/GuaranteedTableAliasCalculator.java index 0817de7c4..1480e93bc 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/GuaranteedTableAliasCalculator.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/GuaranteedTableAliasCalculator.java @@ -1,5 +1,5 @@ /** - * Copyright 2016-2017 the original author or authors. + * Copyright 2016-2019 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. diff --git a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionModel.java b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionModel.java index 0ebeb4551..dbf21020d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionModel.java @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 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.