From c7eaf1dfcda8c3520958c3becbb2cdd930669032 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 30 Apr 2024 16:33:33 -0400 Subject: [PATCH 001/260] Update Build for Java 11 --- pom.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index c5b04639a..c59ca2ac4 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ <properties> <java.version>17</java.version> - <java.release.version>8</java.release.version> + <java.release.version>11</java.release.version> <junit.jupiter.version>5.10.2</junit.jupiter.version> <spring.batch.version>5.1.1</spring.batch.version> @@ -68,7 +68,8 @@ <module.name>org.mybatis.dynamic.sql</module.name> <kotlin.version>1.9.23</kotlin.version> - <kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget> + <kotlin.compiler.jvmTarget>11</kotlin.compiler.jvmTarget> + <kotlin.compiler.apiVersion>1.6</kotlin.compiler.apiVersion> <sonar.sources>pom.xml,src/main/java,src/main/kotlin</sonar.sources> <sonar.tests>src/test/java,src/test/kotlin</sonar.tests> @@ -84,7 +85,7 @@ <dependencies> <dependency> <groupId>org.jetbrains.kotlin</groupId> - <artifactId>kotlin-stdlib-jdk8</artifactId> + <artifactId>kotlin-stdlib</artifactId> <version>${kotlin.version}</version> <scope>provided</scope> <optional>true</optional> From eaf951c6e6f7a4f8d9006d2d8d72678520c07c09 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 30 Apr 2024 16:40:49 -0400 Subject: [PATCH 002/260] Better Use of Optional --- .../dynamic/sql/insert/render/GeneralInsertRenderer.java | 3 +-- .../org/mybatis/dynamic/sql/insert/render/InsertRenderer.java | 3 +-- .../org/mybatis/dynamic/sql/update/render/UpdateRenderer.java | 3 +-- .../mybatis/dynamic/sql/where/render/CriterionRenderer.java | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertRenderer.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertRenderer.java index afc1d4b98..c5378b493 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertRenderer.java @@ -40,8 +40,7 @@ private GeneralInsertRenderer(Builder builder) { public GeneralInsertStatementProvider render() { FieldAndValueCollector collector = model.columnMappings() .map(m -> m.accept(visitor)) - .filter(Optional::isPresent) - .map(Optional::get) + .flatMap(Optional::stream) .collect(FieldAndValueCollector.collect()); Validator.assertFalse(collector.isEmpty(), "ERROR.9"); //$NON-NLS-1$ 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 431b3df8f..443695c50 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 @@ -35,8 +35,7 @@ private InsertRenderer(Builder<T> builder) { public InsertStatementProvider<T> render() { FieldAndValueCollector collector = model.columnMappings() .map(m -> m.accept(visitor)) - .filter(Optional::isPresent) - .map(Optional::get) + .flatMap(Optional::stream) .collect(FieldAndValueCollector.collect()); Validator.assertFalse(collector.isEmpty(), "ERROR.10"); //$NON-NLS-1$ 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 50397ee7f..c25a29ff9 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 @@ -85,8 +85,7 @@ private FragmentAndParameters calculateSetPhrase() { "ERROR.18"); //$NON-NLS-1$ FragmentCollector fragmentCollector = fragmentsAndParameters.stream() - .filter(Optional::isPresent) - .map(Optional::get) + .flatMap(Optional::stream) .collect(FragmentCollector.collect()); return toSetPhrase(fragmentCollector); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java index 6e3e13254..232b68c11 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java @@ -135,8 +135,7 @@ private FragmentAndParameters renderExists(ExistsCriterion criterion) { private List<RenderedCriterion> renderSubCriteria(List<AndOrCriteriaGroup> subCriteria) { return subCriteria.stream().map(this::renderAndOrCriteriaGroup) - .filter(Optional::isPresent) - .map(Optional::get) + .flatMap(Optional::stream) .collect(Collectors.toList()); } From cb05e7cc127e07156076e5014a7bd366da5b6189 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 30 Apr 2024 17:05:50 -0400 Subject: [PATCH 003/260] Use List builder when possible --- .../examples/emptywhere/EmptyWhereTest.java | 7 +-- .../examples/simple/MyBatisMapToRowTest.java | 10 +-- .../examples/simple/PersonMapperTest.java | 3 +- .../examples/spring/SpringMapToRowTest.java | 10 +-- .../issues/gh430/NoInitialConditionTest.java | 63 +++++++++---------- .../mybatis/dynamic/sql/InvalidSQLTest.java | 6 +- .../dynamic/sql/insert/MapToRowTest.java | 53 ++++++---------- .../sql/select/SelectStatementTest.java | 4 +- 8 files changed, 60 insertions(+), 96 deletions(-) diff --git a/src/test/java/examples/emptywhere/EmptyWhereTest.java b/src/test/java/examples/emptywhere/EmptyWhereTest.java index 3f6d4a86e..8b3fdc546 100644 --- a/src/test/java/examples/emptywhere/EmptyWhereTest.java +++ b/src/test/java/examples/emptywhere/EmptyWhereTest.java @@ -56,12 +56,7 @@ static List<Variation> baseVariations() { Variation v4 = new Variation(null, null, ""); - List<Variation> answer = new ArrayList<>(); - answer.add(v1); - answer.add(v2); - answer.add(v3); - answer.add(v4); - return answer; + return List.of(v1, v2, v3, v4); } static Stream<Variation> whereVariations() { diff --git a/src/test/java/examples/simple/MyBatisMapToRowTest.java b/src/test/java/examples/simple/MyBatisMapToRowTest.java index f17bca807..2b6f714b2 100644 --- a/src/test/java/examples/simple/MyBatisMapToRowTest.java +++ b/src/test/java/examples/simple/MyBatisMapToRowTest.java @@ -109,10 +109,7 @@ void testInsertMultiple() { try (SqlSession session = sqlSessionFactory.openSession()) { CompoundKeyMapper mapper = session.getMapper(CompoundKeyMapper.class); - List<Integer> integers = new ArrayList<>(); - integers.add(1); - integers.add(2); - integers.add(3); + List<Integer> integers = List.of(1, 2, 3); MultiRowInsertStatementProvider<Integer> insertStatement = insertMultiple(integers) .into(compoundKey) @@ -142,10 +139,7 @@ void testInsertBatch() { try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) { CompoundKeyMapper mapper = session.getMapper(CompoundKeyMapper.class); - List<Integer> integers = new ArrayList<>(); - integers.add(1); - integers.add(2); - integers.add(3); + List<Integer> integers = List.of(1, 2, 3); BatchInsert<Integer> insertStatement = insertBatch(integers) .into(compoundKey) diff --git a/src/test/java/examples/simple/PersonMapperTest.java b/src/test/java/examples/simple/PersonMapperTest.java index 3a8ee5b85..89f3a90f1 100644 --- a/src/test/java/examples/simple/PersonMapperTest.java +++ b/src/test/java/examples/simple/PersonMapperTest.java @@ -253,8 +253,7 @@ void testFirstNameIn() { @Test void testOrderByCollection() { - Collection<SortSpecification> orderByColumns = new ArrayList<>(); - orderByColumns.add(firstName); + Collection<SortSpecification> orderByColumns = List.of(firstName); try (SqlSession session = sqlSessionFactory.openSession()) { PersonMapper mapper = session.getMapper(PersonMapper.class); diff --git a/src/test/java/examples/spring/SpringMapToRowTest.java b/src/test/java/examples/spring/SpringMapToRowTest.java index 91271b39f..c3b1077c9 100644 --- a/src/test/java/examples/spring/SpringMapToRowTest.java +++ b/src/test/java/examples/spring/SpringMapToRowTest.java @@ -74,10 +74,7 @@ void testInsertOne() { @Test void testInsertMultiple() { - List<Integer> integers = new ArrayList<>(); - integers.add(1); - integers.add(2); - integers.add(3); + List<Integer> integers = List.of(1, 2, 3); MultiRowInsertStatementProvider<Integer> insertStatement = insertMultiple(integers) .into(compoundKey) @@ -102,10 +99,7 @@ void testInsertMultiple() { @Test void testInsertBatch() { - List<Integer> integers = new ArrayList<>(); - integers.add(1); - integers.add(2); - integers.add(3); + List<Integer> integers = List.of(1, 2, 3); BatchInsert<Integer> insertStatement = insertBatch(integers) .into(compoundKey) diff --git a/src/test/java/issues/gh430/NoInitialConditionTest.java b/src/test/java/issues/gh430/NoInitialConditionTest.java index b9104d43e..22f5c954c 100644 --- a/src/test/java/issues/gh430/NoInitialConditionTest.java +++ b/src/test/java/issues/gh430/NoInitialConditionTest.java @@ -19,7 +19,7 @@ import static org.mybatis.dynamic.sql.SqlBuilder.*; import static org.mybatis.dynamic.sql.subselect.FooDynamicSqlSupport.*; -import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.List; @@ -32,7 +32,7 @@ class NoInitialConditionTest { @Test void testNoInitialConditionEmptyList() { - List<AndOrCriteriaGroup> criteria = new ArrayList<>(); + List<AndOrCriteriaGroup> criteria = Collections.emptyList(); SelectStatementProvider selectStatement = buildSelectStatement(criteria); @@ -43,8 +43,7 @@ void testNoInitialConditionEmptyList() { @Test void testNoInitialConditionSingleSub() { - List<AndOrCriteriaGroup> criteria = new ArrayList<>(); - criteria.add(or(column2, isEqualTo(3))); + List<AndOrCriteriaGroup> criteria = List.of(or(column2, isEqualTo(3))); SelectStatementProvider selectStatement = buildSelectStatement(criteria); @@ -56,10 +55,10 @@ void testNoInitialConditionSingleSub() { @Test void testNoInitialConditionMultipleSubs() { - List<AndOrCriteriaGroup> criteria = new ArrayList<>(); - criteria.add(or(column2, isEqualTo(3))); - criteria.add(or(column2, isEqualTo(4))); - criteria.add(or(column2, isEqualTo(5))); + List<AndOrCriteriaGroup> criteria = List.of( + or(column2, isEqualTo(3)), + or(column2, isEqualTo(4)), + or(column2, isEqualTo(5))); SelectStatementProvider selectStatement = buildSelectStatement(criteria); @@ -71,10 +70,10 @@ void testNoInitialConditionMultipleSubs() { @Test void testNoInitialConditionWhereMultipleSubs() { - List<AndOrCriteriaGroup> criteria = new ArrayList<>(); - criteria.add(or(column2, isEqualTo(3))); - criteria.add(or(column2, isEqualTo(4))); - criteria.add(or(column2, isEqualTo(5))); + List<AndOrCriteriaGroup> criteria = List.of( + or(column2, isEqualTo(3)), + or(column2, isEqualTo(4)), + or(column2, isEqualTo(5))); SelectStatementProvider selectStatement = select(column1, column2) .from(foo) @@ -90,10 +89,10 @@ void testNoInitialConditionWhereMultipleSubs() { @Test void testNoInitialConditionWhereNotMultipleSubs() { - List<AndOrCriteriaGroup> criteria = new ArrayList<>(); - criteria.add(or(column2, isEqualTo(3))); - criteria.add(or(column2, isEqualTo(4))); - criteria.add(or(column2, isEqualTo(5))); + List<AndOrCriteriaGroup> criteria = List.of( + or(column2, isEqualTo(3)), + or(column2, isEqualTo(4)), + or(column2, isEqualTo(5))); SelectStatementProvider selectStatement = select(column1, column2) .from(foo) @@ -110,10 +109,10 @@ void testNoInitialConditionWhereNotMultipleSubs() { @Test void testNoInitialConditionWhereGroupMultipleSubs() { - List<AndOrCriteriaGroup> criteria = new ArrayList<>(); - criteria.add(or(column2, isEqualTo(3))); - criteria.add(or(column2, isEqualTo(4))); - criteria.add(or(column2, isEqualTo(5))); + List<AndOrCriteriaGroup> criteria = List.of( + or(column2, isEqualTo(3)), + or(column2, isEqualTo(4)), + or(column2, isEqualTo(5))); SelectStatementProvider selectStatement = select(column1, column2) .from(foo) @@ -130,10 +129,10 @@ void testNoInitialConditionWhereGroupMultipleSubs() { @Test void testNoInitialConditionWhereCCAndMultipleSubs() { - List<AndOrCriteriaGroup> criteria = new ArrayList<>(); - criteria.add(or(column2, isEqualTo(3))); - criteria.add(or(column2, isEqualTo(4))); - criteria.add(or(column2, isEqualTo(5))); + List<AndOrCriteriaGroup> criteria = List.of( + or(column2, isEqualTo(3)), + or(column2, isEqualTo(4)), + or(column2, isEqualTo(5))); SelectStatementProvider selectStatement = select(column1, column2) .from(foo) @@ -149,10 +148,10 @@ void testNoInitialConditionWhereCCAndMultipleSubs() { @Test void testNoInitialConditionWhereCCOrMultipleSubs() { - List<AndOrCriteriaGroup> criteria = new ArrayList<>(); - criteria.add(or(column2, isEqualTo(3))); - criteria.add(or(column2, isEqualTo(4))); - criteria.add(or(column2, isEqualTo(5))); + List<AndOrCriteriaGroup> criteria = List.of( + or(column2, isEqualTo(3)), + or(column2, isEqualTo(4)), + or(column2, isEqualTo(5))); SelectStatementProvider selectStatement = select(column1, column2) .from(foo) @@ -168,10 +167,10 @@ void testNoInitialConditionWhereCCOrMultipleSubs() { @Test void testNoInitialConditionWhereOrMultipleSubs() { - List<AndOrCriteriaGroup> criteria = new ArrayList<>(); - criteria.add(or(column2, isEqualTo(3))); - criteria.add(or(column2, isEqualTo(4))); - criteria.add(or(column2, isEqualTo(5))); + List<AndOrCriteriaGroup> criteria = List.of( + or(column2, isEqualTo(3)), + or(column2, isEqualTo(4)), + or(column2, isEqualTo(5))); SelectStatementProvider selectStatement = select(column1, column2) .from(foo) diff --git a/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java b/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java index acaff0b4f..bd8df6c7a 100644 --- a/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java @@ -115,8 +115,7 @@ void testInvalidMultipleInsertStatementNoRecords() { @Test void testInvalidMultipleInsertStatementNoMappings() { - List<TestRow> records = new ArrayList<>(); - records.add(new TestRow()); + List<TestRow> records = List.of(new TestRow()); MultiRowInsertModel.Builder<TestRow> builder = new MultiRowInsertModel.Builder<TestRow>() .withRecords(records) @@ -137,8 +136,7 @@ void testInvalidBatchInsertStatementNoRecords() { @Test void testInvalidBatchInsertStatementNoMappings() { - List<TestRow> records = new ArrayList<>(); - records.add(new TestRow()); + List<TestRow> records = List.of(new TestRow()); BatchInsertModel.Builder<TestRow> builder = new BatchInsertModel.Builder<TestRow>() .withRecords(records) diff --git a/src/test/java/org/mybatis/dynamic/sql/insert/MapToRowTest.java b/src/test/java/org/mybatis/dynamic/sql/insert/MapToRowTest.java index cd4871f14..fc8c17ad5 100644 --- a/src/test/java/org/mybatis/dynamic/sql/insert/MapToRowTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/insert/MapToRowTest.java @@ -20,7 +20,6 @@ import static org.mybatis.dynamic.sql.SqlBuilder.insertMultiple; import java.sql.JDBCType; -import java.util.ArrayList; import java.util.List; import org.junit.jupiter.api.Test; @@ -37,10 +36,10 @@ class MapToRowTest { @Test void testBasicInsertMultipleWithMyBatis() { - List<Record> records = new ArrayList<>(); - records.add(new Record(33, 1)); - records.add(new Record(33, 2)); - records.add(new Record(33, 3)); + List<Record> records = List.of( + new Record(33, 1), + new Record(33, 2), + new Record(33, 3)); MultiRowInsertStatementProvider<Record> insertStatement = insertMultiple(records) .into(foo) @@ -55,10 +54,10 @@ void testBasicInsertMultipleWithMyBatis() { @Test void testBasicInsertMultipleWithSpring() { - List<Record> records = new ArrayList<>(); - records.add(new Record(33, 1)); - records.add(new Record(33, 2)); - records.add(new Record(33, 3)); + List<Record> records = List.of( + new Record(33, 1), + new Record(33, 2), + new Record(33, 3)); MultiRowInsertStatementProvider<Record> insertStatement = insertMultiple(records) .into(foo) @@ -73,10 +72,7 @@ void testBasicInsertMultipleWithSpring() { @Test void testBasicInsertMultipleRowMappingWithMyBatis() { - List<Integer> integers = new ArrayList<>(); - integers.add(1); - integers.add(2); - integers.add(3); + List<Integer> integers = List.of(1, 2, 3); MultiRowInsertStatementProvider<Integer> insertStatement = insertMultiple(integers) .into(foo) @@ -91,10 +87,7 @@ void testBasicInsertMultipleRowMappingWithMyBatis() { @Test void testBasicInsertMultipleRowMappingWithSpring() { - List<Integer> integers = new ArrayList<>(); - integers.add(1); - integers.add(2); - integers.add(3); + List<Integer> integers = List.of(1, 2, 3); MultiRowInsertStatementProvider<Integer> insertStatement = insertMultiple(integers) .into(foo) @@ -109,10 +102,10 @@ void testBasicInsertMultipleRowMappingWithSpring() { @Test void testBatchInsertWithMyBatis() { - List<Record> records = new ArrayList<>(); - records.add(new Record(33, 1)); - records.add(new Record(33, 2)); - records.add(new Record(33, 3)); + List<Record> records = List.of( + new Record(33, 1), + new Record(33, 2), + new Record(33, 3)); BatchInsert<Record> batchInsert = insertBatch(records) .into(foo) @@ -127,10 +120,10 @@ void testBatchInsertWithMyBatis() { @Test void testBatchInsertWithSpring() { - List<Record> records = new ArrayList<>(); - records.add(new Record(33, 1)); - records.add(new Record(33, 2)); - records.add(new Record(33, 3)); + List<Record> records = List.of( + new Record(33, 1), + new Record(33, 2), + new Record(33, 3)); BatchInsert<Record> batchInsert = insertBatch(records) .into(foo) @@ -145,10 +138,7 @@ void testBatchInsertWithSpring() { @Test void testBatchInsertRowMappingWithMyBatis() { - List<Integer> integers = new ArrayList<>(); - integers.add(1); - integers.add(2); - integers.add(3); + List<Integer> integers = List.of(1, 2, 3); BatchInsert<Integer> batchInsert = insertBatch(integers) .into(foo) @@ -163,10 +153,7 @@ void testBatchInsertRowMappingWithMyBatis() { @Test void testBatchInsertRowMappingWithSpring() { - List<Integer> integers = new ArrayList<>(); - integers.add(1); - integers.add(2); - integers.add(3); + List<Integer> integers = List.of(1, 2, 3); BatchInsert<Integer> batchInsert = insertBatch(integers) .into(foo) diff --git a/src/test/java/org/mybatis/dynamic/sql/select/SelectStatementTest.java b/src/test/java/org/mybatis/dynamic/sql/select/SelectStatementTest.java index 9fd066a42..a243fec17 100644 --- a/src/test/java/org/mybatis/dynamic/sql/select/SelectStatementTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/select/SelectStatementTest.java @@ -180,9 +180,7 @@ void testOrderByMultipleColumns() { @Test void testOrderByMultipleColumnsWithCollection() { - Collection<SortSpecification> orderByColumns = new ArrayList<>(); - orderByColumns.add(column2.descending()); - orderByColumns.add(column1); + Collection<SortSpecification> orderByColumns = List.of(column2.descending(), column1); SelectStatementProvider selectStatement = select(column1.as("A_COLUMN1"), column2) .from(table, "a") From c3ec1241a48f354f52a55a17559f1ab38881f6e0 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 1 May 2024 10:43:39 -0400 Subject: [PATCH 004/260] Restore new version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ce548f554..c59ca2ac4 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ <groupId>org.mybatis.dynamic-sql</groupId> <artifactId>mybatis-dynamic-sql</artifactId> - <version>1.5.2-SNAPSHOT</version> + <version>1.6.0-SNAPSHOT</version> <name>MyBatis Dynamic SQL</name> <description>MyBatis framework for generating dynamic SQL</description> From 3fb12f7a4523e734f0e823f027f215c915ceb74f Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 3 Jun 2024 17:15:35 -0400 Subject: [PATCH 005/260] [maven-release-plugin] prepare for next development iteration --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 284c3ff83..8dc86be10 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ <groupId>org.mybatis.dynamic-sql</groupId> <artifactId>mybatis-dynamic-sql</artifactId> - <version>1.5.2</version> + <version>1.6.0-SNAPSHOT</version> <name>MyBatis Dynamic SQL</name> <description>MyBatis framework for generating dynamic SQL</description> @@ -36,7 +36,7 @@ <scm> <connection>scm:git:ssh://git@github.com/mybatis/mybatis-dynamic-sql.git</connection> <developerConnection>scm:git:ssh://git@github.com/mybatis/mybatis-dynamic-sql.git</developerConnection> - <tag>mybatis-dynamic-sql-1.5.2</tag> + <tag>HEAD</tag> <url>https://github.com/mybatis/mybatis-dynamic-sql/</url> </scm> <issueManagement> @@ -78,7 +78,7 @@ <osgi.export>org.mybatis.dynamic.sql.*;version=${project.version};-noimport:=true</osgi.export> <!-- Reproducible Builds --> - <project.build.outputTimestamp>1717449261</project.build.outputTimestamp> + <project.build.outputTimestamp>1717449335</project.build.outputTimestamp> </properties> <dependencies> From 2856f6c96218e31ec8dc8968119501a9f4b6e0ca Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 3 Jun 2024 17:35:30 -0400 Subject: [PATCH 006/260] Update Kotlin API Version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1a186bbe3..6effacd82 100644 --- a/pom.xml +++ b/pom.xml @@ -69,7 +69,7 @@ <kotlin.version>2.0.0</kotlin.version> <kotlin.compiler.jvmTarget>11</kotlin.compiler.jvmTarget> - <kotlin.compiler.apiVersion>1.6</kotlin.compiler.apiVersion> + <kotlin.compiler.apiVersion>1.7</kotlin.compiler.apiVersion> <sonar.sources>pom.xml,src/main/java,src/main/kotlin</sonar.sources> <sonar.tests>src/test/java,src/test/kotlin</sonar.tests> From a2e024f9ff64f2cb26cb94843cf0d7bdcbeee377 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 3 Jun 2024 17:47:29 -0400 Subject: [PATCH 007/260] Restore changes lost in merge --- pom.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pom.xml b/pom.xml index 6effacd82..3205bf22d 100644 --- a/pom.xml +++ b/pom.xml @@ -207,6 +207,15 @@ <build> <plugins> + <plugin> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + <configuration> + <excludes> + <exclude>org/jetbrains/kotlin/**/*</exclude> + </excludes> + </configuration> + </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-site-plugin</artifactId> From f887c344ff05b3c72ff2ea7ea7a92b93335473a7 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 7 Jun 2024 10:37:33 -0400 Subject: [PATCH 008/260] Target Java 17 --- pom.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3205bf22d..b846ad845 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ <properties> <java.version>17</java.version> - <java.release.version>11</java.release.version> + <java.release.version>17</java.release.version> <junit.jupiter.version>5.10.2</junit.jupiter.version> <spring.batch.version>5.1.2</spring.batch.version> @@ -68,7 +68,6 @@ <module.name>org.mybatis.dynamic.sql</module.name> <kotlin.version>2.0.0</kotlin.version> - <kotlin.compiler.jvmTarget>11</kotlin.compiler.jvmTarget> <kotlin.compiler.apiVersion>1.7</kotlin.compiler.apiVersion> <sonar.sources>pom.xml,src/main/java,src/main/kotlin</sonar.sources> From 22e75b123979a0e8e9ab0846c415874d087753c8 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 7 Jun 2024 10:44:35 -0400 Subject: [PATCH 009/260] Use Predicate.not for readability --- src/site/markdown/docs/conditions.md | 4 ++-- src/test/java/examples/animal/data/MyInCondition.java | 4 +++- .../data/OptionalConditionsWithPredicatesAnimalDataTest.java | 3 ++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/site/markdown/docs/conditions.md b/src/site/markdown/docs/conditions.md index d5683f206..55a2e6617 100644 --- a/src/site/markdown/docs/conditions.md +++ b/src/site/markdown/docs/conditions.md @@ -267,7 +267,7 @@ any null or blank string, and you want to trim all strings. This can be accompli .where(animalName, isIn(" Mouse", " ", null, "", "Musk shrew ") .filter(Objects::nonNull) .map(String::trim) - .filter(st -> !st.isEmpty())) + .filter(not(String::isEmpty))) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -284,7 +284,7 @@ public class MyInCondition { return SqlBuilder.isIn(values) .filter(Objects::nonNull) .map(String::trim) - .filter(st -> !st.isEmpty()); + .filter(not(String::isEmpty)); } } ``` diff --git a/src/test/java/examples/animal/data/MyInCondition.java b/src/test/java/examples/animal/data/MyInCondition.java index 86035a838..65453997f 100644 --- a/src/test/java/examples/animal/data/MyInCondition.java +++ b/src/test/java/examples/animal/data/MyInCondition.java @@ -15,6 +15,8 @@ */ package examples.animal.data; +import static java.util.function.Predicate.not; + import java.util.Objects; import org.mybatis.dynamic.sql.SqlBuilder; @@ -25,6 +27,6 @@ public static IsIn<String> isIn(String...values) { return SqlBuilder.isIn(values) .filter(Objects::nonNull) .map((String::trim)) - .filter(st -> !st.isEmpty()); + .filter(not(String::isEmpty)); } } diff --git a/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java b/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java index 7dd1e131e..cff21a348 100644 --- a/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java +++ b/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java @@ -20,6 +20,7 @@ import static examples.animal.data.AnimalDataDynamicSqlSupport.bodyWeight; import static examples.animal.data.AnimalDataDynamicSqlSupport.brainWeight; import static examples.animal.data.AnimalDataDynamicSqlSupport.id; +import static java.util.function.Predicate.not; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertAll; import static org.mybatis.dynamic.sql.SqlBuilder.*; @@ -484,7 +485,7 @@ void testValueStreamTransformer() { .where(animalName, isIn(" Mouse", " ", null, "", "Musk shrew ") .filter(Objects::nonNull) .map(String::trim) - .filter(st -> !st.isEmpty())) + .filter(not(String::isEmpty))) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); From 24fef48d28f3935e20099907d525820969234c0e Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 7 Jun 2024 11:00:39 -0400 Subject: [PATCH 010/260] Remove Deprecated Java code --- .../org/mybatis/dynamic/sql/BasicColumn.java | 23 +-- .../org/mybatis/dynamic/sql/SqlTable.java | 71 -------- .../DefaultInsertStatementProvider.java | 13 -- .../render/InsertStatementProvider.java | 10 -- .../schema_supplier/SchemaSupplier.java | 26 --- .../schema_supplier/SchemaSupplierTest.java | 146 ----------------- .../java/examples/schema_supplier/User.java | 37 ----- .../UserDynamicSqlSupport.java | 36 ----- .../examples/schema_supplier/UserMapper.java | 56 ------- .../mybatis/dynamic/sql/InvalidSQLTest.java | 59 ------- .../org/mybatis/dynamic/sql/SqlTableTest.java | 153 ------------------ .../sql/insert/InsertStatementTest.java | 18 --- 12 files changed, 1 insertion(+), 647 deletions(-) delete mode 100644 src/test/java/examples/schema_supplier/SchemaSupplier.java delete mode 100644 src/test/java/examples/schema_supplier/SchemaSupplierTest.java delete mode 100644 src/test/java/examples/schema_supplier/User.java delete mode 100644 src/test/java/examples/schema_supplier/UserDynamicSqlSupport.java delete mode 100644 src/test/java/examples/schema_supplier/UserMapper.java diff --git a/src/main/java/org/mybatis/dynamic/sql/BasicColumn.java b/src/main/java/org/mybatis/dynamic/sql/BasicColumn.java index aaee827b1..b73757a71 100644 --- a/src/main/java/org/mybatis/dynamic/sql/BasicColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/BasicColumn.java @@ -17,11 +17,8 @@ import java.util.Optional; -import org.mybatis.dynamic.sql.exception.DynamicSqlException; import org.mybatis.dynamic.sql.render.RenderingContext; -import org.mybatis.dynamic.sql.render.TableAliasCalculator; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -import org.mybatis.dynamic.sql.util.Messages; /** * Describes attributes of columns that are necessary for rendering if the column is not expected to @@ -59,25 +56,7 @@ public interface BasicColumn { * @return a rendered SQL fragment and, optionally, parameters associated with the fragment * @since 1.5.1 */ - default FragmentAndParameters render(RenderingContext renderingContext) { - // the default implementation ensures compatibility with prior releases. When the - // deprecated renderWithTableAlias method is removed, this function can become purely abstract. - // Also remove the method tableAliasCalculator() from RenderingContext. - return FragmentAndParameters.fromFragment(renderWithTableAlias(renderingContext.tableAliasCalculator())); - } - - /** - * Returns the name of the item aliased with a table name if appropriate. - * For example, "a.foo". This is appropriate for where clauses and order by clauses. - * - * @param tableAliasCalculator the table alias calculator for the current renderer - * @return the item name with the table alias applied - * @deprecated Please replace this method by overriding the more general "render" method - */ - @Deprecated - default String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) { - throw new DynamicSqlException(Messages.getString("ERROR.36")); //$NON-NLS-1$ - } + FragmentAndParameters render(RenderingContext renderingContext); /** * Utility method to make it easier to build column lists for methods that require an diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlTable.java b/src/main/java/org/mybatis/dynamic/sql/SqlTable.java index d3b34eff0..1322d958f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlTable.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlTable.java @@ -32,77 +32,6 @@ protected SqlTable(String tableName) { this.nameSupplier = () -> tableName; } - /** - * Creates an SqlTable whose name can be changed at runtime. - * - * @param tableNameSupplier table name supplier - * @deprecated please use {@link AliasableSqlTable} if you need to change the table name at runtime - */ - @Deprecated - protected SqlTable(Supplier<String> tableNameSupplier) { - Objects.requireNonNull(tableNameSupplier); - - this.nameSupplier = tableNameSupplier; - } - - /** - * Creates an SqlTable whose name can be changed at runtime. - * - * @param schemaSupplier schema supplier - * @param tableName table name - * @deprecated please use {@link AliasableSqlTable} if you need to change the table name at runtime - */ - @Deprecated - protected SqlTable(Supplier<Optional<String>> schemaSupplier, String tableName) { - this(Optional::empty, schemaSupplier, tableName); - } - - /** - * Creates an SqlTable whose name can be changed at runtime. - * - * @param catalogSupplier catalog supplier - * @param schemaSupplier schema supplier - * @param tableName table name - * @deprecated please use {@link AliasableSqlTable} if you need to change the table name at runtime - */ - @Deprecated - protected SqlTable(Supplier<Optional<String>> catalogSupplier, Supplier<Optional<String>> schemaSupplier, - String tableName) { - Objects.requireNonNull(catalogSupplier); - Objects.requireNonNull(schemaSupplier); - Objects.requireNonNull(tableName); - - this.nameSupplier = () -> compose(catalogSupplier, schemaSupplier, tableName); - } - - private String compose(Supplier<Optional<String>> catalogSupplier, Supplier<Optional<String>> schemaSupplier, - String tableName) { - return catalogSupplier.get().map(c -> compose(c, schemaSupplier, tableName)) - .orElseGet(() -> compose(schemaSupplier, tableName)); - } - - private String compose(String catalog, Supplier<Optional<String>> schemaSupplier, String tableName) { - return schemaSupplier.get().map(s -> composeCatalogSchemaAndTable(catalog, s, tableName)) - .orElseGet(() -> composeCatalogAndTable(catalog, tableName)); - } - - private String compose(Supplier<Optional<String>> 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 composeCatalogSchemaAndTable(String catalog, String schema, String tableName) { - return catalog + "." + schema + "." + tableName; //$NON-NLS-1$ //$NON-NLS-2$ - } - public String tableNameAtRuntime() { return nameSupplier.get(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultInsertStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultInsertStatementProvider.java index aae15c34e..d75e90e27 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultInsertStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultInsertStatementProvider.java @@ -21,24 +21,11 @@ public class DefaultInsertStatementProvider<T> implements InsertStatementProvider<T> { private final String insertStatement; - // need to keep both row and record for now so we don't break - // old code. The MyBatis reflection utilities don't handle - // the case where the attribute name is different from the getter. - // - // MyBatis Generator version 1.4.1 (March 8, 2022) changed to use "row" instead of "record". - // Target March 2023 for removing "record" from MyBatis Dynamic SQL. - private final T record; private final T row; private DefaultInsertStatementProvider(Builder<T> builder) { insertStatement = Objects.requireNonNull(builder.insertStatement); row = Objects.requireNonNull(builder.row); - record = row; - } - - @Override - public T getRecord() { - return record; } @Override diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertStatementProvider.java index 6658320f9..ea0d0db18 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertStatementProvider.java @@ -18,16 +18,6 @@ import org.jetbrains.annotations.NotNull; public interface InsertStatementProvider<T> { - /** - * Return the row associated with this insert statement. - * - * @return the row associated with this insert statement. - * - * @deprecated in favor of {@link InsertStatementProvider#getRow()} - */ - @Deprecated - T getRecord(); - /** * Return the row associated with this insert statement. * diff --git a/src/test/java/examples/schema_supplier/SchemaSupplier.java b/src/test/java/examples/schema_supplier/SchemaSupplier.java deleted file mode 100644 index b5a3e8fbe..000000000 --- a/src/test/java/examples/schema_supplier/SchemaSupplier.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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<String> 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 deleted file mode 100644 index 7cc70fc7c..000000000 --- a/src/test/java/examples/schema_supplier/SchemaSupplierTest.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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; -import org.mybatis.dynamic.sql.select.SelectDSLCompleter; - -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 - void setup() throws Exception { - Class.forName(JDBC_DRIVER); - InputStream is = getClass().getResourceAsStream("/examples/schema_supplier/CreateDB.sql"); - assert is != null; - 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 - void testUnsetSchemaProperty() { - System.clearProperty(SchemaSupplier.schema_property); - - try (SqlSession session = sqlSessionFactory.openSession()) { - UserMapper mapper = session.getMapper(UserMapper.class); - - User user = new User(); - user.setId(1); - user.setName("Fred"); - - assertThrows(PersistenceException.class, () -> mapper.insert(user)); - } - } - - @Test - void testSchemaProperty() { - System.setProperty(SchemaSupplier.schema_property, "schema1"); - - try (SqlSession session = sqlSessionFactory.openSession()) { - UserMapper mapper = session.getMapper(UserMapper.class); - - insertFlintstones(mapper); - - List<User> records = mapper.select(SelectDSLCompleter.allRows()); - assertThat(records).hasSize(2); - } - } - - @Test - void testSchemaSwitchingProperty() { - try (SqlSession session = sqlSessionFactory.openSession()) { - UserMapper mapper = session.getMapper(UserMapper.class); - - System.setProperty(SchemaSupplier.schema_property, "schema1"); - insertFlintstones(mapper); - - List<User> records = mapper.select(SelectDSLCompleter.allRows()); - assertThat(records).hasSize(2); - - System.setProperty(SchemaSupplier.schema_property, "schema2"); - insertRubbles(mapper); - - records = mapper.select(SelectDSLCompleter.allRows()); - assertThat(records).hasSize(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 deleted file mode 100644 index 02acc9c53..000000000 --- a/src/test/java/examples/schema_supplier/User.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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 deleted file mode 100644 index fdb38f0ea..000000000 --- a/src/test/java/examples/schema_supplier/UserDynamicSqlSupport.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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<Integer> id = user.id; - public static final SqlColumn<String> name = user.name; - - public static final class User extends SqlTable { - public final SqlColumn<Integer> id = column("user_id", JDBCType.INTEGER); - public final SqlColumn<String> 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 deleted file mode 100644 index 602ed49a3..000000000 --- a/src/test/java/examples/schema_supplier/UserMapper.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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.Result; -import org.apache.ibatis.annotations.Results; -import org.apache.ibatis.annotations.SelectProvider; -import org.apache.ibatis.type.JdbcType; -import org.mybatis.dynamic.sql.BasicColumn; -import org.mybatis.dynamic.sql.SqlBuilder; -import org.mybatis.dynamic.sql.render.RenderingStrategies; -import org.mybatis.dynamic.sql.select.SelectDSLCompleter; -import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; -import org.mybatis.dynamic.sql.util.SqlProviderAdapter; -import org.mybatis.dynamic.sql.util.mybatis3.CommonInsertMapper; -import org.mybatis.dynamic.sql.util.mybatis3.MyBatis3Utils; - -public interface UserMapper extends CommonInsertMapper<User> { - - @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<User> selectMany(SelectStatementProvider selectStatement); - - default List<User> select(SelectDSLCompleter completer) { - return MyBatis3Utils.selectList(this::selectMany, BasicColumn.columnList(id, name), user, completer); - } - - default int insert(User row) { - return insert(SqlBuilder.insert(row) - .into(user) - .map(id).toProperty("id") - .map(name).toProperty("name") - .build() - .render(RenderingStrategies.MYBATIS3)); - } -} diff --git a/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java b/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java index 4c7afc0b0..6665dd48f 100644 --- a/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java @@ -19,7 +19,6 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mybatis.dynamic.sql.SqlBuilder.insert; import static org.mybatis.dynamic.sql.SqlBuilder.insertInto; -import static org.mybatis.dynamic.sql.SqlBuilder.select; import static org.mybatis.dynamic.sql.SqlBuilder.update; import static org.mybatis.dynamic.sql.SqlBuilder.value; @@ -32,7 +31,6 @@ import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; -import org.mybatis.dynamic.sql.exception.DynamicSqlException; import org.mybatis.dynamic.sql.exception.InvalidSqlException; import org.mybatis.dynamic.sql.insert.BatchInsertModel; import org.mybatis.dynamic.sql.insert.GeneralInsertModel; @@ -41,7 +39,6 @@ import org.mybatis.dynamic.sql.insert.MultiRowInsertModel; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.render.RenderingStrategies; -import org.mybatis.dynamic.sql.render.TableAliasCalculator; import org.mybatis.dynamic.sql.select.GroupByModel; import org.mybatis.dynamic.sql.select.PagingModel; import org.mybatis.dynamic.sql.select.QueryExpressionModel; @@ -50,7 +47,6 @@ import org.mybatis.dynamic.sql.select.join.JoinSpecification; import org.mybatis.dynamic.sql.select.join.JoinType; import org.mybatis.dynamic.sql.select.render.FetchFirstPagingModelRenderer; -import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.mybatis.dynamic.sql.update.UpdateModel; import org.mybatis.dynamic.sql.util.InternalError; import org.mybatis.dynamic.sql.util.Messages; @@ -267,23 +263,6 @@ void testInvalidValueAlias() { .withMessage(Messages.getString("ERROR.38")); } - @Test - void testBadColumn() { - SelectModel selectModel = select(new BadCount<>()).from(person).build(); - assertThatExceptionOfType(DynamicSqlException.class) - .isThrownBy(() -> selectModel.render(RenderingStrategies.MYBATIS3)) - .withMessage(Messages.getString("ERROR.36")); - } - - @Test - void testDeprecatedColumn() { - SelectStatementProvider selectStatement = select(new DeprecatedCount<>()) - .from(person) - .build() - .render(RenderingStrategies.MYBATIS3); - assertThat(selectStatement.getSelectStatement()).isEqualTo("select count(*) from person"); - } - static class TestRow { private Integer id; @@ -295,42 +274,4 @@ public void setId(Integer id) { this.id = id; } } - - static class BadCount<T> implements BindableColumn<T> { - private String alias; - - @Override - public Optional<String> alias() { - return Optional.ofNullable(alias); - } - - @Override - public BindableColumn<T> as(String alias) { - BadCount<T> newCount = new BadCount<>(); - newCount.alias = alias; - return newCount; - } - } - - static class DeprecatedCount<T> implements BindableColumn<T> { - private String alias; - - @Override - @Deprecated - public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) { - return "count(*)"; - } - - @Override - public Optional<String> alias() { - return Optional.ofNullable(alias); - } - - @Override - public BindableColumn<T> as(String alias) { - DeprecatedCount<T> newCount = new DeprecatedCount<>(); - newCount.alias = alias; - return newCount; - } - } } diff --git a/src/test/java/org/mybatis/dynamic/sql/SqlTableTest.java b/src/test/java/org/mybatis/dynamic/sql/SqlTableTest.java index 32d336572..473258dcb 100644 --- a/src/test/java/org/mybatis/dynamic/sql/SqlTableTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/SqlTableTest.java @@ -17,166 +17,13 @@ import static org.assertj.core.api.Assertions.assertThat; -import java.util.Optional; -import java.util.function.Supplier; - import org.junit.jupiter.api.Test; class SqlTableTest { - private static final String NAME_PROPERTY = "nameProperty"; - @Test void testFullName() { SqlTable table = new SqlTable("my_table"); assertThat(table.tableNameAtRuntime()).isEqualTo("my_table"); } - - @Test - void testFullNameSupplier() { - - System.setProperty(NAME_PROPERTY, "my_table"); - SqlTable table = new SqlTable(SqlTableTest::namePropertyReader); - assertThat(table.tableNameAtRuntime()).isEqualTo("my_table"); - System.clearProperty(NAME_PROPERTY); - } - - @Test - void testSchemaSupplierEmpty() { - SqlTable table = new SqlTable(Optional::empty, "my_table"); - assertThat(table.tableNameAtRuntime()).isEqualTo("my_table"); - } - - @Test - void testSchemaSupplierWithValue() { - SqlTable table = new SqlTable(() -> Optional.of("my_schema"), "my_table"); - assertThat(table.tableNameAtRuntime()).isEqualTo("my_schema.my_table"); - } - - @Test - void testSingletonSchemaSupplier() { - SqlTable table = new SqlTable(MySchemaSupplier.instance(), "my_table"); - assertThat(table.tableNameAtRuntime()).isEqualTo("first_schema.my_table"); - } - - @Test - void testThatSchemaSupplierDoesDelay() { - MySchemaSupplier schemaSupplier = new MySchemaSupplier(); - SqlTable table = new SqlTable(schemaSupplier, "my_table"); - assertThat(table.tableNameAtRuntime()).isEqualTo("first_schema.my_table"); - - schemaSupplier.setFirst(false); - assertThat(table.tableNameAtRuntime()).isEqualTo("second_schema.my_table"); - } - - @Test - void testCatalogAndSchemaSupplierEmpty() { - SqlTable table = new SqlTable(Optional::empty, Optional::empty, "my_table"); - assertThat(table.tableNameAtRuntime()).isEqualTo("my_table"); - } - - @Test - void testCatalogSupplierWithValue() { - SqlTable table = new SqlTable(() -> Optional.of("my_catalog"), Optional::empty, "my_table"); - assertThat(table.tableNameAtRuntime()).isEqualTo("my_catalog..my_table"); - } - - @Test - void testThatCatalogSupplierDoesDelay() { - MyCatalogSupplier catalogSupplier = new MyCatalogSupplier(); - SqlTable table = new SqlTable(catalogSupplier, Optional::empty, "my_table"); - assertThat(table.tableNameAtRuntime()).isEqualTo("first_catalog..my_table"); - - catalogSupplier.setFirst(false); - assertThat(table.tableNameAtRuntime()).isEqualTo("second_catalog..my_table"); - } - - @Test - void testThatCatalogSupplierAndSchemaSupplierBothDelay() { - MyCatalogSupplier catalogSupplier = new MyCatalogSupplier(); - MySchemaSupplier schemaSupplier = new MySchemaSupplier(); - SqlTable table = new SqlTable(catalogSupplier, schemaSupplier, "my_table"); - assertThat(table.tableNameAtRuntime()).isEqualTo("first_catalog.first_schema.my_table"); - - catalogSupplier.setFirst(false); - assertThat(table.tableNameAtRuntime()).isEqualTo("second_catalog.first_schema.my_table"); - - catalogSupplier.setFirst(true); - schemaSupplier.setFirst(false); - assertThat(table.tableNameAtRuntime()).isEqualTo("first_catalog.second_schema.my_table"); - - catalogSupplier.setFirst(false); - assertThat(table.tableNameAtRuntime()).isEqualTo("second_catalog.second_schema.my_table"); - - catalogSupplier.setEmpty(true); - assertThat(table.tableNameAtRuntime()).isEqualTo("second_schema.my_table"); - - schemaSupplier.setEmpty(true); - assertThat(table.tableNameAtRuntime()).isEqualTo("my_table"); - - catalogSupplier.setEmpty(false); - assertThat(table.tableNameAtRuntime()).isEqualTo("second_catalog..my_table"); - } - - private static String namePropertyReader() { - return System.getProperty(NAME_PROPERTY); - } - - static class MySchemaSupplier implements Supplier<Optional<String>> { - private static final MySchemaSupplier instance = new MySchemaSupplier(); - - static MySchemaSupplier instance() { - return instance; - } - - private boolean first = true; - private boolean empty; - - void setFirst(boolean first) { - this.first = first; - } - - void setEmpty(boolean empty) { - this.empty = empty; - } - - @Override - public Optional<String> get() { - if (empty) { - return Optional.empty(); - } - - if (first) { - return Optional.of("first_schema"); - } else { - return Optional.of("second_schema"); - } - } - } - - static class MyCatalogSupplier implements Supplier<Optional<String>> { - private boolean first = true; - private boolean empty; - - void setFirst(boolean first) { - this.first = first; - } - - void setEmpty(boolean empty) { - this.empty = empty; - } - - @Override - public Optional<String> get() { - if (empty) { - return Optional.empty(); - } - - if (first) { - return Optional.of("first_catalog"); - } else { - return Optional.of("second_catalog"); - } - } - } } 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 350532cb2..e0ebe5d19 100644 --- a/src/test/java/org/mybatis/dynamic/sql/insert/InsertStatementTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/insert/InsertStatementTest.java @@ -115,24 +115,6 @@ void testSelectiveInsertStatementBuilder() { assertThat(insertStatement.getInsertStatement()).isEqualTo(expected); } - @Test - void testDeprecatedMethod() { - TestRecord row = new TestRecord(); - row.setLastName("jones"); - row.setOccupation("dino driver"); - - InsertStatementProvider<TestRecord> insertStatement = insert(row) - .into(foo) - .map(id).toPropertyWhenPresent("id", row::getId) - .map(firstName).toPropertyWhenPresent("firstName", row::getFirstName) - .map(lastName).toPropertyWhenPresent("lastName", row::getLastName) - .map(occupation).toPropertyWhenPresent("occupation", row::getOccupation) - .build() - .render(RenderingStrategies.MYBATIS3); - - assertThat(insertStatement.getRow()).isEqualTo(insertStatement.getRecord()); - } - static class TestRecord { private Integer id; private String firstName; From 8582ae1194212977c27bef2e15df113023cae3e2 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 7 Jun 2024 11:23:09 -0400 Subject: [PATCH 011/260] Remove Deprecated Kotlin code --- .../sql/util/kotlin/KotlinBaseBuilders.kt | 34 ---------------- .../mybatis3/canonical/ReusableWhereTest.kt | 40 ------------------- .../kotlin/gh430/KNoInitialConditionsTest.kt | 12 ++++-- 3 files changed, 8 insertions(+), 78 deletions(-) diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt index 2f6bc175b..4207905c6 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt @@ -25,15 +25,6 @@ import org.mybatis.dynamic.sql.where.AbstractWhereStarter @DslMarker annotation class MyBatisDslMarker -@Deprecated("Please use GroupingCriteriaCollector.where") -typealias WhereApplier = KotlinBaseBuilder<*>.() -> Unit - -@Deprecated("Please use GroupingCriteriaCollector.where") -fun WhereApplier.andThen(after: WhereApplier): WhereApplier = { - invoke(this) - after(this) -} - @MyBatisDslMarker @Suppress("TooManyFunctions") abstract class KotlinBaseBuilder<D : AbstractWhereStarter<*,*>> { @@ -51,31 +42,6 @@ abstract class KotlinBaseBuilder<D : AbstractWhereStarter<*,*>> { getDsl().where(criteria) } - @Deprecated("Please move the \"and\" function into the where lambda. If the where lambda has more than one condition, you may need to surround the existing conditions with \"group\" first.") - fun and(criteria: GroupingCriteriaReceiver): Unit = - GroupingCriteriaCollector().apply(criteria).let { - getDsl().where().and(it.initialCriterion, it.subCriteria) - } - - @Deprecated("Please move the \"and\" function into the where lambda. If the where lambda has more than one condition, you may need to surround the existing conditions with \"group\" first.") - fun and(criteria: List<AndOrCriteriaGroup>) { - getDsl().where().and(criteria) - } - - @Deprecated("Please move the \"or\" function into the where lambda. If the where lambda has more than one condition, you may need to surround the existing conditions with \"group\" first.") - fun or(criteria: GroupingCriteriaReceiver): Unit = - GroupingCriteriaCollector().apply(criteria).let { - getDsl().where().or(it.initialCriterion, it.subCriteria) - } - - @Deprecated("Please move the \"or\" function into the where lambda. If the where lambda has more than one condition, you may need to surround the existing conditions with \"group\" first.") - fun or(criteria: List<AndOrCriteriaGroup>) { - getDsl().where().or(criteria) - } - - @Deprecated("Please use GroupingCriteriaCollector.where, then pass it to the \"where\" method") - fun applyWhere(whereApplier: WhereApplier) = whereApplier.invoke(this) - /** * This function does nothing, but it can be used to make some code snippets more understandable. * diff --git a/src/test/kotlin/examples/kotlin/mybatis3/canonical/ReusableWhereTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/ReusableWhereTest.kt index 7feca7e63..db54364e7 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/ReusableWhereTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/ReusableWhereTest.kt @@ -27,7 +27,6 @@ import org.junit.jupiter.api.BeforeAll import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.mybatis.dynamic.sql.util.kotlin.GroupingCriteriaCollector.Companion.where -import org.mybatis.dynamic.sql.util.kotlin.WhereApplier import org.mybatis.dynamic.sql.util.kotlin.andThen import org.mybatis.dynamic.sql.util.kotlin.mybatis3.select @@ -44,19 +43,6 @@ class ReusableWhereTest { } } - @Test - fun testCountWithDeprecatedClause() { - sqlSessionFactory.openSession().use { session -> - val mapper = session.getMapper(PersonMapper::class.java) - - val rows = mapper.count { - applyWhere(commonWhere) - } - - assertThat(rows).isEqualTo(3) - } - } - @Test fun testDelete() { sqlSessionFactory.openSession().use { session -> @@ -98,27 +84,6 @@ class ReusableWhereTest { } } - @Test - fun testDeprecatedComposition() { - val composedWhereClause = commonWhere.andThen { - and { birthDate.isNotNull() } - }.andThen { - or { addressId isLessThan 3 } - } - - val selectStatement = select(person.allColumns()) { - from(person) - applyWhere(composedWhereClause) - } - - assertThat(selectStatement.selectStatement).isEqualTo( - "select * from Person " + - "where id = #{parameters.p1,jdbcType=INTEGER} or occupation is null " + - "and birth_date is not null " + - "or address_id < #{parameters.p2,jdbcType=INTEGER}" - ) - } - @Test fun testComposition() { val composedWhereClause = commonWhereClause.andThen { @@ -140,11 +105,6 @@ class ReusableWhereTest { ) } - private val commonWhere: WhereApplier = { - where { id isEqualTo 1 } - or { occupation.isNull() } - } - private val commonWhereClause = where { id isEqualTo 1 or { occupation.isNull() } diff --git a/src/test/kotlin/issues/kotlin/gh430/KNoInitialConditionsTest.kt b/src/test/kotlin/issues/kotlin/gh430/KNoInitialConditionsTest.kt index 0f78c6d13..b11b4f3aa 100644 --- a/src/test/kotlin/issues/kotlin/gh430/KNoInitialConditionsTest.kt +++ b/src/test/kotlin/issues/kotlin/gh430/KNoInitialConditionsTest.kt @@ -175,8 +175,10 @@ class KNoInitialConditionsTest { val selectStatement = select(column1, column2) { from(foo) - where { column1 isLessThan Date() } - or(criteria) + where { + column1 isLessThan Date() + or(criteria) + } } val expected = "select column1, column2 from foo where column1 < :p1 " + @@ -187,7 +189,9 @@ class KNoInitialConditionsTest { private fun buildSelectStatement(criteria: List<AndOrCriteriaGroup>) = select(column1, column2) { from(foo) - where { column1 isLessThan Date() } - and(criteria) + where { + column1 isLessThan Date() + and(criteria) + } } } From bc27cfb062dc8296c9e8deac63f6edf8f6b25bf5 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 7 Jun 2024 11:25:33 -0400 Subject: [PATCH 012/260] Remove Deprecated Kotlin code --- .../examples/kotlin/mybatis3/canonical/PersonMapperTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperTest.kt index 8276ebe9c..5dc24ede2 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperTest.kt @@ -242,7 +242,7 @@ class PersonMapperTest { } @Test - fun testInsertSelect() { + fun testInsertSelectExtensionFunction() { sqlSessionFactory.openSession().use { session -> val mapper = session.getMapper(PersonMapper::class.java) @@ -259,7 +259,7 @@ class PersonMapperTest { } @Test - fun testDeprecatedInsertSelect() { + fun testInsertSelect() { sqlSessionFactory.openSession().use { session -> val mapper = session.getMapper(PersonMapper::class.java) From 414f98de650392689f927632b4013fb8698bce61 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 7 Jun 2024 11:46:36 -0400 Subject: [PATCH 013/260] Remove Unused Method --- .../org/mybatis/dynamic/sql/render/RenderingContext.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java b/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java index a23c8d07a..8a5d1cf5e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java @@ -53,11 +53,6 @@ private RenderingContext(Builder builder) { : builder.parameterName + "." + RenderingStrategy.DEFAULT_PARAMETER_PREFIX; //$NON-NLS-1$ } - public TableAliasCalculator tableAliasCalculator() { - // this method can be removed when the renderWithTableAlias method is removed from BasicColumn - return tableAliasCalculator; - } - private String nextMapKey() { return renderingStrategy.formatParameterMapKey(sequence); } From 8deb494b48463117ec428237e6a72c8951f1c491 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 7 Jun 2024 13:54:38 -0400 Subject: [PATCH 014/260] Simplify SqlTable --- .../java/org/mybatis/dynamic/sql/AliasableSqlTable.java | 4 ++-- src/main/java/org/mybatis/dynamic/sql/SqlTable.java | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/AliasableSqlTable.java b/src/main/java/org/mybatis/dynamic/sql/AliasableSqlTable.java index 4e6c32386..7474b00ba 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AliasableSqlTable.java +++ b/src/main/java/org/mybatis/dynamic/sql/AliasableSqlTable.java @@ -32,7 +32,7 @@ protected AliasableSqlTable(String tableName, Supplier<T> constructor) { public T withAlias(String alias) { T newTable = constructor.get(); ((AliasableSqlTable<T>) newTable).tableAlias = alias; - newTable.nameSupplier = nameSupplier; + newTable.tableName = tableName; return newTable; } @@ -48,7 +48,7 @@ public T withName(String name) { Objects.requireNonNull(name); T newTable = constructor.get(); ((AliasableSqlTable<T>) newTable).tableAlias = tableAlias; - newTable.nameSupplier = () -> name; + newTable.tableName = name; return newTable; } diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlTable.java b/src/main/java/org/mybatis/dynamic/sql/SqlTable.java index 1322d958f..c482458d9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlTable.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlTable.java @@ -18,22 +18,19 @@ import java.sql.JDBCType; import java.util.Objects; import java.util.Optional; -import java.util.function.Supplier; import org.jetbrains.annotations.NotNull; public class SqlTable implements TableExpression { - protected Supplier<String> nameSupplier; + protected String tableName; protected SqlTable(String tableName) { - Objects.requireNonNull(tableName); - - this.nameSupplier = () -> tableName; + this.tableName = Objects.requireNonNull(tableName); } public String tableNameAtRuntime() { - return nameSupplier.get(); + return tableName; } public BasicColumn allColumns() { From 471ca84f06bbdd9837d11b5f8868d7e96d31415a Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 7 Jun 2024 13:58:50 -0400 Subject: [PATCH 015/260] Obsolete Message --- .../resources/org/mybatis/dynamic/sql/util/messages.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties index 9927dbeec..c25eb02c5 100644 --- a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties +++ b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties @@ -52,7 +52,7 @@ ERROR.33=Calling "select" or "selectDistinct" more than once is not allowed. Add union or unionAll expression ERROR.34=You must specify "select" or "selectDistinct" before any other clauses in a multi-select statement ERROR.35=Multi-select statements must have at least one "union" or "union all" expression -ERROR.36=You must either implement the "render" or "renderWithTableAlias" method in a column or function +ERROR.36=Obsolete Message - Not Used ERROR.37=The "{0}" function does not support conditions that fail to render ERROR.38=Bound values cannot be aliased ERROR.39=When clauses in case expressions must render From 2ab30ded4f5b0e4210a40e5d820453a5694e0e15 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 13 Jun 2024 14:10:33 +0000 Subject: [PATCH 016/260] Update dependency org.springframework:spring-jdbc to v6.1.9 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8dc86be10..a37a79ec8 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,7 @@ <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> - <version>6.1.8</version> + <version>6.1.9</version> <scope>provided</scope> <optional>true</optional> </dependency> From f6361ec73c0739fc0abb2a2b8d6da66110cd59a5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 10:37:18 +0000 Subject: [PATCH 017/260] Update dependency maven to v3.9.8 --- .mvn/wrapper/maven-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index 34d543889..bceca511d 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -15,5 +15,5 @@ # specific language governing permissions and limitations # under the License. wrapperVersion=3.3.1 -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.7/apache-maven-3.9.7-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.1/maven-wrapper-3.3.1.jar From b90a1ff24d6998085fe3a0fa92f00bb34df1bf6f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 19 Jun 2024 18:28:41 +0000 Subject: [PATCH 018/260] Update dependency org.springframework:spring-jdbc to v6.1.10 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a37a79ec8..6aedfc031 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,7 @@ <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> - <version>6.1.9</version> + <version>6.1.10</version> <scope>provided</scope> <optional>true</optional> </dependency> From ced7fcd228d7264a17d485717455bf1743a94d29 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 20 Jun 2024 09:25:46 -0400 Subject: [PATCH 019/260] Remove Obsolete Test --- .../org/mybatis/dynamic/sql/SqlTableTest.java | 29 ------------------- 1 file changed, 29 deletions(-) delete mode 100644 src/test/java/org/mybatis/dynamic/sql/SqlTableTest.java diff --git a/src/test/java/org/mybatis/dynamic/sql/SqlTableTest.java b/src/test/java/org/mybatis/dynamic/sql/SqlTableTest.java deleted file mode 100644 index 473258dcb..000000000 --- a/src/test/java/org/mybatis/dynamic/sql/SqlTableTest.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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 org.junit.jupiter.api.Test; - -class SqlTableTest { - - @Test - void testFullName() { - SqlTable table = new SqlTable("my_table"); - assertThat(table.tableNameAtRuntime()).isEqualTo("my_table"); - } -} From 8e18992327610bb4caaf8b17260a77b649aae97f Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 20 Jun 2024 09:34:58 -0400 Subject: [PATCH 020/260] Better method name --- src/main/java/org/mybatis/dynamic/sql/SqlTable.java | 2 +- .../dynamic/sql/exception/DuplicateTableAliasException.java | 2 +- .../dynamic/sql/insert/render/InsertRenderingUtilities.java | 2 +- .../dynamic/sql/render/GuaranteedTableAliasCalculator.java | 2 +- .../java/org/mybatis/dynamic/sql/render/RenderingContext.java | 4 ++-- src/test/java/examples/joins/JoinMapperTest.java | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlTable.java b/src/main/java/org/mybatis/dynamic/sql/SqlTable.java index c482458d9..40b6ccf17 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlTable.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlTable.java @@ -29,7 +29,7 @@ protected SqlTable(String tableName) { this.tableName = Objects.requireNonNull(tableName); } - public String tableNameAtRuntime() { + public String tableName() { return tableName; } diff --git a/src/main/java/org/mybatis/dynamic/sql/exception/DuplicateTableAliasException.java b/src/main/java/org/mybatis/dynamic/sql/exception/DuplicateTableAliasException.java index d32e66e5e..ee8c1e2d1 100644 --- a/src/main/java/org/mybatis/dynamic/sql/exception/DuplicateTableAliasException.java +++ b/src/main/java/org/mybatis/dynamic/sql/exception/DuplicateTableAliasException.java @@ -43,6 +43,6 @@ public DuplicateTableAliasException(SqlTable table, String newAlias, String exis } private static String generateMessage(SqlTable table, String newAlias, String existingAlias) { - return Messages.getString("ERROR.1", table.tableNameAtRuntime(), newAlias, existingAlias); //$NON-NLS-1$ + return Messages.getString("ERROR.1", table.tableName(), newAlias, existingAlias); //$NON-NLS-1$ } } diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertRenderingUtilities.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertRenderingUtilities.java index 31bbf02ed..e22143109 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertRenderingUtilities.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertRenderingUtilities.java @@ -31,6 +31,6 @@ public static String calculateInsertStatement(SqlTable table, FieldAndValueColle } public static String calculateInsertStatementStart(SqlTable table) { - return "insert into " + table.tableNameAtRuntime(); //$NON-NLS-1$ + return "insert into " + table.tableName(); //$NON-NLS-1$ } } 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 59948b03f..4d4a3b883 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/GuaranteedTableAliasCalculator.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/GuaranteedTableAliasCalculator.java @@ -38,7 +38,7 @@ public Optional<String> aliasForColumn(SqlTable table) { if (alias.isPresent()) { return alias; } else { - return Optional.of(table.tableNameAtRuntime()); + return Optional.of(table.tableName()); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java b/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java index 8a5d1cf5e..bc953f847 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java @@ -88,8 +88,8 @@ public <T> String aliasedColumnName(SqlColumn<T> column, String explicitAlias) { public String aliasedTableName(SqlTable table) { return tableAliasCalculator.aliasForTable(table) - .map(a -> table.tableNameAtRuntime() + spaceBefore(a)) - .orElseGet(table::tableNameAtRuntime); + .map(a -> table.tableName() + spaceBefore(a)) + .orElseGet(table::tableName); } public boolean isNonRenderingClauseAllowed() { diff --git a/src/test/java/examples/joins/JoinMapperTest.java b/src/test/java/examples/joins/JoinMapperTest.java index e84571231..50c8e30f5 100644 --- a/src/test/java/examples/joins/JoinMapperTest.java +++ b/src/test/java/examples/joins/JoinMapperTest.java @@ -957,7 +957,7 @@ void testSelfWithDuplicateAlias() { .from(user, "u1"); assertThatExceptionOfType(DuplicateTableAliasException.class).isThrownBy(() -> dsl.join(user, "u2")) - .withMessage(Messages.getString("ERROR.1", user.tableNameAtRuntime(), "u2", "u1")); + .withMessage(Messages.getString("ERROR.1", user.tableName(), "u2", "u1")); } @Test From 51311e07ecbf3c2b56419a473b4c8c194e574293 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 24 Jun 2024 11:18:22 -0400 Subject: [PATCH 021/260] Update error locations for K2 compiler --- .../kotlin/nullability/test/ComparisonTest.kt | 24 +++++++++---------- .../nullability/test/EqualNotEqualTest.kt | 8 +++---- src/test/kotlin/nullability/test/InTest.kt | 2 +- src/test/kotlin/nullability/test/NotInTest.kt | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/test/kotlin/nullability/test/ComparisonTest.kt b/src/test/kotlin/nullability/test/ComparisonTest.kt index ebd25607f..0df088eb2 100644 --- a/src/test/kotlin/nullability/test/ComparisonTest.kt +++ b/src/test/kotlin/nullability/test/ComparisonTest.kt @@ -38,7 +38,7 @@ class ComparisonTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(9, 30)) + .contains(ErrorLocation(9, 20)) } @Test @@ -81,7 +81,7 @@ class ComparisonTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(10, 31)) + .contains(ErrorLocation(10, 21)) } @Test @@ -124,7 +124,7 @@ class ComparisonTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(9, 33)) + .contains(ErrorLocation(9, 20)) } @Test @@ -167,7 +167,7 @@ class ComparisonTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(10, 34)) + .contains(ErrorLocation(10, 21)) } @Test @@ -210,7 +210,7 @@ class ComparisonTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(9, 34)) + .contains(ErrorLocation(9, 20)) } @Test @@ -253,7 +253,7 @@ class ComparisonTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(10, 35)) + .contains(ErrorLocation(10, 21)) } @Test @@ -296,7 +296,7 @@ class ComparisonTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(9, 43)) + .contains(ErrorLocation(9, 20)) } @Test @@ -339,7 +339,7 @@ class ComparisonTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(10, 44)) + .contains(ErrorLocation(10, 21)) } @Test @@ -382,7 +382,7 @@ class ComparisonTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(9, 31)) + .contains(ErrorLocation(9, 20)) } @Test @@ -425,7 +425,7 @@ class ComparisonTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(10, 32)) + .contains(ErrorLocation(10, 21)) } @Test @@ -468,7 +468,7 @@ class ComparisonTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(9, 40)) + .contains(ErrorLocation(9, 20)) } @Test @@ -511,7 +511,7 @@ class ComparisonTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(10, 41)) + .contains(ErrorLocation(10, 21)) } @Test diff --git a/src/test/kotlin/nullability/test/EqualNotEqualTest.kt b/src/test/kotlin/nullability/test/EqualNotEqualTest.kt index d1f475d69..70fd7c242 100644 --- a/src/test/kotlin/nullability/test/EqualNotEqualTest.kt +++ b/src/test/kotlin/nullability/test/EqualNotEqualTest.kt @@ -38,7 +38,7 @@ class EqualNotEqualTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(9, 37)) + .contains(ErrorLocation(9, 27)) } @Test @@ -81,7 +81,7 @@ class EqualNotEqualTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(10, 40)) + .contains(ErrorLocation(10, 27)) } @Test @@ -124,7 +124,7 @@ class EqualNotEqualTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(10, 38)) + .contains(ErrorLocation(10, 28)) } @Test @@ -169,7 +169,7 @@ class EqualNotEqualTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(11, 41)) + .contains(ErrorLocation(11, 28)) } @Test diff --git a/src/test/kotlin/nullability/test/InTest.kt b/src/test/kotlin/nullability/test/InTest.kt index 23fa9e784..4ea242830 100644 --- a/src/test/kotlin/nullability/test/InTest.kt +++ b/src/test/kotlin/nullability/test/InTest.kt @@ -108,6 +108,6 @@ class InTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(11, 26)) + .contains(ErrorLocation(11, 21)) } } diff --git a/src/test/kotlin/nullability/test/NotInTest.kt b/src/test/kotlin/nullability/test/NotInTest.kt index f88356c26..adbcf21bf 100644 --- a/src/test/kotlin/nullability/test/NotInTest.kt +++ b/src/test/kotlin/nullability/test/NotInTest.kt @@ -108,6 +108,6 @@ class NotInTest { val compilerMessageCollector = compile(source) assertThat(compilerMessageCollector.errorLocations()) .hasSize(1) -// TODO .contains(ErrorLocation(11, 29)) + .contains(ErrorLocation(11, 21)) } } From 5b03ef0ec32cc68c4133383d55326c44f76e9593 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Jun 2024 15:55:05 +0000 Subject: [PATCH 022/260] Update junit5 monorepo to v5.10.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6aedfc031..d16979e76 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ <properties> <java.version>17</java.version> <java.release.version>8</java.release.version> - <junit.jupiter.version>5.10.2</junit.jupiter.version> + <junit.jupiter.version>5.10.3</junit.jupiter.version> <spring.batch.version>5.1.2</spring.batch.version> <checkstyle.config>checkstyle-override.xml</checkstyle.config> From 869c584ea5ff5909f28181037b26188dadc60e32 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 5 Jul 2024 16:41:27 +0000 Subject: [PATCH 023/260] Update JamesIves/github-pages-deploy-action action to v4.6.3 --- .github/workflows/site.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/site.yaml b/.github/workflows/site.yaml index 746afc0ec..11eb6ac73 100644 --- a/.github/workflows/site.yaml +++ b/.github/workflows/site.yaml @@ -25,7 +25,7 @@ jobs: CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Deploy Site to gh-pages - uses: JamesIves/github-pages-deploy-action@v4.6.1 + uses: JamesIves/github-pages-deploy-action@v4.6.3 with: ssh-key: true branch: gh-pages From 48ff191897e53cc4d502767f4ba5b377cb808cb3 Mon Sep 17 00:00:00 2001 From: Jeremy Landis <jeremylandis@hotmail.com> Date: Sat, 6 Jul 2024 13:22:26 -0400 Subject: [PATCH 024/260] [mvn] Update maven wrapper --- .mvn/wrapper/MavenWrapperDownloader.java | 2 +- .mvn/wrapper/maven-wrapper.properties | 5 +++-- mvnw | 6 +++--- mvnw.cmd | 6 +++--- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java index f6cb0fa0b..bdf0ddfa6 100644 --- a/.mvn/wrapper/MavenWrapperDownloader.java +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -30,7 +30,7 @@ import java.util.concurrent.ThreadLocalRandom; public final class MavenWrapperDownloader { - private static final String WRAPPER_VERSION = "3.3.1"; + private static final String WRAPPER_VERSION = "3.3.2"; private static final boolean VERBOSE = Boolean.parseBoolean(System.getenv("MVNW_VERBOSE")); diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index bceca511d..fd5166374 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -14,6 +14,7 @@ # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. -wrapperVersion=3.3.1 +wrapperVersion=3.3.2 +distributionType=source distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.1/maven-wrapper-3.3.1.jar +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar diff --git a/mvnw b/mvnw index b21a698ee..668388825 100755 --- a/mvnw +++ b/mvnw @@ -19,7 +19,7 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Apache Maven Wrapper startup batch script, version 3.3.1 +# Apache Maven Wrapper startup batch script, version 3.3.2 # # Required ENV vars: # ------------------ @@ -212,9 +212,9 @@ else log "Couldn't find $wrapperJarPath, downloading it ..." if [ -n "$MVNW_REPOURL" ]; then - wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.3.1/maven-wrapper-3.3.1.jar" + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar" else - wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.1/maven-wrapper-3.3.1.jar" + wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar" fi while IFS="=" read -r key value; do # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) diff --git a/mvnw.cmd b/mvnw.cmd index f93f29a8e..da4fe4dd9 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -18,7 +18,7 @@ @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- -@REM Apache Maven Wrapper startup batch script, version 3.3.1 +@REM Apache Maven Wrapper startup batch script, version 3.3.2 @REM @REM Required ENV vars: @REM JAVA_HOME - location of a JDK home dir @@ -119,7 +119,7 @@ SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain -set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.1/maven-wrapper-3.3.1.jar" +set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar" FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B @@ -133,7 +133,7 @@ if exist %WRAPPER_JAR% ( ) ) else ( if not "%MVNW_REPOURL%" == "" ( - SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.3.1/maven-wrapper-3.3.1.jar" + SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar" ) if "%MVNW_VERBOSE%" == "true" ( echo Couldn't find %WRAPPER_JAR%, downloading it ... From 14c8f6f6dc9a43d09b016f8004230c015598edff Mon Sep 17 00:00:00 2001 From: Jeremy Landis <jeremylandis@hotmail.com> Date: Sat, 6 Jul 2024 13:24:08 -0400 Subject: [PATCH 025/260] [GHA] Update github actions --- .github/workflows/ci.yaml | 8 +++++--- .github/workflows/coveralls.yaml | 3 ++- .github/workflows/site.yaml | 15 ++++++--------- .github/workflows/sonar.yaml | 5 +++-- .github/workflows/sonatype.yaml | 3 ++- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 43119e8b4..d5a23da97 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -7,9 +7,10 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [ubuntu-latest] - java: [17, 21, 22-ea] - distribution: ['temurin'] + cache: [maven] + distribution: [temurin] + java: [17, 21, 22, 23-ea] + os: [ubuntu-latest, macos-latest, windows-latest] fail-fast: false max-parallel: 4 name: Test JDK ${{ matrix.java }}, ${{ matrix.os }} @@ -21,5 +22,6 @@ jobs: with: java-version: ${{ matrix.java }} distribution: ${{ matrix.distribution }} + cache: ${{ matrix.cache }} - name: Test with Maven run: ./mvnw test -B -V --no-transfer-progress -D"license.skip=true" diff --git a/.github/workflows/coveralls.yaml b/.github/workflows/coveralls.yaml index a898e3793..270a6c85b 100644 --- a/.github/workflows/coveralls.yaml +++ b/.github/workflows/coveralls.yaml @@ -11,8 +11,9 @@ jobs: - name: Set up JDK uses: actions/setup-java@v4 with: + cache: maven + distribution: temurin java-version: 21 - distribution: zulu - name: Report Coverage to Coveralls for Pull Requests if: github.event_name == 'pull_request' run: ./mvnw -B -V test jacoco:report coveralls:report -q -Dlicense.skip=true -DrepoToken=$GITHUB_TOKEN -DserviceName=github -DpullRequest=$PR_NUMBER --no-transfer-progress diff --git a/.github/workflows/site.yaml b/.github/workflows/site.yaml index 11eb6ac73..5d6998019 100644 --- a/.github/workflows/site.yaml +++ b/.github/workflows/site.yaml @@ -14,21 +14,18 @@ jobs: - name: Set up JDK uses: actions/setup-java@v4 with: + cache: maven + distribution: temurin java-version: 21 - distribution: zulu - - uses: webfactory/ssh-agent@master - with: - ssh-private-key: ${{ secrets.DEPLOY_KEY }} - name: Build site - run: ./mvnw site site:stage -DskipTests -B -V --no-transfer-progress -Dlicense.skip=true + run: ./mvnw site site:stage -DskipTests -Dlicense.skip=true -B -V --no-transfer-progress --settings ./.mvn/settings.xml env: CI_DEPLOY_USERNAME: ${{ secrets.CI_DEPLOY_USERNAME }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NVD_API_KEY: ${{ secrets.NVD_API_KEY }} - name: Deploy Site to gh-pages - uses: JamesIves/github-pages-deploy-action@v4.6.3 + uses: JamesIves/github-pages-deploy-action@v4 with: - ssh-key: true branch: gh-pages folder: target/staging - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ssh-key: ${{ secrets.DEPLOY_KEY }} diff --git a/.github/workflows/sonar.yaml b/.github/workflows/sonar.yaml index e4bf41ac8..293c0e4ad 100644 --- a/.github/workflows/sonar.yaml +++ b/.github/workflows/sonar.yaml @@ -17,10 +17,11 @@ jobs: - name: Set up JDK uses: actions/setup-java@v4 with: + cache: maven + distribution: temurin java-version: 21 - distribution: zulu - name: Analyze with SonarCloud - run: ./mvnw verify jacoco:report sonar:sonar -B -Dsonar.projectKey=mybatis_mybatis-dynamic-sql -Dsonar.organization=mybatis -Dsonar.host.url=https://sonarcloud.io -Dsonar.token=$SONAR_TOKEN -Dlicense.skip=true --no-transfer-progress + run: ./mvnw verify jacoco:report sonar:sonar -B -V -Dsonar.projectKey=mybatis_mybatis-dynamic-sql -Dsonar.organization=mybatis -Dsonar.host.url=https://sonarcloud.io -Dsonar.token=$SONAR_TOKEN -Dlicense.skip=true --no-transfer-progress env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/.github/workflows/sonatype.yaml b/.github/workflows/sonatype.yaml index 72086bc1d..494bb2f4c 100644 --- a/.github/workflows/sonatype.yaml +++ b/.github/workflows/sonatype.yaml @@ -14,8 +14,9 @@ jobs: - name: Set up JDK uses: actions/setup-java@v4 with: + cache: maven + distribution: temurin java-version: 21 - distribution: zulu - name: Deploy to Sonatype run: ./mvnw deploy -DskipTests -B -V --no-transfer-progress --settings ./.mvn/settings.xml -Dlicense.skip=true env: From 5669e5d075281b4f0d4ff71bd392fb67bfdac2ed Mon Sep 17 00:00:00 2001 From: Jeremy Landis <jeremylandis@hotmail.com> Date: Sat, 6 Jul 2024 13:28:41 -0400 Subject: [PATCH 026/260] [GHA] Run on ubuntu only again --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d5a23da97..5a6947c02 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -10,7 +10,7 @@ jobs: cache: [maven] distribution: [temurin] java: [17, 21, 22, 23-ea] - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-latest] fail-fast: false max-parallel: 4 name: Test JDK ${{ matrix.java }}, ${{ matrix.os }} From 325a9e58e46ee46c17d65a78a7fabd405dfe840f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 9 Jul 2024 18:24:21 +0000 Subject: [PATCH 027/260] Update dependency org.assertj:assertj-core to v3.26.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d16979e76..2e52b8ca9 100644 --- a/pom.xml +++ b/pom.xml @@ -125,7 +125,7 @@ <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> - <version>3.26.0</version> + <version>3.26.3</version> <scope>test</scope> </dependency> <dependency> From 1bbe16a79df8f08c7967f87b13c4ba3f972301e4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 11 Jul 2024 10:29:33 +0000 Subject: [PATCH 028/260] Update dependency org.springframework:spring-jdbc to v6.1.11 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2e52b8ca9..34c3d1ef8 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,7 @@ <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> - <version>6.1.10</version> + <version>6.1.11</version> <scope>provided</scope> <optional>true</optional> </dependency> From 5652077273bcea7e7b51cb08f24bf5b2989f560e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jul 2024 15:40:07 +0000 Subject: [PATCH 029/260] Update dependency org.mariadb.jdbc:mariadb-java-client to v3.4.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 34c3d1ef8..8205dbbe7 100644 --- a/pom.xml +++ b/pom.xml @@ -199,7 +199,7 @@ <dependency> <groupId>org.mariadb.jdbc</groupId> <artifactId>mariadb-java-client</artifactId> - <version>3.4.0</version> + <version>3.4.1</version> <scope>test</scope> </dependency> </dependencies> From 62992bad171c4334eed4145144f6882538686375 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 17 Jul 2024 15:40:12 +0000 Subject: [PATCH 030/260] Update dependency org.testcontainers:mariadb to v1.20.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 34c3d1ef8..1eab6c049 100644 --- a/pom.xml +++ b/pom.xml @@ -74,7 +74,7 @@ <sonar.tests>src/test/java,src/test/kotlin</sonar.tests> <kotlin.code.style>official</kotlin.code.style> - <test.containers.version>1.19.8</test.containers.version> + <test.containers.version>1.20.0</test.containers.version> <osgi.export>org.mybatis.dynamic.sql.*;version=${project.version};-noimport:=true</osgi.export> <!-- Reproducible Builds --> From 0e54dace33c05cbe2eb8a0d0e504e75bcfb8a970 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 31 Jul 2024 19:14:03 +0000 Subject: [PATCH 031/260] Update testcontainers-java monorepo to v1.20.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 332f928f0..b72e92fd4 100644 --- a/pom.xml +++ b/pom.xml @@ -74,7 +74,7 @@ <sonar.tests>src/test/java,src/test/kotlin</sonar.tests> <kotlin.code.style>official</kotlin.code.style> - <test.containers.version>1.20.0</test.containers.version> + <test.containers.version>1.20.1</test.containers.version> <osgi.export>org.mybatis.dynamic.sql.*;version=${project.version};-noimport:=true</osgi.export> <!-- Reproducible Builds --> From aa8d486355d14813545988976e720e7b5b713a99 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 1 Aug 2024 12:56:15 +0000 Subject: [PATCH 032/260] Update dependency org.hamcrest:hamcrest to v3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b72e92fd4..24b549daa 100644 --- a/pom.xml +++ b/pom.xml @@ -168,7 +168,7 @@ <dependency> <groupId>org.hamcrest</groupId> <artifactId>hamcrest</artifactId> - <version>2.2</version> + <version>3.0</version> <scope>test</scope> </dependency> From cd452ac502d55d082c267f5ea511628a929937ca Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 1 Aug 2024 11:04:22 -0400 Subject: [PATCH 033/260] Shim in a more general render method for sort specification --- .../dynamic/sql/SortSpecification.java | 29 +++++++++++++++++-- .../org/mybatis/dynamic/sql/SqlColumn.java | 23 ++++++--------- .../dynamic/sql/common/OrderByRenderer.java | 24 +++++++-------- .../sql/delete/render/DeleteRenderer.java | 2 +- .../sql/select/ColumnSortSpecification.java | 21 ++++++-------- .../sql/select/SimpleSortSpecification.java | 21 ++++++-------- .../select/render/MultiSelectRenderer.java | 2 +- .../sql/select/render/SelectRenderer.java | 2 +- .../sql/update/render/UpdateRenderer.java | 2 +- .../dynamic/sql/util/messages.properties | 4 ++- 10 files changed, 73 insertions(+), 57 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java b/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java index a17557017..85f9f5288 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java +++ b/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java @@ -15,6 +15,11 @@ */ package org.mybatis.dynamic.sql; +import org.mybatis.dynamic.sql.exception.DynamicSqlException; +import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; +import org.mybatis.dynamic.sql.util.Messages; + /** * Defines attributes of columns that are necessary for rendering an order by expression. * @@ -34,13 +39,33 @@ public interface SortSpecification { * NOT include the "DESC" word for descending sort specifications. * * @return the order by phrase + * @deprecated Please replace this method by overriding the more general "renderForOrderBy" method. Target for + * removal in release 2.1 */ - String orderByName(); + @Deprecated + default String orderByName() { + throw new DynamicSqlException(Messages.getString("ERROR.44")); //$NON-NLS-1$ + } /** * Return true if the sort order is descending. * * @return true if the SortSpecification should render as descending + * @deprecated Please replace this method by overriding the more general "renderForOrderBy" method. Target for + * removal in release 2.1 */ - boolean isDescending(); + @Deprecated + default boolean isDescending() { + throw new DynamicSqlException(Messages.getString("ERROR.44")); //$NON-NLS-1$ + } + + // the default implementation ensures compatibility with prior releases. When the + // deprecated methods are removed, this function can become purely abstract. + default FragmentAndParameters renderForOrderBy(RenderingContext renderingContext) { + String phrase = orderByName(); + if (isDescending()) { + phrase = phrase + " DESC"; //$NON-NLS-1$ + } + return FragmentAndParameters.fromFragment(phrase); + } } diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java b/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java index 76f40e15c..0c8475d33 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java @@ -30,7 +30,7 @@ public class SqlColumn<T> implements BindableColumn<T>, SortSpecification { protected final String name; protected final SqlTable table; protected final JDBCType jdbcType; - protected final boolean isDescending; + protected final String descendingPhrase; protected final String alias; protected final String typeHandler; protected final RenderingStrategy renderingStrategy; @@ -42,7 +42,7 @@ private SqlColumn(Builder<T> builder) { name = Objects.requireNonNull(builder.name); table = Objects.requireNonNull(builder.table); jdbcType = builder.jdbcType; - isDescending = builder.isDescending; + descendingPhrase = builder.descendingPhrase; alias = builder.alias; typeHandler = builder.typeHandler; renderingStrategy = builder.renderingStrategy; @@ -87,7 +87,7 @@ public Object convertParameterType(T value) { @Override public SortSpecification descending() { Builder<T> b = copy(); - return b.withDescending(true).build(); + return b.withDescendingPhrase(" DESC").build(); //$NON-NLS-1$ } @Override @@ -126,13 +126,8 @@ public SqlColumn<T> asCamelCase() { } @Override - public boolean isDescending() { - return isDescending; - } - - @Override - public String orderByName() { - return alias().orElse(name); + public FragmentAndParameters renderForOrderBy(RenderingContext renderingContext) { + return FragmentAndParameters.fromFragment(alias().orElse(name) + descendingPhrase); } @Override @@ -188,7 +183,7 @@ private <S> Builder<S> copy() { .withName(this.name) .withTable(this.table) .withJdbcType(this.jdbcType) - .withDescending(this.isDescending) + .withDescendingPhrase(this.descendingPhrase) .withAlias(this.alias) .withTypeHandler(this.typeHandler) .withRenderingStrategy(this.renderingStrategy) @@ -214,7 +209,7 @@ public static class Builder<T> { protected String name; protected SqlTable table; protected JDBCType jdbcType; - protected boolean isDescending = false; + protected String descendingPhrase = ""; //$NON-NLS-1$ protected String alias; protected String typeHandler; protected RenderingStrategy renderingStrategy; @@ -237,8 +232,8 @@ public Builder<T> withJdbcType(JDBCType jdbcType) { return this; } - public Builder<T> withDescending(boolean isDescending) { - this.isDescending = isDescending; + public Builder<T> withDescendingPhrase(String descendingPhrase) { + this.descendingPhrase = descendingPhrase; return this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/common/OrderByRenderer.java b/src/main/java/org/mybatis/dynamic/sql/common/OrderByRenderer.java index f1a28ed4e..206c1a297 100644 --- a/src/main/java/org/mybatis/dynamic/sql/common/OrderByRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/common/OrderByRenderer.java @@ -15,24 +15,24 @@ */ package org.mybatis.dynamic.sql.common; +import java.util.Objects; import java.util.stream.Collectors; -import org.mybatis.dynamic.sql.SortSpecification; +import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; +import org.mybatis.dynamic.sql.util.FragmentCollector; public class OrderByRenderer { - public FragmentAndParameters render(OrderByModel orderByModel) { - String phrase = orderByModel.columns() - .map(this::calculateOrderByPhrase) - .collect(Collectors.joining(", ", "order by ", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - return FragmentAndParameters.fromFragment(phrase); + private final RenderingContext renderingContext; + + public OrderByRenderer(RenderingContext renderingContext) { + this.renderingContext = Objects.requireNonNull(renderingContext); } - private String calculateOrderByPhrase(SortSpecification column) { - String phrase = column.orderByName(); - if (column.isDescending()) { - phrase = phrase + " DESC"; //$NON-NLS-1$ - } - return phrase; + public FragmentAndParameters render(OrderByModel orderByModel) { + return orderByModel.columns().map(c -> c.renderForOrderBy(renderingContext)) + .collect(FragmentCollector.collect()) + .toFragmentAndParameters( + Collectors.joining(", ", "order by ", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } 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 ce46c4c10..8a9c945d4 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 @@ -96,7 +96,7 @@ private Optional<FragmentAndParameters> calculateOrderByClause() { } private FragmentAndParameters renderOrderByClause(OrderByModel orderByModel) { - return new OrderByRenderer().render(orderByModel); + return new OrderByRenderer(renderingContext).render(orderByModel); } public static Builder withDeleteModel(DeleteModel deleteModel) { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/ColumnSortSpecification.java b/src/main/java/org/mybatis/dynamic/sql/select/ColumnSortSpecification.java index b8503a971..4420affc9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/ColumnSortSpecification.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/ColumnSortSpecification.java @@ -19,34 +19,31 @@ import org.mybatis.dynamic.sql.SortSpecification; import org.mybatis.dynamic.sql.SqlColumn; +import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; public class ColumnSortSpecification implements SortSpecification { private final String tableAlias; private final SqlColumn<?> column; - private final boolean isDescending; + private final String descendingPhrase; public ColumnSortSpecification(String tableAlias, SqlColumn<?> column) { - this(tableAlias, column, false); + this(tableAlias, column, ""); //$NON-NLS-1$ } - private ColumnSortSpecification(String tableAlias, SqlColumn<?> column, boolean isDescending) { + private ColumnSortSpecification(String tableAlias, SqlColumn<?> column, String descendingPhrase) { this.tableAlias = Objects.requireNonNull(tableAlias); this.column = Objects.requireNonNull(column); - this.isDescending = isDescending; + this.descendingPhrase = descendingPhrase; } @Override public SortSpecification descending() { - return new ColumnSortSpecification(tableAlias, column, true); + return new ColumnSortSpecification(tableAlias, column, " DESC"); //$NON-NLS-1$ } @Override - public String orderByName() { - return tableAlias + "." + column.name(); //$NON-NLS-1$ - } - - @Override - public boolean isDescending() { - return isDescending; + public FragmentAndParameters renderForOrderBy(RenderingContext renderingContext) { + return FragmentAndParameters.fromFragment(tableAlias + "." + column.name() + descendingPhrase); //$NON-NLS-1$ } } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SimpleSortSpecification.java b/src/main/java/org/mybatis/dynamic/sql/select/SimpleSortSpecification.java index 9620020e2..2c363ccc4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SimpleSortSpecification.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SimpleSortSpecification.java @@ -18,6 +18,8 @@ import java.util.Objects; import org.mybatis.dynamic.sql.SortSpecification; +import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; /** * This class is used for an order by phrase where there is no suitable column name @@ -28,30 +30,25 @@ public class SimpleSortSpecification implements SortSpecification { private final String name; - private final boolean isDescending; + private final String descendingPhrase; private SimpleSortSpecification(String name) { - this(name, false); + this(name, ""); //$NON-NLS-1$ } - private SimpleSortSpecification(String name, boolean isDescending) { + private SimpleSortSpecification(String name, String descendingPhrase) { this.name = Objects.requireNonNull(name); - this.isDescending = isDescending; + this.descendingPhrase = descendingPhrase; } @Override public SortSpecification descending() { - return new SimpleSortSpecification(name, true); + return new SimpleSortSpecification(name, " DESC"); //$NON-NLS-1$ } @Override - public String orderByName() { - return name; - } - - @Override - public boolean isDescending() { - return isDescending; + public FragmentAndParameters renderForOrderBy(RenderingContext renderingContext) { + return FragmentAndParameters.fromFragment(name + descendingPhrase); } public static SimpleSortSpecification of(String name) { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java index 59e926f67..c063e7866 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java @@ -87,7 +87,7 @@ private Optional<FragmentAndParameters> renderOrderBy() { } private FragmentAndParameters renderOrderBy(OrderByModel orderByModel) { - return new OrderByRenderer().render(orderByModel); + return new OrderByRenderer(renderingContext).render(orderByModel); } private Optional<FragmentAndParameters> renderPagingModel() { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java index 3f65a51e4..128ab3e8e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java @@ -68,7 +68,7 @@ private Optional<FragmentAndParameters> renderOrderBy() { } private FragmentAndParameters renderOrderBy(OrderByModel orderByModel) { - return new OrderByRenderer().render(orderByModel); + return new OrderByRenderer(renderingContext).render(orderByModel); } private Optional<FragmentAndParameters> renderPagingModel() { 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 50397ee7f..3edfed684 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 @@ -122,7 +122,7 @@ private Optional<FragmentAndParameters> calculateOrderByClause() { } private FragmentAndParameters renderOrderByClause(OrderByModel orderByModel) { - return new OrderByRenderer().render(orderByModel); + return new OrderByRenderer(renderingContext).render(orderByModel); } public static Builder withUpdateModel(UpdateModel updateModel) { diff --git a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties index 9927dbeec..35d0a810c 100644 --- a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties +++ b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties @@ -52,7 +52,7 @@ ERROR.33=Calling "select" or "selectDistinct" more than once is not allowed. Add union or unionAll expression ERROR.34=You must specify "select" or "selectDistinct" before any other clauses in a multi-select statement ERROR.35=Multi-select statements must have at least one "union" or "union all" expression -ERROR.36=You must either implement the "render" or "renderWithTableAlias" method in a column or function +ERROR.36=You must either implement the "render" or "renderWithTableAlias" method in a column or function ERROR.37=The "{0}" function does not support conditions that fail to render ERROR.38=Bound values cannot be aliased ERROR.39=When clauses in case expressions must render @@ -60,4 +60,6 @@ ERROR.40=Case expressions must have at least one "when" clause ERROR.41=You cannot call "then" in a Kotlin case expression more than once ERROR.42=You cannot call `else` in a Kotlin case expression more than once ERROR.43=A Kotlin cast expression must have one, and only one, `as` element +ERROR.44=You must either implement the "renderForOrderBy" method or both "orderByName" and "isDescending" methods in a \ + sort specification INTERNAL.ERROR=Internal Error {0} From f4702861162c54e92bcf4a9af5520d6278b56a97 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 4 Aug 2024 22:45:43 +0000 Subject: [PATCH 034/260] Update dependency org.mybatis:mybatis-parent to v45 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 24b549daa..80746c98f 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ <parent> <groupId>org.mybatis</groupId> <artifactId>mybatis-parent</artifactId> - <version>44</version> + <version>45</version> </parent> <groupId>org.mybatis.dynamic-sql</groupId> From 2d85bb46a33b02f36a376e60e475bbe0ec6735dc Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 5 Aug 2024 10:53:15 -0400 Subject: [PATCH 035/260] Allow case statements in order by phrases --- .../caseexpression/SearchedCaseDSL.java | 4 +- .../caseexpression/SearchedCaseModel.java | 26 +- .../select/caseexpression/SimpleCaseDSL.java | 4 +- .../caseexpression/SimpleCaseModel.java | 28 +- .../sql/select/render/SimpleCaseRenderer.java | 4 +- .../render/ColumnAndConditionRenderer.java | 4 +- .../mariadb/NumbersDynamicSQLSupport.java | 36 ++ .../examples/mariadb/OrderByCaseTest.java | 358 ++++++++++++++++++ .../canonical/SpringKotlinSubQueryTest.kt | 4 +- .../resources/examples/mariadb/CreateDB.sql | 12 + 10 files changed, 470 insertions(+), 10 deletions(-) create mode 100644 src/test/java/examples/mariadb/NumbersDynamicSQLSupport.java create mode 100644 src/test/java/examples/mariadb/OrderByCaseTest.java diff --git a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseDSL.java index 674012d3c..360fc344d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseDSL.java @@ -71,7 +71,7 @@ public SearchedCaseEnder else_(BasicColumn column) { return new SearchedCaseEnder(); } - public BasicColumn end() { + public SearchedCaseModel end() { return new SearchedCaseModel.Builder() .withElseValue(elseValue) .withWhenConditions(whenConditions) @@ -100,7 +100,7 @@ protected WhenDSL getThis() { } public class SearchedCaseEnder { - public BasicColumn end() { + public SearchedCaseModel end() { return SearchedCaseDSL.this.end(); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseModel.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseModel.java index 65d3f949f..15fd864f8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseModel.java @@ -21,20 +21,23 @@ import java.util.stream.Stream; import org.mybatis.dynamic.sql.BasicColumn; +import org.mybatis.dynamic.sql.SortSpecification; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.render.SearchedCaseRenderer; import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.Validator; -public class SearchedCaseModel implements BasicColumn { +public class SearchedCaseModel implements BasicColumn, SortSpecification { private final List<SearchedCaseWhenCondition> whenConditions; private final BasicColumn elseValue; private final String alias; + private final String descendingPhrase; private SearchedCaseModel(Builder builder) { whenConditions = builder.whenConditions; alias = builder.alias; elseValue = builder.elseValue; + descendingPhrase = builder.descendingPhrase; Validator.assertNotEmpty(whenConditions, "ERROR.40"); //$NON-NLS-1$ } @@ -56,9 +59,24 @@ public SearchedCaseModel as(String alias) { return new Builder().withWhenConditions(whenConditions) .withElseValue(elseValue) .withAlias(alias) + .withDescendingPhrase(descendingPhrase) .build(); } + @Override + public SearchedCaseModel descending() { + return new Builder().withWhenConditions(whenConditions) + .withElseValue(elseValue) + .withAlias(alias) + .withDescendingPhrase(" DESC") //$NON-NLS-1$ + .build(); + } + + @Override + public FragmentAndParameters renderForOrderBy(RenderingContext renderingContext) { + return render(renderingContext).mapFragment(f -> f + descendingPhrase); + } + @Override public FragmentAndParameters render(RenderingContext renderingContext) { return new SearchedCaseRenderer(this, renderingContext).render(); @@ -68,6 +86,7 @@ public static class Builder { private final List<SearchedCaseWhenCondition> whenConditions = new ArrayList<>(); private BasicColumn elseValue; private String alias; + private String descendingPhrase = ""; //$NON-NLS-1$ public Builder withWhenConditions(List<SearchedCaseWhenCondition> whenConditions) { this.whenConditions.addAll(whenConditions); @@ -84,6 +103,11 @@ public Builder withAlias(String alias) { return this; } + public Builder withDescendingPhrase(String descendingPhrase) { + this.descendingPhrase = descendingPhrase; + return this; + } + public SearchedCaseModel build() { return new SearchedCaseModel(this); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseDSL.java index 83e46473a..6b3f41338 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseDSL.java @@ -60,7 +60,7 @@ public SimpleCaseEnder else_(BasicColumn column) { return new SimpleCaseEnder(); } - public BasicColumn end() { + public SimpleCaseModel<T> end() { return new SimpleCaseModel.Builder<T>() .withColumn(column) .withWhenConditions(whenConditions) @@ -100,7 +100,7 @@ public SimpleCaseDSL<T> then(BasicColumn column) { } public class SimpleCaseEnder { - public BasicColumn end() { + public SimpleCaseModel<T> end() { return SimpleCaseDSL.this.end(); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseModel.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseModel.java index 4b71407ae..3c649c3da 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseModel.java @@ -23,22 +23,25 @@ import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; +import org.mybatis.dynamic.sql.SortSpecification; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.render.SimpleCaseRenderer; import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.Validator; -public class SimpleCaseModel<T> implements BasicColumn { +public class SimpleCaseModel<T> implements BasicColumn, SortSpecification { private final BindableColumn<T> column; private final List<SimpleCaseWhenCondition<T>> whenConditions; private final BasicColumn elseValue; private final String alias; + private final String descendingPhrase; private SimpleCaseModel(Builder<T> builder) { column = Objects.requireNonNull(builder.column); whenConditions = builder.whenConditions; elseValue = builder.elseValue; alias = builder.alias; + descendingPhrase = builder.descendingPhrase; Validator.assertNotEmpty(whenConditions, "ERROR.40"); //$NON-NLS-1$ } @@ -66,9 +69,26 @@ public SimpleCaseModel<T> as(String alias) { .withWhenConditions(whenConditions) .withElseValue(elseValue) .withAlias(alias) + .withDescendingPhrase(descendingPhrase) .build(); } + @Override + public SimpleCaseModel<T> descending() { + return new Builder<T>() + .withColumn(column) + .withWhenConditions(whenConditions) + .withElseValue(elseValue) + .withAlias(alias) + .withDescendingPhrase(" DESC") //$NON-NLS-1$ + .build(); + } + + @Override + public FragmentAndParameters renderForOrderBy(RenderingContext renderingContext) { + return render(renderingContext).mapFragment(f -> f + descendingPhrase); + } + @Override public FragmentAndParameters render(RenderingContext renderingContext) { return new SimpleCaseRenderer<>(this, renderingContext).render(); @@ -79,6 +99,7 @@ public static class Builder<T> { private final List<SimpleCaseWhenCondition<T>> whenConditions = new ArrayList<>(); private BasicColumn elseValue; private String alias; + private String descendingPhrase = ""; //$NON-NLS-1$ public Builder<T> withColumn(BindableColumn<T> column) { this.column = column; @@ -100,6 +121,11 @@ public Builder<T> withAlias(String alias) { return this; } + public Builder<T> withDescendingPhrase(String descendingPhrase) { + this.descendingPhrase = descendingPhrase; + return this; + } + public SimpleCaseModel<T> build() { return new SimpleCaseModel<>(this); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseRenderer.java index 2639d0b53..94cd071f1 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseRenderer.java @@ -48,7 +48,9 @@ public FragmentAndParameters render() { } private FragmentAndParameters renderCase() { - return simpleCaseModel.column().render(renderingContext) + return simpleCaseModel.column().alias() + .map(FragmentAndParameters::fromFragment) + .orElseGet(() -> simpleCaseModel.column().render(renderingContext)) .mapFragment(f -> "case " + f); //$NON-NLS-1$ } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java index 2a78ccbf8..da1050ed8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java @@ -36,7 +36,9 @@ private ColumnAndConditionRenderer(Builder<T> builder) { } public FragmentAndParameters render() { - FragmentAndParameters renderedLeftColumn = column.render(renderingContext); + FragmentAndParameters renderedLeftColumn = column.alias() + .map(FragmentAndParameters::fromFragment) + .orElseGet(() -> column.render(renderingContext)); DefaultConditionVisitor<T> visitor = DefaultConditionVisitor.withColumn(column) .withRenderingContext(renderingContext) diff --git a/src/test/java/examples/mariadb/NumbersDynamicSQLSupport.java b/src/test/java/examples/mariadb/NumbersDynamicSQLSupport.java new file mode 100644 index 000000000..f707b91fe --- /dev/null +++ b/src/test/java/examples/mariadb/NumbersDynamicSQLSupport.java @@ -0,0 +1,36 @@ +/* + * Copyright 2016-2024 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 + * + * https://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.mariadb; + +import org.mybatis.dynamic.sql.SqlColumn; +import org.mybatis.dynamic.sql.SqlTable; + +import java.sql.JDBCType; + +public final class NumbersDynamicSQLSupport { + public static final Numbers numbers = new Numbers(); + public static final SqlColumn<Integer> id = numbers.id; + public static final SqlColumn<String> description = numbers.description; + + public static final class Numbers extends SqlTable { + public final SqlColumn<Integer> id = column("id", JDBCType.INTEGER); + public final SqlColumn<String> description = column("description", JDBCType.VARCHAR); + + public Numbers() { + super("numbers"); + } + } +} diff --git a/src/test/java/examples/mariadb/OrderByCaseTest.java b/src/test/java/examples/mariadb/OrderByCaseTest.java new file mode 100644 index 000000000..0e0daf251 --- /dev/null +++ b/src/test/java/examples/mariadb/OrderByCaseTest.java @@ -0,0 +1,358 @@ +/* + * Copyright 2016-2024 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 + * + * https://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.mariadb; + +import static examples.mariadb.NumbersDynamicSQLSupport.description; +import static examples.mariadb.NumbersDynamicSQLSupport.id; +import static examples.mariadb.NumbersDynamicSQLSupport.numbers; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mybatis.dynamic.sql.SqlBuilder.case_; +import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo; +import static org.mybatis.dynamic.sql.SqlBuilder.select; + +import java.util.List; +import java.util.Map; + +import config.TestContainersConfiguration; +import org.apache.ibatis.datasource.unpooled.UnpooledDataSource; +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.BeforeAll; +import org.junit.jupiter.api.Test; +import org.mybatis.dynamic.sql.render.RenderingStrategies; +import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; +import org.mybatis.dynamic.sql.util.mybatis3.CommonSelectMapper; +import org.testcontainers.containers.MariaDBContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +@Testcontainers +class OrderByCaseTest { + + @SuppressWarnings("resource") + @Container + private static final MariaDBContainer<?> mariadb = + new MariaDBContainer<>(TestContainersConfiguration.MARIADB_LATEST) + .withInitScript("examples/mariadb/CreateDB.sql"); + + private static SqlSessionFactory sqlSessionFactory; + + @BeforeAll + static void setup() { + UnpooledDataSource ds = new UnpooledDataSource(mariadb.getDriverClassName(), mariadb.getJdbcUrl(), + mariadb.getUsername(), mariadb.getPassword()); + Environment environment = new Environment("test", new JdbcTransactionFactory(), ds); + Configuration config = new Configuration(environment); + config.addMapper(CommonSelectMapper.class); + sqlSessionFactory = new SqlSessionFactoryBuilder().build(config); + } + + @Test + void testOrderBySimpleCase() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description).from(numbers) + .orderBy(case_(description) + .when("One").then(3) + .when("Two").then(5) + .when("Three").then(4) + .when("Four").then(2) + .when("Five").then(1) + .else_(99) + .end()) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expected = "select id, description from numbers order by case description " + + "when #{parameters.p1,jdbcType=VARCHAR} then 3 " + + "when #{parameters.p2,jdbcType=VARCHAR} then 5 " + + "when #{parameters.p3,jdbcType=VARCHAR} then 4 " + + "when #{parameters.p4,jdbcType=VARCHAR} then 2 " + + "when #{parameters.p5,jdbcType=VARCHAR} then 1 else 99 end"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo( expected); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + assertThat(rows).hasSize(5); + assertThat(rows.get(0)).extracting("id", "description").containsExactly(5, "Five"); + assertThat(rows.get(1)).extracting("id", "description").containsExactly(4, "Four"); + assertThat(rows.get(2)).extracting("id", "description").containsExactly(1, "One"); + assertThat(rows.get(3)).extracting("id", "description").containsExactly(3, "Three"); + assertThat(rows.get(4)).extracting("id", "description").containsExactly(2, "Two"); + } + } + + @Test + void testOrderBySimpleCaseWithTableAlias() { + // ignore table aliases in order by phrases + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description).from(numbers, "n") + .orderBy(case_(description) + .when("One").then(3) + .when("Two").then(5) + .when("Three").then(4) + .when("Four").then(2) + .when("Five").then(1) + .else_(99) + .end()) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expected = "select n.id, n.description from numbers n order by case description " + + "when #{parameters.p1,jdbcType=VARCHAR} then 3 " + + "when #{parameters.p2,jdbcType=VARCHAR} then 5 " + + "when #{parameters.p3,jdbcType=VARCHAR} then 4 " + + "when #{parameters.p4,jdbcType=VARCHAR} then 2 " + + "when #{parameters.p5,jdbcType=VARCHAR} then 1 else 99 end"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo( expected); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + assertThat(rows).hasSize(5); + assertThat(rows.get(0)).extracting("id", "description").containsExactly(5, "Five"); + assertThat(rows.get(1)).extracting("id", "description").containsExactly(4, "Four"); + assertThat(rows.get(2)).extracting("id", "description").containsExactly(1, "One"); + assertThat(rows.get(3)).extracting("id", "description").containsExactly(3, "Three"); + assertThat(rows.get(4)).extracting("id", "description").containsExactly(2, "Two"); + } + } + + @Test + void testOrderBySimpleCaseWithColumnAlias() { + // ignore table aliases in order by phrases + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description.as("descr")).from(numbers) + .orderBy(case_(description.as("descr")) + .when("One").then(3) + .when("Two").then(5) + .when("Three").then(4) + .when("Four").then(2) + .when("Five").then(1) + .else_(99) + .end()) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expected = "select id, description as descr from numbers order by case descr " + + "when #{parameters.p1,jdbcType=VARCHAR} then 3 " + + "when #{parameters.p2,jdbcType=VARCHAR} then 5 " + + "when #{parameters.p3,jdbcType=VARCHAR} then 4 " + + "when #{parameters.p4,jdbcType=VARCHAR} then 2 " + + "when #{parameters.p5,jdbcType=VARCHAR} then 1 else 99 end"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo( expected); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + assertThat(rows).hasSize(5); + assertThat(rows.get(0)).extracting("id", "descr").containsExactly(5, "Five"); + assertThat(rows.get(1)).extracting("id", "descr").containsExactly(4, "Four"); + assertThat(rows.get(2)).extracting("id", "descr").containsExactly(1, "One"); + assertThat(rows.get(3)).extracting("id", "descr").containsExactly(3, "Three"); + assertThat(rows.get(4)).extracting("id", "descr").containsExactly(2, "Two"); + } + } + + @Test + void testOrderBySimpleCaseDescending() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description).from(numbers) + .orderBy(case_(description) + .when("One").then(3) + .when("Two").then(5) + .when("Three").then(4) + .when("Four").then(2) + .when("Five").then(1) + .else_(99) + .end().descending()) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expected = "select id, description from numbers order by case description " + + "when #{parameters.p1,jdbcType=VARCHAR} then 3 " + + "when #{parameters.p2,jdbcType=VARCHAR} then 5 " + + "when #{parameters.p3,jdbcType=VARCHAR} then 4 " + + "when #{parameters.p4,jdbcType=VARCHAR} then 2 " + + "when #{parameters.p5,jdbcType=VARCHAR} then 1 else 99 end DESC"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo( expected); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + assertThat(rows).hasSize(5); + assertThat(rows.get(4)).extracting("id", "description").containsExactly(5, "Five"); + assertThat(rows.get(3)).extracting("id", "description").containsExactly(4, "Four"); + assertThat(rows.get(2)).extracting("id", "description").containsExactly(1, "One"); + assertThat(rows.get(1)).extracting("id", "description").containsExactly(3, "Three"); + assertThat(rows.get(0)).extracting("id", "description").containsExactly(2, "Two"); + } + } + + @Test + void testOrderBySearchedCase() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description).from(numbers) + .orderBy(case_() + .when(description, isEqualTo("One")).then(3) + .when(description, isEqualTo("Two")).then(5) + .when(description, isEqualTo("Three")).then(4) + .when(description, isEqualTo("Four")).then(2) + .when(description, isEqualTo("Five")).then(1) + .else_(99) + .end()) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expected = "select id, description from numbers order by case " + + "when description = #{parameters.p1,jdbcType=VARCHAR} then 3 " + + "when description = #{parameters.p2,jdbcType=VARCHAR} then 5 " + + "when description = #{parameters.p3,jdbcType=VARCHAR} then 4 " + + "when description = #{parameters.p4,jdbcType=VARCHAR} then 2 " + + "when description = #{parameters.p5,jdbcType=VARCHAR} then 1 else 99 end"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo( expected); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + assertThat(rows).hasSize(5); + assertThat(rows.get(0)).extracting("id", "description").containsExactly(5, "Five"); + assertThat(rows.get(1)).extracting("id", "description").containsExactly(4, "Four"); + assertThat(rows.get(2)).extracting("id", "description").containsExactly(1, "One"); + assertThat(rows.get(3)).extracting("id", "description").containsExactly(3, "Three"); + assertThat(rows.get(4)).extracting("id", "description").containsExactly(2, "Two"); + } + } + + @Test + void testOrderBySearchedCaseWithTableAlias() { + // ignore table aliases in order by phrases + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description).from(numbers, "n") + .orderBy(case_() + .when(description, isEqualTo("One")).then(3) + .when(description, isEqualTo("Two")).then(5) + .when(description, isEqualTo("Three")).then(4) + .when(description, isEqualTo("Four")).then(2) + .when(description, isEqualTo("Five")).then(1) + .else_(99) + .end()) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expected = "select n.id, n.description from numbers n order by case " + + "when description = #{parameters.p1,jdbcType=VARCHAR} then 3 " + + "when description = #{parameters.p2,jdbcType=VARCHAR} then 5 " + + "when description = #{parameters.p3,jdbcType=VARCHAR} then 4 " + + "when description = #{parameters.p4,jdbcType=VARCHAR} then 2 " + + "when description = #{parameters.p5,jdbcType=VARCHAR} then 1 else 99 end"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo( expected); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + assertThat(rows).hasSize(5); + assertThat(rows.get(0)).extracting("id", "description").containsExactly(5, "Five"); + assertThat(rows.get(1)).extracting("id", "description").containsExactly(4, "Four"); + assertThat(rows.get(2)).extracting("id", "description").containsExactly(1, "One"); + assertThat(rows.get(3)).extracting("id", "description").containsExactly(3, "Three"); + assertThat(rows.get(4)).extracting("id", "description").containsExactly(2, "Two"); + } + } + + @Test + void testOrderBySearchedCaseWithColumnAlias() { + // ignore table aliases in order by phrases + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description.as("descr")).from(numbers) + .orderBy(case_() + .when(description.as("descr"), isEqualTo("One")).then(3) + .when(description.as("descr"), isEqualTo("Two")).then(5) + .when(description.as("descr"), isEqualTo("Three")).then(4) + .when(description.as("descr"), isEqualTo("Four")).then(2) + .when(description.as("descr"), isEqualTo("Five")).then(1) + .else_(99) + .end()) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expected = "select id, description as descr from numbers order by case " + + "when descr = #{parameters.p1,jdbcType=VARCHAR} then 3 " + + "when descr = #{parameters.p2,jdbcType=VARCHAR} then 5 " + + "when descr = #{parameters.p3,jdbcType=VARCHAR} then 4 " + + "when descr = #{parameters.p4,jdbcType=VARCHAR} then 2 " + + "when descr = #{parameters.p5,jdbcType=VARCHAR} then 1 else 99 end"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo( expected); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + assertThat(rows).hasSize(5); + assertThat(rows.get(0)).extracting("id", "descr").containsExactly(5, "Five"); + assertThat(rows.get(1)).extracting("id", "descr").containsExactly(4, "Four"); + assertThat(rows.get(2)).extracting("id", "descr").containsExactly(1, "One"); + assertThat(rows.get(3)).extracting("id", "descr").containsExactly(3, "Three"); + assertThat(rows.get(4)).extracting("id", "descr").containsExactly(2, "Two"); + } + } + + @Test + void testOrderBySearchedCaseDescending() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description).from(numbers) + .orderBy(case_() + .when(description, isEqualTo("One")).then(3) + .when(description, isEqualTo("Two")).then(5) + .when(description, isEqualTo("Three")).then(4) + .when(description, isEqualTo("Four")).then(2) + .when(description, isEqualTo("Five")).then(1) + .else_(99) + .end().descending()) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expected = "select id, description from numbers order by case " + + "when description = #{parameters.p1,jdbcType=VARCHAR} then 3 " + + "when description = #{parameters.p2,jdbcType=VARCHAR} then 5 " + + "when description = #{parameters.p3,jdbcType=VARCHAR} then 4 " + + "when description = #{parameters.p4,jdbcType=VARCHAR} then 2 " + + "when description = #{parameters.p5,jdbcType=VARCHAR} then 1 else 99 end DESC"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo( expected); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + assertThat(rows).hasSize(5); + assertThat(rows.get(4)).extracting("id", "description").containsExactly(5, "Five"); + assertThat(rows.get(3)).extracting("id", "description").containsExactly(4, "Four"); + assertThat(rows.get(2)).extracting("id", "description").containsExactly(1, "One"); + assertThat(rows.get(1)).extracting("id", "description").containsExactly(3, "Three"); + assertThat(rows.get(0)).extracting("id", "description").containsExactly(2, "Two"); + } + } +} diff --git a/src/test/kotlin/examples/kotlin/spring/canonical/SpringKotlinSubQueryTest.kt b/src/test/kotlin/examples/kotlin/spring/canonical/SpringKotlinSubQueryTest.kt index eb97249a6..d4ff965b9 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/SpringKotlinSubQueryTest.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/SpringKotlinSubQueryTest.kt @@ -113,12 +113,12 @@ open class SpringKotlinSubQueryTest { @Test fun testBasicSubQueryWithAliases() { - val rowNum = DerivedColumn.of<Int>("rownum()") `as` "myRows" + val rowNum = DerivedColumn.of<Int>("rownum()") val outerFirstName = "b"(firstName) val personId = DerivedColumn.of<Int>("personId", "b") val selectStatement = - select(outerFirstName.asCamelCase(), personId, rowNum) { + select(outerFirstName.asCamelCase(), personId, rowNum `as` "myRows") { from { select(id `as` "personId", firstName) { from(person, "a") diff --git a/src/test/resources/examples/mariadb/CreateDB.sql b/src/test/resources/examples/mariadb/CreateDB.sql index 3e16f6a73..3c90c396d 100644 --- a/src/test/resources/examples/mariadb/CreateDB.sql +++ b/src/test/resources/examples/mariadb/CreateDB.sql @@ -41,3 +41,15 @@ insert into items values (17, 'Item 17', 117); insert into items values (18, 'Item 18', 118); insert into items values (19, 'Item 19', 119); insert into items values (20, 'Item 20', 120); + +create table numbers ( + id int not null, + description varchar(50) not null, + primary key (id) +); + +insert into numbers values (1, 'One'); +insert into numbers values (2, 'Two'); +insert into numbers values (3, 'Three'); +insert into numbers values (4, 'Four'); +insert into numbers values (5, 'Five'); From a959711d16f0275abe49c7dbb719865076d1e29e Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 5 Aug 2024 11:08:38 -0400 Subject: [PATCH 036/260] Update version to 2.0.0! --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 03b765595..0da827e3b 100644 --- a/pom.xml +++ b/pom.xml @@ -26,7 +26,7 @@ <groupId>org.mybatis.dynamic-sql</groupId> <artifactId>mybatis-dynamic-sql</artifactId> - <version>1.6.0-SNAPSHOT</version> + <version>2.0.0-SNAPSHOT</version> <name>MyBatis Dynamic SQL</name> <description>MyBatis framework for generating dynamic SQL</description> From 523c7497e87700b1d1641f767a15676f98dd7b6f Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 5 Aug 2024 11:08:49 -0400 Subject: [PATCH 037/260] Docs --- CHANGELOG.md | 4 ++++ README.md | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d80d14ee3..de304acca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ This log will detail notable changes to MyBatis Dynamic SQL. Full details are available on the GitHub milestone pages. +## Release 2.0.0 - Unreleased + +The library now requires Java 17. + ## Release 1.5.2 - June 3, 2024 This is a small maintenance release with the following changes: diff --git a/README.md b/README.md index 12dac83b3..a9172a1b3 100644 --- a/README.md +++ b/README.md @@ -80,4 +80,4 @@ The library test cases provide several complete examples of using the library in ## Requirements -The library has no dependencies. Java 8 or higher is required. +The library has no dependencies. Version 2.x requires Java 17. Version 1.8 requires Java 8. From 491e9b4af33246acf800a051fbbcf4f136057dbf Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 5 Aug 2024 12:00:17 -0400 Subject: [PATCH 038/260] Kick Github --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a9172a1b3..33f212278 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,6 @@ The library test cases provide several complete examples of using the library in | Kotlin | Spring JDBC | Example using Kotlin utility classes for Spring JDBC Template | [../examples/kotlin/spring/canonical](src/test/kotlin/examples/kotlin/spring/canonical) | -## Requirements +## Requirements The library has no dependencies. Version 2.x requires Java 17. Version 1.8 requires Java 8. From 73f5e8f726fd8fe305d41b3e77e79c2083d14a50 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 5 Aug 2024 12:00:25 -0400 Subject: [PATCH 039/260] Kick Github --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 33f212278..a9172a1b3 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,6 @@ The library test cases provide several complete examples of using the library in | Kotlin | Spring JDBC | Example using Kotlin utility classes for Spring JDBC Template | [../examples/kotlin/spring/canonical](src/test/kotlin/examples/kotlin/spring/canonical) | -## Requirements +## Requirements The library has no dependencies. Version 2.x requires Java 17. Version 1.8 requires Java 8. From bc1506cd71197a064f277834369f7acd62896687 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 5 Aug 2024 16:46:33 +0000 Subject: [PATCH 040/260] Update junit5 monorepo to v5.10.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0da827e3b..5d5447a8f 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ <properties> <java.version>17</java.version> <java.release.version>17</java.release.version> - <junit.jupiter.version>5.10.2</junit.jupiter.version> + <junit.jupiter.version>5.10.3</junit.jupiter.version> <spring.batch.version>5.1.2</spring.batch.version> <checkstyle.config>checkstyle-override.xml</checkstyle.config> From 7e06a2a6080bf4aba479f00e946cabffe4f024f0 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 5 Aug 2024 12:48:15 -0400 Subject: [PATCH 041/260] Small typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a9172a1b3..812dc3b9d 100644 --- a/README.md +++ b/README.md @@ -80,4 +80,4 @@ The library test cases provide several complete examples of using the library in ## Requirements -The library has no dependencies. Version 2.x requires Java 17. Version 1.8 requires Java 8. +The library has no dependencies. Version 2.x requires Java 17. Version 1.x requires Java 8. From a6022069af41a7132b19b01303b6002b38004880 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 5 Aug 2024 12:51:44 -0400 Subject: [PATCH 042/260] Docs --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de304acca..31e9fa8b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,10 @@ This log will detail notable changes to MyBatis Dynamic SQL. Full details are av ## Release 2.0.0 - Unreleased -The library now requires Java 17. +Significant changes: + +- The library now requires Java 17 +- Deprecated code from prior releases is removed ## Release 1.5.2 - June 3, 2024 From 6f483d823a5970d589840e0843dc0dd5b91558c5 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 5 Aug 2024 17:04:34 -0400 Subject: [PATCH 043/260] Coverage for deprecated methods --- .../sql/DeprecatedSortMethodsTest.java | 142 ++++++++++++++++++ .../mybatis/dynamic/sql/InvalidSQLTest.java | 1 - 2 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 src/test/java/org/mybatis/dynamic/sql/DeprecatedSortMethodsTest.java diff --git a/src/test/java/org/mybatis/dynamic/sql/DeprecatedSortMethodsTest.java b/src/test/java/org/mybatis/dynamic/sql/DeprecatedSortMethodsTest.java new file mode 100644 index 000000000..678d997d2 --- /dev/null +++ b/src/test/java/org/mybatis/dynamic/sql/DeprecatedSortMethodsTest.java @@ -0,0 +1,142 @@ +/* + * Copyright 2016-2024 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 + * + * https://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 static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.mybatis.dynamic.sql.common.OrderByModel; +import org.mybatis.dynamic.sql.common.OrderByRenderer; +import org.mybatis.dynamic.sql.configuration.StatementConfiguration; +import org.mybatis.dynamic.sql.exception.DynamicSqlException; +import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.render.RenderingStrategies; +import org.mybatis.dynamic.sql.render.TableAliasCalculator; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; +import org.mybatis.dynamic.sql.util.Messages; + +class DeprecatedSortMethodsTest { + + @Test + void bothMethodsExist() { + SortSpecification ss = new SortSpecification() { + @Override + public SortSpecification descending() { + return this; + } + + @Override + public String orderByName() { + return "id"; + } + + @Override + public boolean isDescending() { + return true; + } + }; + + OrderByModel model = OrderByModel.of(List.of(ss)); + + RenderingContext renderingContext = RenderingContext + .withRenderingStrategy(RenderingStrategies.MYBATIS3) + .withTableAliasCalculator(TableAliasCalculator.empty()) + .withStatementConfiguration(new StatementConfiguration()) + .build(); + OrderByRenderer renderer = new OrderByRenderer(renderingContext); + FragmentAndParameters fp = renderer.render(model); + assertThat(fp.fragment()).isEqualTo("order by id DESC"); + } + + @Test + void orderByNameMethodMissing() { + SortSpecification ss = new SortSpecification() { + @Override + public SortSpecification descending() { + return this; + } + + @Override + public boolean isDescending() { + return true; + } + }; + + OrderByModel model = OrderByModel.of(List.of(ss)); + + RenderingContext renderingContext = RenderingContext + .withRenderingStrategy(RenderingStrategies.MYBATIS3) + .withTableAliasCalculator(TableAliasCalculator.empty()) + .withStatementConfiguration(new StatementConfiguration()) + .build(); + OrderByRenderer renderer = new OrderByRenderer(renderingContext); + assertThatExceptionOfType(DynamicSqlException.class) + .isThrownBy(() -> renderer.render(model)) + .withMessage(Messages.getString("ERROR.44")); + } + + @Test + void isDescendingMethodMissing() { + SortSpecification ss = new SortSpecification() { + @Override + public SortSpecification descending() { + return this; + } + + @Override + public String orderByName() { + return "id"; + } + }; + + OrderByModel model = OrderByModel.of(List.of(ss)); + + RenderingContext renderingContext = RenderingContext + .withRenderingStrategy(RenderingStrategies.MYBATIS3) + .withTableAliasCalculator(TableAliasCalculator.empty()) + .withStatementConfiguration(new StatementConfiguration()) + .build(); + OrderByRenderer renderer = new OrderByRenderer(renderingContext); + assertThatExceptionOfType(DynamicSqlException.class) + .isThrownBy(() -> renderer.render(model)) + .withMessage(Messages.getString("ERROR.44")); + } + + @Test + void bothMethodsMissing() { + SortSpecification ss = new SortSpecification() { + @Override + public SortSpecification descending() { + return this; + } + }; + + OrderByModel model = OrderByModel.of(List.of(ss)); + + RenderingContext renderingContext = RenderingContext + .withRenderingStrategy(RenderingStrategies.MYBATIS3) + .withTableAliasCalculator(TableAliasCalculator.empty()) + .withStatementConfiguration(new StatementConfiguration()) + .build(); + OrderByRenderer renderer = new OrderByRenderer(renderingContext); + assertThatExceptionOfType(DynamicSqlException.class) + .isThrownBy(() -> renderer.render(model)) + .withMessage(Messages.getString("ERROR.44")); + } +} diff --git a/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java b/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java index bfec86e73..cc5f16193 100644 --- a/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java @@ -22,7 +22,6 @@ import static org.mybatis.dynamic.sql.SqlBuilder.update; import static org.mybatis.dynamic.sql.SqlBuilder.value; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.MissingResourceException; From 1da8ab4f9190b0575e4a1929ba7f40a6c91cc16b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 6 Aug 2024 10:20:50 +0000 Subject: [PATCH 044/260] Update kotlin monorepo to v2.0.10 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5d5447a8f..aa2ee3a0d 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,7 @@ <module.name>org.mybatis.dynamic.sql</module.name> - <kotlin.version>2.0.0</kotlin.version> + <kotlin.version>2.0.10</kotlin.version> <kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget> <sonar.sources>pom.xml,src/main/java,src/main/kotlin</sonar.sources> From d69b968dbea48b25978592de12a8bf26fc5abdb5 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 6 Aug 2024 11:01:23 -0400 Subject: [PATCH 045/260] Sonar suggestions --- .../org/mybatis/dynamic/sql/AbstractListValueCondition.java | 2 +- src/main/java/org/mybatis/dynamic/sql/SortSpecification.java | 4 ++-- .../org/mybatis/dynamic/sql/insert/render/BatchInsert.java | 3 +-- .../dynamic/sql/select/AbstractQueryExpressionDSL.java | 3 +-- src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java | 3 +-- .../org/mybatis/dynamic/sql/update/render/UpdateRenderer.java | 4 ++-- .../java/org/mybatis/dynamic/sql/util/SqlProviderAdapter.java | 3 +-- .../mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java | 3 +-- .../mybatis/dynamic/sql/util/spring/BatchInsertUtility.java | 3 +-- .../sql/where/condition/IsInCaseInsensitiveWhenPresent.java | 3 +-- .../mybatis/dynamic/sql/where/condition/IsInWhenPresent.java | 3 +-- .../where/condition/IsNotInCaseInsensitiveWhenPresent.java | 3 +-- .../dynamic/sql/where/condition/IsNotInWhenPresent.java | 3 +-- .../mybatis/dynamic/sql/where/render/CriterionRenderer.java | 2 +- 14 files changed, 16 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java index 104859de8..dc287e842 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java @@ -51,7 +51,7 @@ private <R> Collection<R> applyMapper(Function<? super T, ? extends R> mapper) { private Collection<T> applyFilter(Predicate<? super T> predicate) { Objects.requireNonNull(predicate); - return values.stream().filter(predicate).collect(Collectors.toList()); + return values.stream().filter(predicate).toList(); } protected <S extends AbstractListValueCondition<T>> S filterSupport(Predicate<? super T> predicate, diff --git a/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java b/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java index 85f9f5288..87b986d27 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java +++ b/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java @@ -42,7 +42,7 @@ public interface SortSpecification { * @deprecated Please replace this method by overriding the more general "renderForOrderBy" method. Target for * removal in release 2.1 */ - @Deprecated + @Deprecated(since = "2.0", forRemoval = true) default String orderByName() { throw new DynamicSqlException(Messages.getString("ERROR.44")); //$NON-NLS-1$ } @@ -54,7 +54,7 @@ default String orderByName() { * @deprecated Please replace this method by overriding the more general "renderForOrderBy" method. Target for * removal in release 2.1 */ - @Deprecated + @Deprecated(since = "2.0", forRemoval = true) default boolean isDescending() { throw new DynamicSqlException(Messages.getString("ERROR.44")); //$NON-NLS-1$ } diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsert.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsert.java index 2759bb907..cde4ec626 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsert.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsert.java @@ -19,7 +19,6 @@ import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; public class BatchInsert<T> { private final String insertStatement; @@ -38,7 +37,7 @@ private BatchInsert(Builder<T> builder) { public List<InsertStatementProvider<T>> insertStatements() { return records.stream() .map(this::toInsertStatement) - .collect(Collectors.toList()); + .toList(); } private InsertStatementProvider<T> toInsertStatement(T row) { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/AbstractQueryExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/AbstractQueryExpressionDSL.java index d800a02ff..d82076a49 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/AbstractQueryExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/AbstractQueryExpressionDSL.java @@ -23,7 +23,6 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.stream.Collectors; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.TableExpression; @@ -196,7 +195,7 @@ protected Optional<JoinModel> buildJoinModel() { return Optional.of(JoinModel.of(joinSpecificationBuilders.stream() .map(JoinSpecification.Builder::build) - .collect(Collectors.toList()))); + .toList())); } protected void addTableAlias(SqlTable table, String tableAlias) { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java index a509e974b..cb1fae92d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java @@ -23,7 +23,6 @@ import java.util.Optional; import java.util.function.Consumer; import java.util.function.Function; -import java.util.stream.Collectors; import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.BasicColumn; @@ -143,7 +142,7 @@ public R build() { private List<QueryExpressionModel> buildModels() { return queryExpressions.stream() .map(QueryExpressionDSL::buildModel) - .collect(Collectors.toList()); + .toList(); } private Optional<PagingModel> buildPagingModel() { 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 0a3fae0d1..f11662c02 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 @@ -78,8 +78,8 @@ private FragmentAndParameters calculateUpdateStatementStart() { private FragmentAndParameters calculateSetPhrase() { List<Optional<FragmentAndParameters>> fragmentsAndParameters = updateModel.columnMappings() - .map(m -> m.accept(visitor)) - .collect(Collectors.toList()); + .map(m -> m.accept(visitor)) + .toList(); Validator.assertFalse(fragmentsAndParameters.stream().noneMatch(Optional::isPresent), "ERROR.18"); //$NON-NLS-1$ diff --git a/src/main/java/org/mybatis/dynamic/sql/util/SqlProviderAdapter.java b/src/main/java/org/mybatis/dynamic/sql/util/SqlProviderAdapter.java index fafcc6bda..2e129b611 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/SqlProviderAdapter.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/SqlProviderAdapter.java @@ -17,7 +17,6 @@ import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider; import org.mybatis.dynamic.sql.insert.render.GeneralInsertStatementProvider; @@ -76,7 +75,7 @@ public String insertMultipleWithGeneratedKeys(Map<String, Object> parameterMap) .map(Map.Entry::getValue) .filter(String.class::isInstance) .map(String.class::cast) - .collect(Collectors.toList()); + .toList(); if (entries.size() == 1) { return entries.get(0); diff --git a/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java index d7d67edc0..f0cfb72c0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java @@ -20,7 +20,6 @@ import java.util.Map; import java.util.Optional; import java.util.function.Function; -import java.util.stream.Collectors; import org.apache.ibatis.annotations.SelectProvider; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; @@ -110,7 +109,7 @@ default <R> List<R> selectMany(SelectStatementProvider selectStatement, Function<Map<String, Object>, R> rowMapper) { return selectManyMappedRows(selectStatement).stream() .map(rowMapper) - .collect(Collectors.toList()); + .toList(); } /** diff --git a/src/main/java/org/mybatis/dynamic/sql/util/spring/BatchInsertUtility.java b/src/main/java/org/mybatis/dynamic/sql/util/spring/BatchInsertUtility.java index 485868ba6..01b76b9a0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/spring/BatchInsertUtility.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/spring/BatchInsertUtility.java @@ -16,7 +16,6 @@ package org.mybatis.dynamic.sql.util.spring; import java.util.List; -import java.util.stream.Collectors; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils; @@ -35,7 +34,7 @@ private BatchInsertUtility() {} public static <T> SqlParameterSource[] createBatch(List<T> rows) { List<RowHolder<T>> tt = rows.stream() .map(RowHolder::new) - .collect(Collectors.toList()); + .toList(); return SqlParameterSourceUtils.createBatch(tt); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java index b123d30c5..3fc3eca6f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java @@ -21,7 +21,6 @@ import java.util.Objects; import java.util.function.Predicate; import java.util.function.UnaryOperator; -import java.util.stream.Collectors; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; @@ -35,7 +34,7 @@ public static IsInCaseInsensitiveWhenPresent empty() { } protected IsInCaseInsensitiveWhenPresent(Collection<String> values) { - super(values.stream().filter(Objects::nonNull).collect(Collectors.toList())); + super(values.stream().filter(Objects::nonNull).toList()); } @Override diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java index fc2994ea7..6e12a0437 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java @@ -21,7 +21,6 @@ import java.util.Objects; import java.util.function.Function; import java.util.function.Predicate; -import java.util.stream.Collectors; import org.mybatis.dynamic.sql.AbstractListValueCondition; @@ -35,7 +34,7 @@ public static <T> IsInWhenPresent<T> empty() { } protected IsInWhenPresent(Collection<T> values) { - super(values.stream().filter(Objects::nonNull).collect(Collectors.toList())); + super(values.stream().filter(Objects::nonNull).toList()); } @Override diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java index 58f0b347e..543ff7817 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java @@ -21,7 +21,6 @@ import java.util.Objects; import java.util.function.Predicate; import java.util.function.UnaryOperator; -import java.util.stream.Collectors; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; @@ -35,7 +34,7 @@ public static IsNotInCaseInsensitiveWhenPresent empty() { } protected IsNotInCaseInsensitiveWhenPresent(Collection<String> values) { - super(values.stream().filter(Objects::nonNull).collect(Collectors.toList())); + super(values.stream().filter(Objects::nonNull).toList()); } @Override diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java index 8115413ef..6917128ab 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java @@ -21,7 +21,6 @@ import java.util.Objects; import java.util.function.Function; import java.util.function.Predicate; -import java.util.stream.Collectors; import org.mybatis.dynamic.sql.AbstractListValueCondition; @@ -35,7 +34,7 @@ public static <T> IsNotInWhenPresent<T> empty() { } protected IsNotInWhenPresent(Collection<T> values) { - super(values.stream().filter(Objects::nonNull).collect(Collectors.toList())); + super(values.stream().filter(Objects::nonNull).toList()); } @Override diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java index 232b68c11..0e4325179 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java @@ -136,7 +136,7 @@ private FragmentAndParameters renderExists(ExistsCriterion criterion) { private List<RenderedCriterion> renderSubCriteria(List<AndOrCriteriaGroup> subCriteria) { return subCriteria.stream().map(this::renderAndOrCriteriaGroup) .flatMap(Optional::stream) - .collect(Collectors.toList()); + .toList(); } private Optional<RenderedCriterion> renderAndOrCriteriaGroup(AndOrCriteriaGroup criterion) { From e83b6f9d0550bff54f8bf2e96424857ddc9d48b6 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 6 Aug 2024 11:07:02 -0400 Subject: [PATCH 046/260] Coverage --- .../sql/insert/render/BatchInsert.java | 2 +- .../sql/DeprecatedSortMethodsTest.java | 33 ++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsert.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsert.java index cde4ec626..5a3c22893 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsert.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsert.java @@ -56,7 +56,7 @@ public String getInsertStatementSQL() { } public List<T> getRecords() { - return Collections.unmodifiableList(records); + return records; } public static <T> Builder<T> withRecords(List<T> records) { diff --git a/src/test/java/org/mybatis/dynamic/sql/DeprecatedSortMethodsTest.java b/src/test/java/org/mybatis/dynamic/sql/DeprecatedSortMethodsTest.java index 678d997d2..520783155 100644 --- a/src/test/java/org/mybatis/dynamic/sql/DeprecatedSortMethodsTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/DeprecatedSortMethodsTest.java @@ -48,12 +48,43 @@ public String orderByName() { @Override public boolean isDescending() { - return true; + return false; } }; OrderByModel model = OrderByModel.of(List.of(ss)); + RenderingContext renderingContext = RenderingContext + .withRenderingStrategy(RenderingStrategies.MYBATIS3) + .withTableAliasCalculator(TableAliasCalculator.empty()) + .withStatementConfiguration(new StatementConfiguration()) + .build(); + OrderByRenderer renderer = new OrderByRenderer(renderingContext); + FragmentAndParameters fp = renderer.render(model); + assertThat(fp.fragment()).isEqualTo("order by id"); + } + + @Test + void bothMethodsExistDescending() { + SortSpecification ss = new SortSpecification() { + @Override + public SortSpecification descending() { + return this; + } + + @Override + public String orderByName() { + return "id"; + } + + @Override + public boolean isDescending() { + return true; + } + }; + + OrderByModel model = OrderByModel.of(List.of(ss)); + RenderingContext renderingContext = RenderingContext .withRenderingStrategy(RenderingStrategies.MYBATIS3) .withTableAliasCalculator(TableAliasCalculator.empty()) From 8b645112a8cc500573f1dc997efcbd2a4fdf2e66 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 6 Aug 2024 11:24:26 -0400 Subject: [PATCH 047/260] Checkstyle and PMD Updates --- .../java/org/mybatis/dynamic/sql/SortSpecification.java | 4 ++-- .../java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java | 2 +- .../org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java | 2 +- .../org/mybatis/dynamic/sql/util/FragmentAndParameters.java | 2 +- .../sql/where/condition/IsInCaseInsensitiveWhenPresent.java | 6 ++++-- .../where/condition/IsNotInCaseInsensitiveWhenPresent.java | 6 ++++-- 6 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java b/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java index 87b986d27..48aee58c4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java +++ b/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java @@ -40,7 +40,7 @@ public interface SortSpecification { * * @return the order by phrase * @deprecated Please replace this method by overriding the more general "renderForOrderBy" method. Target for - * removal in release 2.1 + * removal in release 2.1 */ @Deprecated(since = "2.0", forRemoval = true) default String orderByName() { @@ -52,7 +52,7 @@ default String orderByName() { * * @return true if the SortSpecification should render as descending * @deprecated Please replace this method by overriding the more general "renderForOrderBy" method. Target for - * removal in release 2.1 + * removal in release 2.1 */ @Deprecated(since = "2.0", forRemoval = true) default boolean isDescending() { diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java index 9b5f69cec..104557a4c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java @@ -59,7 +59,7 @@ public BatchInsertModel<T> build() { @SafeVarargs public static <T> IntoGatherer<T> insert(T... records) { - return BatchInsertDSL.insert(Arrays.asList(records)); + return insert(Arrays.asList(records)); } public static <T> IntoGatherer<T> insert(Collection<T> records) { diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java index 1b8feaca3..6976dabc9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java @@ -58,7 +58,7 @@ public MultiRowInsertModel<T> build() { @SafeVarargs public static <T> IntoGatherer<T> insert(T... records) { - return MultiRowInsertDSL.insert(Arrays.asList(records)); + return insert(Arrays.asList(records)); } public static <T> IntoGatherer<T> insert(Collection<T> records) { diff --git a/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java b/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java index c6b65b3b0..4c240120c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java @@ -46,7 +46,7 @@ public Map<String, Object> parameters() { * @return a new instance with the same parameters and a transformed fragment */ public FragmentAndParameters mapFragment(UnaryOperator<String> mapper) { - return FragmentAndParameters.withFragment(mapper.apply(fragment)) + return withFragment(mapper.apply(fragment)) .withParameters(parameters) .build(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java index 3fc3eca6f..356fb034a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java @@ -27,7 +27,8 @@ public class IsInCaseInsensitiveWhenPresent extends AbstractListValueCondition<String> implements CaseInsensitiveVisitableCondition { - private static final IsInCaseInsensitiveWhenPresent EMPTY = new IsInCaseInsensitiveWhenPresent(Collections.emptyList()); + private static final IsInCaseInsensitiveWhenPresent EMPTY = + new IsInCaseInsensitiveWhenPresent(Collections.emptyList()); public static IsInCaseInsensitiveWhenPresent empty() { return EMPTY; @@ -44,7 +45,8 @@ public String operator() { @Override public IsInCaseInsensitiveWhenPresent filter(Predicate<? super String> predicate) { - return filterSupport(predicate, IsInCaseInsensitiveWhenPresent::new, this, IsInCaseInsensitiveWhenPresent::empty); + return filterSupport(predicate, IsInCaseInsensitiveWhenPresent::new, this, + IsInCaseInsensitiveWhenPresent::empty); } /** diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java index 543ff7817..7f254eedd 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java @@ -27,7 +27,8 @@ public class IsNotInCaseInsensitiveWhenPresent extends AbstractListValueCondition<String> implements CaseInsensitiveVisitableCondition { - private static final IsNotInCaseInsensitiveWhenPresent EMPTY = new IsNotInCaseInsensitiveWhenPresent(Collections.emptyList()); + private static final IsNotInCaseInsensitiveWhenPresent EMPTY = + new IsNotInCaseInsensitiveWhenPresent(Collections.emptyList()); public static IsNotInCaseInsensitiveWhenPresent empty() { return EMPTY; @@ -44,7 +45,8 @@ public String operator() { @Override public IsNotInCaseInsensitiveWhenPresent filter(Predicate<? super String> predicate) { - return filterSupport(predicate, IsNotInCaseInsensitiveWhenPresent::new, this, IsNotInCaseInsensitiveWhenPresent::empty); + return filterSupport(predicate, IsNotInCaseInsensitiveWhenPresent::new, + this, IsNotInCaseInsensitiveWhenPresent::empty); } /** From 1d2dc669b0092896058efbf2a38c61b54f585aeb Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 6 Aug 2024 11:40:51 -0400 Subject: [PATCH 048/260] CPD Fixes --- .../java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java | 4 ++-- .../org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java index 104557a4c..ba912e5a6 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java @@ -58,11 +58,11 @@ public BatchInsertModel<T> build() { } @SafeVarargs - public static <T> IntoGatherer<T> insert(T... records) { + public static <T> BatchInsertDSL.IntoGatherer<T> insert(T... records) { return insert(Arrays.asList(records)); } - public static <T> IntoGatherer<T> insert(Collection<T> records) { + public static <T> BatchInsertDSL.IntoGatherer<T> insert(Collection<T> records) { return new IntoGatherer<>(records); } diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java index 6976dabc9..7c0530a2a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java @@ -57,11 +57,11 @@ public MultiRowInsertModel<T> build() { } @SafeVarargs - public static <T> IntoGatherer<T> insert(T... records) { + public static <T> MultiRowInsertDSL.IntoGatherer<T> insert(T... records) { return insert(Arrays.asList(records)); } - public static <T> IntoGatherer<T> insert(Collection<T> records) { + public static <T> MultiRowInsertDSL.IntoGatherer<T> insert(Collection<T> records) { return new IntoGatherer<>(records); } From 4b89c48e6e08636f866e531ed7ff517a2c901c65 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 6 Aug 2024 12:53:03 -0400 Subject: [PATCH 049/260] Don't need Hamcrest anymore --- pom.xml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/pom.xml b/pom.xml index 5d5447a8f..d2ce1ecdd 100644 --- a/pom.xml +++ b/pom.xml @@ -164,14 +164,6 @@ <version>1.5.6</version> <scope>test</scope> </dependency> - <!-- Hamcrest is only here to make Infinitest happy. Not really used in the project. --> - <dependency> - <groupId>org.hamcrest</groupId> - <artifactId>hamcrest</artifactId> - <version>3.0</version> - <scope>test</scope> - </dependency> - <dependency> <groupId>org.testcontainers</groupId> <artifactId>postgresql</artifactId> From dca5d3dadc52b5d22d195a35dba3a1001f44e54d Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 6 Aug 2024 14:48:07 -0400 Subject: [PATCH 050/260] Docs --- CHANGELOG.md | 1 + src/site/markdown/docs/caseExpressions.md | 4 ++-- src/site/markdown/docs/kotlinCaseExpressions.md | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31e9fa8b3..3323eafdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ Significant changes: - The library now requires Java 17 - Deprecated code from prior releases is removed +- Allow CASE expressions in ORDER BY Clauses ## Release 1.5.2 - June 3, 2024 diff --git a/src/site/markdown/docs/caseExpressions.md b/src/site/markdown/docs/caseExpressions.md index 9b83d4f3e..3f711e626 100644 --- a/src/site/markdown/docs/caseExpressions.md +++ b/src/site/markdown/docs/caseExpressions.md @@ -3,9 +3,9 @@ Support for case expressions was added in version 1.5.1. For information about case expressions in the Kotlin DSL, see the [Kotlin Case Expressions](kotlinCaseExpressions.md) page. -## Case Statements in SQL +## Case Expressions in SQL The library supports different types of case expressions - a "simple" case expression, and a "searched" case -expressions. +expressions. Case expressions can be used in many places including select lists, order by phrases, etc. A simple case expression checks the values of a single column. It looks like this: diff --git a/src/site/markdown/docs/kotlinCaseExpressions.md b/src/site/markdown/docs/kotlinCaseExpressions.md index 5366db40b..d0fdb4b4d 100644 --- a/src/site/markdown/docs/kotlinCaseExpressions.md +++ b/src/site/markdown/docs/kotlinCaseExpressions.md @@ -3,9 +3,9 @@ Support for case expressions was added in version 1.5.1. For information about case expressions in the Java DSL, see the [Java Case Expressions](caseExpressions.md) page. -## Case Statements in SQL +## Case Expressions in SQL The library supports different types of case expressions - a "simple" case expression, and a "searched" case -expressions. +expressions. Case expressions can be used in many places including select lists, order by phrases, etc. A simple case expression checks the values of a single column. It looks like this: From b938d32d6838c8e8a45ce055ed21058d75d59d4d Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 6 Aug 2024 15:28:31 -0400 Subject: [PATCH 051/260] Update Kotlin compiler settings for JVM 17 --- pom.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 94348cd05..ff30de791 100644 --- a/pom.xml +++ b/pom.xml @@ -68,7 +68,9 @@ <module.name>org.mybatis.dynamic.sql</module.name> <kotlin.version>2.0.10</kotlin.version> - <kotlin.compiler.jvmTarget>1.8</kotlin.compiler.jvmTarget> + <kotlin.compiler.jvmTarget>17</kotlin.compiler.jvmTarget> + <kotlin.compiler.languageVersion>2.0</kotlin.compiler.languageVersion> + <kotlin.compiler.apiVersion>2.0</kotlin.compiler.apiVersion> <sonar.sources>pom.xml,src/main/java,src/main/kotlin</sonar.sources> <sonar.tests>src/test/java,src/test/kotlin</sonar.tests> From 42646b53469ec8adff0c5b71d7d15b0bbb83087c Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 6 Aug 2024 17:53:37 -0400 Subject: [PATCH 052/260] Refactor column hierarchy so we can build un-typed functions --- .../org/mybatis/dynamic/sql/BasicColumn.java | 14 +++++ .../mybatis/dynamic/sql/BindableColumn.java | 19 +------ .../org/mybatis/dynamic/sql/SqlBuilder.java | 4 ++ .../dynamic/sql/select/aggregate/Avg.java | 3 +- .../dynamic/sql/select/aggregate/Max.java | 3 +- .../dynamic/sql/select/aggregate/Min.java | 3 +- .../dynamic/sql/select/aggregate/Sum.java | 9 +++- .../AbstractTypeConvertingFunction.java | 5 +- .../function/AbstractUniTypeFunction.java | 4 +- .../dynamic/sql/select/function/Add.java | 2 +- .../dynamic/sql/select/function/Concat.java | 2 +- .../sql/select/function/Concatenate.java | 2 +- .../dynamic/sql/select/function/Divide.java | 2 +- .../dynamic/sql/select/function/Lower.java | 3 +- .../dynamic/sql/select/function/Multiply.java | 2 +- .../sql/select/function/OperatorFunction.java | 6 +-- .../sql/select/function/Substring.java | 3 +- .../dynamic/sql/select/function/Subtract.java | 2 +- .../dynamic/sql/select/function/Upper.java | 3 +- .../sql/util/kotlin/elements/SqlElements.kt | 2 + .../java/examples/animal/data/Length.java | 7 ++- .../examples/type_conversion/ToBase64.java | 3 +- .../mybatis3/canonical/PersonMapperTest.kt | 51 +++++++++++++++++++ 23 files changed, 110 insertions(+), 44 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/BasicColumn.java b/src/main/java/org/mybatis/dynamic/sql/BasicColumn.java index b73757a71..a583ba4ff 100644 --- a/src/main/java/org/mybatis/dynamic/sql/BasicColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/BasicColumn.java @@ -15,9 +15,11 @@ */ package org.mybatis.dynamic.sql; +import java.sql.JDBCType; import java.util.Optional; import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.util.FragmentAndParameters; /** @@ -58,6 +60,18 @@ public interface BasicColumn { */ FragmentAndParameters render(RenderingContext renderingContext); + default Optional<JDBCType> jdbcType() { + return Optional.empty(); + } + + default Optional<String> typeHandler() { + return Optional.empty(); + } + + default Optional<RenderingStrategy> renderingStrategy() { + return Optional.empty(); + } + /** * Utility method to make it easier to build column lists for methods that require an * array rather than the varargs method. diff --git a/src/main/java/org/mybatis/dynamic/sql/BindableColumn.java b/src/main/java/org/mybatis/dynamic/sql/BindableColumn.java index 274b52e25..77e6e5bc1 100644 --- a/src/main/java/org/mybatis/dynamic/sql/BindableColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/BindableColumn.java @@ -15,14 +15,11 @@ */ package org.mybatis.dynamic.sql; -import java.sql.JDBCType; import java.util.Optional; -import org.mybatis.dynamic.sql.render.RenderingStrategy; - /** - * Describes additional attributes of columns that are necessary for binding the column as a JDBC parameter. - * Columns in where clauses are typically bound. + * Describes a column with a known data type. The type is only used by the compiler to assure type safety + * when building clauses with conditions. * * @author Jeff Butler * @@ -37,18 +34,6 @@ public interface BindableColumn<T> extends BasicColumn { @Override BindableColumn<T> as(String alias); - default Optional<JDBCType> jdbcType() { - return Optional.empty(); - } - - default Optional<String> typeHandler() { - return Optional.empty(); - } - - default Optional<RenderingStrategy> renderingStrategy() { - return Optional.empty(); - } - default Object convertParameterType(T value) { return value; } diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java index 6516696f6..df4292653 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java @@ -497,6 +497,10 @@ static <T> Sum<T> sum(BindableColumn<T> column) { return Sum.of(column); } + static Sum<Object> sum(BasicColumn column) { + return Sum.of(column); + } + static <T> Sum<T> sum(BindableColumn<T> column, VisitableCondition<T> condition) { return Sum.of(column, condition); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Avg.java b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Avg.java index 5130abf7c..6fcb1f3b5 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Avg.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Avg.java @@ -15,6 +15,7 @@ */ package org.mybatis.dynamic.sql.select.aggregate; +import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.function.AbstractUniTypeFunction; @@ -22,7 +23,7 @@ public class Avg<T> extends AbstractUniTypeFunction<T, Avg<T>> { - private Avg(BindableColumn<T> column) { + private Avg(BasicColumn column) { super(column); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Max.java b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Max.java index f44225f12..2e3e0fec0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Max.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Max.java @@ -15,6 +15,7 @@ */ package org.mybatis.dynamic.sql.select.aggregate; +import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.function.AbstractUniTypeFunction; @@ -22,7 +23,7 @@ public class Max<T> extends AbstractUniTypeFunction<T, Max<T>> { - private Max(BindableColumn<T> column) { + private Max(BasicColumn column) { super(column); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Min.java b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Min.java index 02830335c..b376d00a2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Min.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Min.java @@ -15,6 +15,7 @@ */ package org.mybatis.dynamic.sql.select.aggregate; +import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.function.AbstractUniTypeFunction; @@ -22,7 +23,7 @@ public class Min<T> extends AbstractUniTypeFunction<T, Min<T>> { - private Min(BindableColumn<T> column) { + private Min(BasicColumn column) { super(column); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Sum.java b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Sum.java index 02c8c7a42..e86a0d5b4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Sum.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Sum.java @@ -17,6 +17,7 @@ import java.util.function.Function; +import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.VisitableCondition; import org.mybatis.dynamic.sql.render.RenderingContext; @@ -28,7 +29,7 @@ public class Sum<T> extends AbstractUniTypeFunction<T, Sum<T>> { private final Function<RenderingContext, FragmentAndParameters> renderer; - private Sum(BindableColumn<T> column) { + private Sum(BasicColumn column) { super(column); renderer = rc -> column.render(rc).mapFragment(this::applyAggregate); } @@ -48,7 +49,7 @@ private Sum(BindableColumn<T> column, VisitableCondition<T> condition) { }; } - private Sum(BindableColumn<T> column, Function<RenderingContext, FragmentAndParameters> renderer) { + private Sum(BasicColumn column, Function<RenderingContext, FragmentAndParameters> renderer) { super(column); this.renderer = renderer; } @@ -71,6 +72,10 @@ public static <T> Sum<T> of(BindableColumn<T> column) { return new Sum<>(column); } + public static Sum<Object> of(BasicColumn column) { + return new Sum<>(column); + } + public static <T> Sum<T> of(BindableColumn<T> column, VisitableCondition<T> condition) { return new Sum<>(column, condition); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractTypeConvertingFunction.java b/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractTypeConvertingFunction.java index cab8aff39..98e019fa7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractTypeConvertingFunction.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractTypeConvertingFunction.java @@ -18,6 +18,7 @@ import java.util.Objects; import java.util.Optional; +import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; /** @@ -36,10 +37,10 @@ */ public abstract class AbstractTypeConvertingFunction<T, R, U extends AbstractTypeConvertingFunction<T, R, U>> implements BindableColumn<R> { - protected final BindableColumn<T> column; + protected final BasicColumn column; protected String alias; - protected AbstractTypeConvertingFunction(BindableColumn<T> column) { + protected AbstractTypeConvertingFunction(BasicColumn column) { this.column = Objects.requireNonNull(column); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractUniTypeFunction.java b/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractUniTypeFunction.java index 7a0690bae..6e59885cb 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractUniTypeFunction.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractUniTypeFunction.java @@ -18,7 +18,7 @@ import java.sql.JDBCType; import java.util.Optional; -import org.mybatis.dynamic.sql.BindableColumn; +import org.mybatis.dynamic.sql.BasicColumn; /** * Represents a function that does not change the underlying data type. @@ -33,7 +33,7 @@ public abstract class AbstractUniTypeFunction<T, U extends AbstractUniTypeFunction<T, U>> extends AbstractTypeConvertingFunction<T, T, U> { - protected AbstractUniTypeFunction(BindableColumn<T> column) { + protected AbstractUniTypeFunction(BasicColumn column) { super(column); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/function/Add.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Add.java index fe0661bea..533f5cc15 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Add.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Add.java @@ -23,7 +23,7 @@ public class Add<T> extends OperatorFunction<T> { - private Add(BindableColumn<T> firstColumn, BasicColumn secondColumn, + private Add(BasicColumn firstColumn, BasicColumn secondColumn, List<BasicColumn> subsequentColumns) { super("+", firstColumn, secondColumn, subsequentColumns); //$NON-NLS-1$ } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/function/Concat.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Concat.java index e633b2953..ec1c7f93e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Concat.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Concat.java @@ -29,7 +29,7 @@ public class Concat<T> extends AbstractUniTypeFunction<T, Concat<T>> { private final List<BasicColumn> allColumns = new ArrayList<>(); - protected Concat(BindableColumn<T> firstColumn, List<BasicColumn> subsequentColumns) { + protected Concat(BasicColumn firstColumn, List<BasicColumn> subsequentColumns) { super(firstColumn); allColumns.add(firstColumn); this.allColumns.addAll(subsequentColumns); diff --git a/src/main/java/org/mybatis/dynamic/sql/select/function/Concatenate.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Concatenate.java index 3179f2a1d..fa16f4a43 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Concatenate.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Concatenate.java @@ -23,7 +23,7 @@ public class Concatenate<T> extends OperatorFunction<T> { - protected Concatenate(BindableColumn<T> firstColumn, BasicColumn secondColumn, + protected Concatenate(BasicColumn firstColumn, BasicColumn secondColumn, List<BasicColumn> subsequentColumns) { super("||", firstColumn, secondColumn, subsequentColumns); //$NON-NLS-1$ } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/function/Divide.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Divide.java index 24d2832ca..76d804707 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Divide.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Divide.java @@ -23,7 +23,7 @@ public class Divide<T> extends OperatorFunction<T> { - private Divide(BindableColumn<T> firstColumn, BasicColumn secondColumn, + private Divide(BasicColumn firstColumn, BasicColumn secondColumn, List<BasicColumn> subsequentColumns) { super("/", firstColumn, secondColumn, subsequentColumns); //$NON-NLS-1$ } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/function/Lower.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Lower.java index e59d04712..6bed396c0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Lower.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Lower.java @@ -15,13 +15,14 @@ */ package org.mybatis.dynamic.sql.select.function; +import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; public class Lower<T> extends AbstractUniTypeFunction<T, Lower<T>> { - private Lower(BindableColumn<T> column) { + private Lower(BasicColumn column) { super(column); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/function/Multiply.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Multiply.java index 50d38b966..de359e09c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Multiply.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Multiply.java @@ -23,7 +23,7 @@ public class Multiply<T> extends OperatorFunction<T> { - private Multiply(BindableColumn<T> firstColumn, BasicColumn secondColumn, + private Multiply(BasicColumn firstColumn, BasicColumn secondColumn, List<BasicColumn> subsequentColumns) { super("*", firstColumn, secondColumn, subsequentColumns); //$NON-NLS-1$ } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/function/OperatorFunction.java b/src/main/java/org/mybatis/dynamic/sql/select/function/OperatorFunction.java index 7ce5c5c25..7c9a89316 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/OperatorFunction.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/OperatorFunction.java @@ -35,7 +35,7 @@ public class OperatorFunction<T> extends AbstractUniTypeFunction<T, OperatorFunc protected final List<BasicColumn> subsequentColumns = new ArrayList<>(); private final String operator; - protected OperatorFunction(String operator, BindableColumn<T> firstColumn, BasicColumn secondColumn, + protected OperatorFunction(String operator, BasicColumn firstColumn, BasicColumn secondColumn, List<BasicColumn> subsequentColumns) { super(firstColumn); this.secondColumn = Objects.requireNonNull(secondColumn); @@ -52,9 +52,7 @@ protected OperatorFunction<T> copy() { public FragmentAndParameters render(RenderingContext renderingContext) { String paddedOperator = " " + operator + " "; //$NON-NLS-1$ //$NON-NLS-2$ - // note - the cast below is added for type inference issues in some compilers - return Stream.of(Stream.of((BasicColumn) column), - Stream.of(secondColumn), subsequentColumns.stream()) + return Stream.of(Stream.of(column, secondColumn), subsequentColumns.stream()) .flatMap(Function.identity()) .map(column -> column.render(renderingContext)) .collect(FragmentCollector.collect()) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/function/Substring.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Substring.java index 81b95ea5c..d49263977 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Substring.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Substring.java @@ -15,6 +15,7 @@ */ package org.mybatis.dynamic.sql.select.function; +import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; @@ -24,7 +25,7 @@ public class Substring<T> extends AbstractUniTypeFunction<T, Substring<T>> { private final int offset; private final int length; - private Substring(BindableColumn<T> column, int offset, int length) { + private Substring(BasicColumn column, int offset, int length) { super(column); this.offset = offset; this.length = length; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/function/Subtract.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Subtract.java index 94e7e3c81..8f011e902 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Subtract.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Subtract.java @@ -23,7 +23,7 @@ public class Subtract<T> extends OperatorFunction<T> { - private Subtract(BindableColumn<T> firstColumn, BasicColumn secondColumn, + private Subtract(BasicColumn firstColumn, BasicColumn secondColumn, List<BasicColumn> subsequentColumns) { super("-", firstColumn, secondColumn, subsequentColumns); //$NON-NLS-1$ } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/function/Upper.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Upper.java index 2891032df..a62e5d655 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Upper.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Upper.java @@ -15,13 +15,14 @@ */ package org.mybatis.dynamic.sql.select.function; +import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; public class Upper<T> extends AbstractUniTypeFunction<T, Upper<T>> { - private Upper(BindableColumn<T> column) { + private Upper(BasicColumn column) { super(column); } diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt index 2d9f1e8a1..8a249279a 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt @@ -137,6 +137,8 @@ fun <T> avg(column: BindableColumn<T>): Avg<T> = SqlBuilder.avg(column) fun <T> sum(column: BindableColumn<T>): Sum<T> = SqlBuilder.sum(column) +fun sum(column: BasicColumn): Sum<*> = SqlBuilder.sum(column) + fun <T> sum(column: BindableColumn<T>, condition: VisitableCondition<T>): Sum<T> = SqlBuilder.sum(column, condition) // constants diff --git a/src/test/java/examples/animal/data/Length.java b/src/test/java/examples/animal/data/Length.java index cf779c15e..6fb90e40d 100644 --- a/src/test/java/examples/animal/data/Length.java +++ b/src/test/java/examples/animal/data/Length.java @@ -18,13 +18,14 @@ import java.sql.JDBCType; import java.util.Optional; +import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.function.AbstractTypeConvertingFunction; import org.mybatis.dynamic.sql.util.FragmentAndParameters; public class Length extends AbstractTypeConvertingFunction<Object, Integer, Length> { - private Length(BindableColumn<Object> column) { + private Length(BasicColumn column) { super(column); } @@ -48,8 +49,6 @@ protected Length copy() { } public static Length length(BindableColumn<?> column) { - @SuppressWarnings("unchecked") - BindableColumn<Object> c = (BindableColumn<Object>) column; - return new Length(c); + return new Length(column); } } diff --git a/src/test/java/examples/type_conversion/ToBase64.java b/src/test/java/examples/type_conversion/ToBase64.java index 97d8ad097..ce5ab5891 100644 --- a/src/test/java/examples/type_conversion/ToBase64.java +++ b/src/test/java/examples/type_conversion/ToBase64.java @@ -18,6 +18,7 @@ import java.sql.JDBCType; import java.util.Optional; +import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.function.AbstractTypeConvertingFunction; @@ -25,7 +26,7 @@ public class ToBase64 extends AbstractTypeConvertingFunction<byte[], String, ToBase64> { - protected ToBase64(BindableColumn<byte[]> column) { + protected ToBase64(BasicColumn column) { super(column); } diff --git a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperTest.kt index 5dc24ede2..75a703c09 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperTest.kt @@ -35,13 +35,18 @@ import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance.Lifecycle import org.mybatis.dynamic.sql.exception.NonRenderingWhereClauseException import org.mybatis.dynamic.sql.util.kotlin.elements.add +import org.mybatis.dynamic.sql.util.kotlin.elements.case +import org.mybatis.dynamic.sql.util.kotlin.elements.concat import org.mybatis.dynamic.sql.util.kotlin.elements.constant import org.mybatis.dynamic.sql.util.kotlin.elements.isIn import org.mybatis.dynamic.sql.util.kotlin.elements.sortColumn +import org.mybatis.dynamic.sql.util.kotlin.elements.stringConstant +import org.mybatis.dynamic.sql.util.kotlin.elements.sum import org.mybatis.dynamic.sql.util.kotlin.mybatis3.insertInto import org.mybatis.dynamic.sql.util.kotlin.mybatis3.insertSelect import org.mybatis.dynamic.sql.util.kotlin.mybatis3.multiSelect import org.mybatis.dynamic.sql.util.kotlin.mybatis3.select +import org.mybatis.dynamic.sql.util.mybatis3.CommonSelectMapper import java.util.* @TestInstance(Lifecycle.PER_CLASS) @@ -55,6 +60,7 @@ class PersonMapperTest { withMapper(PersonMapper::class) withMapper(PersonWithAddressMapper::class) withMapper(AddressMapper::class) + withMapper(CommonSelectMapper::class) withTypeHandler(YesNoTypeHandler::class) } } @@ -917,4 +923,49 @@ class PersonMapperTest { "where id in ()" assertThat(selectStatement.selectStatement).isEqualTo(expected) } + + @Test + fun testSumWithCase() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(CommonSelectMapper::class.java) + + val selectStatement = select(id, sum(case { + `when` { + id isEqualTo 1 + then(101) + } + `else`(999) + }).`as`("fred")) { + from(person) + groupBy(id) + } + + val expected = + "select id, sum(case when id = #{parameters.p1,jdbcType=INTEGER} then 101 else 999 end) as fred from Person group by id" + assertThat(selectStatement.selectStatement).isEqualTo(expected) + + val rows = mapper.selectManyMappedRows(selectStatement) + assertThat(rows).hasSize(6) + } + } + + @Test + fun testConcat() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(CommonSelectMapper::class.java) + + val selectStatement = select(id, concat(firstName, stringConstant(" "), lastName).`as`("fullname")) { + from(person) + where { concat(firstName, stringConstant(" "), lastName) isEqualTo "Fred Flintstone" } + } + + val expected = + "select id, concat(first_name, ' ', last_name) as fullname from Person " + + "where concat(first_name, ' ', last_name) = #{parameters.p1,jdbcType=VARCHAR}" + assertThat(selectStatement.selectStatement).isEqualTo(expected) + + val rows = mapper.selectManyMappedRows(selectStatement) + assertThat(rows).hasSize(1) + } + } } From a7663060c6b180b9eab9b374ddee73e0caf6ef7c Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 7 Aug 2024 11:59:55 -0400 Subject: [PATCH 053/260] Docs --- CHANGELOG.md | 16 ++++++++++++++- src/site/markdown/docs/extending.md | 30 ++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3323eafdb..dddb1c222 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,21 @@ This log will detail notable changes to MyBatis Dynamic SQL. Full details are av ## Release 2.0.0 - Unreleased -Significant changes: +Release 2.0.0 is a significant milestone for the library. We have moved to Java 17 as the minimum version supported. If +you are unable to move to this version of Java then the releases in the 1.x line can be used with Java 8. + +In addition, we have taken the opportunity to make changes to the library that may break existing code. We have +worked to make these changes as minimal as possible. + +**Potentially Breaking Changes:** + +- If you have implemented any custom functions, you will likely need to make changes. The supplied base classes now + hold an instance of `BasicColumn` rather than `BindableColumn`. This change was made to make the functions more + useful in variety of circumstances. If you follow the patterns shown on the + [Extending the Library](https://mybatis.org/mybatis-dynamic-sql/docs/extending.html) page, the change should be as + minimal as changing the private constructor to accept `BasicColumn` rather than `BindableColumn`. + +Other important changes: - The library now requires Java 17 - Deprecated code from prior releases is removed diff --git a/src/site/markdown/docs/extending.md b/src/site/markdown/docs/extending.md index ae04f434a..a32dea137 100644 --- a/src/site/markdown/docs/extending.md +++ b/src/site/markdown/docs/extending.md @@ -11,10 +11,10 @@ The SELECT support is the most complex part of the library, and also the part of extended. There are two main interfaces involved with extending the SELECT support. Picking which interface to implement is dependent on how you want to use your extension. -| Interface | Purpose | -|------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------| -| `org.mybatis.dynamic.sql.BasicColumn` | Use this interface if you want to add capabilities to a SELECT list or a GROUP BY expression. For example, using a database function. | -| `org.mybatis.dynamic.sql.BindableColumn` | Use this interface if you want to add capabilities to a WHERE clause. For example, creating a custom condition. | +| Interface | Purpose | +|------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `org.mybatis.dynamic.sql.BasicColumn` | Use this interface if you want to add capabilities to a SELECT list, a GROUP BY, or an ORDER BY expression. For example, using a database function. | +| `org.mybatis.dynamic.sql.BindableColumn` | Use this interface if you want to add capabilities to a WHERE clause in addition to the capabilities of `BasicColumn`. For example, creating a custom condition. | Rendering is the process of generating an appropriate SQL fragment to implement the function or calculated column. The library will call a method `render(RenderingContext)` in your implementation. This method should return an @@ -101,6 +101,7 @@ the function changes the data type from `byte[]` to `String`. import java.sql.JDBCType; import java.util.Optional; +import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.function.AbstractTypeConvertingFunction; @@ -108,7 +109,7 @@ import org.mybatis.dynamic.sql.util.FragmentAndParameters; public class ToBase64 extends AbstractTypeConvertingFunction<byte[], String, ToBase64> { - protected ToBase64(BindableColumn<byte[]> column) { + private ToBase64(BasicColumn column) { super(column); } @@ -143,13 +144,15 @@ public class ToBase64 extends AbstractTypeConvertingFunction<byte[], String, ToB The following function implements the common database `UPPER()` function. ```java +import org.mybatis.dynamic.sql.BasicColumn; +import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.function.AbstractUniTypeFunction; import org.mybatis.dynamic.sql.util.FragmentAndParameters; public class Upper extends AbstractUniTypeFunction<String, Upper> { - private Upper(BindableColumn<String> column) { + private Upper(BasicColumn column) { super(column); } @@ -178,19 +181,21 @@ Note that `FragmentAndParameters` has a utility method that can simplify the imp add any new parameters to the resulting fragment. For example, the UPPER function can be simplified as follows: ```java +import org.mybatis.dynamic.sql.BasicColumn; +import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.function.AbstractUniTypeFunction; import org.mybatis.dynamic.sql.util.FragmentAndParameters; public class Upper extends AbstractUniTypeFunction<String, Upper> { - private Upper(BindableColumn<String> column) { + private Upper(BasicColumn column) { super(column); } @Override public FragmentAndParameters render(RenderingContext renderingContext) { - return = column.render(renderingContext).mapFragment(f -> "upper(" + f + ")"); //$NON-NLS-1$ //$NON-NLS-2$ + return column.render(renderingContext).mapFragment(f -> "upper(" + f + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } @Override @@ -211,9 +216,16 @@ The following function implements the concatenate operator. Note that the operat arbitrary length: ```java +import java.util.Arrays; +import java.util.List; + +import org.mybatis.dynamic.sql.BasicColumn; +import org.mybatis.dynamic.sql.BindableColumn; +import org.mybatis.dynamic.sql.select.function.OperatorFunction; + public class Concatenate<T> extends OperatorFunction<T> { - protected Concatenate(BindableColumn<T> firstColumn, BasicColumn secondColumn, + protected Concatenate(BasicColumn firstColumn, BasicColumn secondColumn, List<BasicColumn> subsequentColumns) { super("||", firstColumn, secondColumn, subsequentColumns); //$NON-NLS-1$ } From 406220c18530511337225813ef24abc83a5bb2f5 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 7 Aug 2024 15:07:35 -0400 Subject: [PATCH 054/260] Docs --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dddb1c222..9f3da4db9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,14 +15,14 @@ worked to make these changes as minimal as possible. - If you have implemented any custom functions, you will likely need to make changes. The supplied base classes now hold an instance of `BasicColumn` rather than `BindableColumn`. This change was made to make the functions more useful in variety of circumstances. If you follow the patterns shown on the - [Extending the Library](https://mybatis.org/mybatis-dynamic-sql/docs/extending.html) page, the change should be as - minimal as changing the private constructor to accept `BasicColumn` rather than `BindableColumn`. + [Extending the Library](https://mybatis.org/mybatis-dynamic-sql/docs/extending.html) page, the change should be + limited to changing the private constructor to accept `BasicColumn` rather than `BindableColumn`. Other important changes: - The library now requires Java 17 - Deprecated code from prior releases is removed -- Allow CASE expressions in ORDER BY Clauses +- We now allow CASE expressions in ORDER BY Clauses ## Release 1.5.2 - June 3, 2024 From e5ba7c95f6f2ba1d9923328cab5db57f7e527e2a Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 7 Aug 2024 16:39:44 -0400 Subject: [PATCH 055/260] Remove Deprecated sortSpecification Methods These methods are likely not used outside the library itself, so the risk of a breaking change is low --- CHANGELOG.md | 3 + .../dynamic/sql/SortSpecification.java | 39 +--- .../dynamic/sql/util/messages.properties | 2 - .../sql/DeprecatedSortMethodsTest.java | 173 ------------------ 4 files changed, 9 insertions(+), 208 deletions(-) delete mode 100644 src/test/java/org/mybatis/dynamic/sql/DeprecatedSortMethodsTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f3da4db9..2e35e5e63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,9 @@ worked to make these changes as minimal as possible. **Potentially Breaking Changes:** +- If you have implemented any custom implementations of `SortSpecification`, you will need to update those + implementations due to a new rendering strategy for ORDER BY phrases. The old methods `isDescending` and `orderByName` + are removed in favor of a new method `renderForOrderBy` - If you have implemented any custom functions, you will likely need to make changes. The supplied base classes now hold an instance of `BasicColumn` rather than `BindableColumn`. This change was made to make the functions more useful in variety of circumstances. If you follow the patterns shown on the diff --git a/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java b/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java index 48aee58c4..05ba42e30 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java +++ b/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java @@ -15,10 +15,8 @@ */ package org.mybatis.dynamic.sql; -import org.mybatis.dynamic.sql.exception.DynamicSqlException; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -import org.mybatis.dynamic.sql.util.Messages; /** * Defines attributes of columns that are necessary for rendering an order by expression. @@ -35,37 +33,12 @@ public interface SortSpecification { SortSpecification descending(); /** - * Return the phrase that should be written into a rendered order by clause. This should - * NOT include the "DESC" word for descending sort specifications. + * Return a fragment rendered for use in an ORDER BY clause. The fragment should include "DESC" if a + * descending order is desired. * - * @return the order by phrase - * @deprecated Please replace this method by overriding the more general "renderForOrderBy" method. Target for - * removal in release 2.1 + * @param renderingContext the current rendering context + * @return a rendered fragment and parameters is applicable + * @since 2.0.0 */ - @Deprecated(since = "2.0", forRemoval = true) - default String orderByName() { - throw new DynamicSqlException(Messages.getString("ERROR.44")); //$NON-NLS-1$ - } - - /** - * Return true if the sort order is descending. - * - * @return true if the SortSpecification should render as descending - * @deprecated Please replace this method by overriding the more general "renderForOrderBy" method. Target for - * removal in release 2.1 - */ - @Deprecated(since = "2.0", forRemoval = true) - default boolean isDescending() { - throw new DynamicSqlException(Messages.getString("ERROR.44")); //$NON-NLS-1$ - } - - // the default implementation ensures compatibility with prior releases. When the - // deprecated methods are removed, this function can become purely abstract. - default FragmentAndParameters renderForOrderBy(RenderingContext renderingContext) { - String phrase = orderByName(); - if (isDescending()) { - phrase = phrase + " DESC"; //$NON-NLS-1$ - } - return FragmentAndParameters.fromFragment(phrase); - } + FragmentAndParameters renderForOrderBy(RenderingContext renderingContext); } diff --git a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties index c7e90f7e5..c25eb02c5 100644 --- a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties +++ b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties @@ -60,6 +60,4 @@ ERROR.40=Case expressions must have at least one "when" clause ERROR.41=You cannot call "then" in a Kotlin case expression more than once ERROR.42=You cannot call `else` in a Kotlin case expression more than once ERROR.43=A Kotlin cast expression must have one, and only one, `as` element -ERROR.44=You must either implement the "renderForOrderBy" method or both "orderByName" and "isDescending" methods in a \ - sort specification INTERNAL.ERROR=Internal Error {0} diff --git a/src/test/java/org/mybatis/dynamic/sql/DeprecatedSortMethodsTest.java b/src/test/java/org/mybatis/dynamic/sql/DeprecatedSortMethodsTest.java deleted file mode 100644 index 520783155..000000000 --- a/src/test/java/org/mybatis/dynamic/sql/DeprecatedSortMethodsTest.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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 static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -import java.util.List; - -import org.junit.jupiter.api.Test; -import org.mybatis.dynamic.sql.common.OrderByModel; -import org.mybatis.dynamic.sql.common.OrderByRenderer; -import org.mybatis.dynamic.sql.configuration.StatementConfiguration; -import org.mybatis.dynamic.sql.exception.DynamicSqlException; -import org.mybatis.dynamic.sql.render.RenderingContext; -import org.mybatis.dynamic.sql.render.RenderingStrategies; -import org.mybatis.dynamic.sql.render.TableAliasCalculator; -import org.mybatis.dynamic.sql.util.FragmentAndParameters; -import org.mybatis.dynamic.sql.util.Messages; - -class DeprecatedSortMethodsTest { - - @Test - void bothMethodsExist() { - SortSpecification ss = new SortSpecification() { - @Override - public SortSpecification descending() { - return this; - } - - @Override - public String orderByName() { - return "id"; - } - - @Override - public boolean isDescending() { - return false; - } - }; - - OrderByModel model = OrderByModel.of(List.of(ss)); - - RenderingContext renderingContext = RenderingContext - .withRenderingStrategy(RenderingStrategies.MYBATIS3) - .withTableAliasCalculator(TableAliasCalculator.empty()) - .withStatementConfiguration(new StatementConfiguration()) - .build(); - OrderByRenderer renderer = new OrderByRenderer(renderingContext); - FragmentAndParameters fp = renderer.render(model); - assertThat(fp.fragment()).isEqualTo("order by id"); - } - - @Test - void bothMethodsExistDescending() { - SortSpecification ss = new SortSpecification() { - @Override - public SortSpecification descending() { - return this; - } - - @Override - public String orderByName() { - return "id"; - } - - @Override - public boolean isDescending() { - return true; - } - }; - - OrderByModel model = OrderByModel.of(List.of(ss)); - - RenderingContext renderingContext = RenderingContext - .withRenderingStrategy(RenderingStrategies.MYBATIS3) - .withTableAliasCalculator(TableAliasCalculator.empty()) - .withStatementConfiguration(new StatementConfiguration()) - .build(); - OrderByRenderer renderer = new OrderByRenderer(renderingContext); - FragmentAndParameters fp = renderer.render(model); - assertThat(fp.fragment()).isEqualTo("order by id DESC"); - } - - @Test - void orderByNameMethodMissing() { - SortSpecification ss = new SortSpecification() { - @Override - public SortSpecification descending() { - return this; - } - - @Override - public boolean isDescending() { - return true; - } - }; - - OrderByModel model = OrderByModel.of(List.of(ss)); - - RenderingContext renderingContext = RenderingContext - .withRenderingStrategy(RenderingStrategies.MYBATIS3) - .withTableAliasCalculator(TableAliasCalculator.empty()) - .withStatementConfiguration(new StatementConfiguration()) - .build(); - OrderByRenderer renderer = new OrderByRenderer(renderingContext); - assertThatExceptionOfType(DynamicSqlException.class) - .isThrownBy(() -> renderer.render(model)) - .withMessage(Messages.getString("ERROR.44")); - } - - @Test - void isDescendingMethodMissing() { - SortSpecification ss = new SortSpecification() { - @Override - public SortSpecification descending() { - return this; - } - - @Override - public String orderByName() { - return "id"; - } - }; - - OrderByModel model = OrderByModel.of(List.of(ss)); - - RenderingContext renderingContext = RenderingContext - .withRenderingStrategy(RenderingStrategies.MYBATIS3) - .withTableAliasCalculator(TableAliasCalculator.empty()) - .withStatementConfiguration(new StatementConfiguration()) - .build(); - OrderByRenderer renderer = new OrderByRenderer(renderingContext); - assertThatExceptionOfType(DynamicSqlException.class) - .isThrownBy(() -> renderer.render(model)) - .withMessage(Messages.getString("ERROR.44")); - } - - @Test - void bothMethodsMissing() { - SortSpecification ss = new SortSpecification() { - @Override - public SortSpecification descending() { - return this; - } - }; - - OrderByModel model = OrderByModel.of(List.of(ss)); - - RenderingContext renderingContext = RenderingContext - .withRenderingStrategy(RenderingStrategies.MYBATIS3) - .withTableAliasCalculator(TableAliasCalculator.empty()) - .withStatementConfiguration(new StatementConfiguration()) - .build(); - OrderByRenderer renderer = new OrderByRenderer(renderingContext); - assertThatExceptionOfType(DynamicSqlException.class) - .isThrownBy(() -> renderer.render(model)) - .withMessage(Messages.getString("ERROR.44")); - } -} From f9209112bb855c7f00575db11ce7994f4849dc80 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 7 Aug 2024 16:43:32 -0400 Subject: [PATCH 056/260] Typo --- CHANGELOG.md | 2 +- src/main/java/org/mybatis/dynamic/sql/SortSpecification.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e35e5e63..1ef040d6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ worked to make these changes as minimal as possible. **Potentially Breaking Changes:** -- If you have implemented any custom implementations of `SortSpecification`, you will need to update those +- If you have created any custom implementations of `SortSpecification`, you will need to update those implementations due to a new rendering strategy for ORDER BY phrases. The old methods `isDescending` and `orderByName` are removed in favor of a new method `renderForOrderBy` - If you have implemented any custom functions, you will likely need to make changes. The supplied base classes now diff --git a/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java b/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java index 05ba42e30..0fd0da18f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java +++ b/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java @@ -37,7 +37,7 @@ public interface SortSpecification { * descending order is desired. * * @param renderingContext the current rendering context - * @return a rendered fragment and parameters is applicable + * @return a rendered fragment and parameters if applicable * @since 2.0.0 */ FragmentAndParameters renderForOrderBy(RenderingContext renderingContext); From 06a52b9a442929fcc1ab8845df5bba26827c0079 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 8 Aug 2024 12:26:53 -0400 Subject: [PATCH 057/260] Add @Serial annotation to exceptions --- .../dynamic/sql/exception/DuplicateTableAliasException.java | 2 ++ .../org/mybatis/dynamic/sql/exception/DynamicSqlException.java | 3 +++ .../org/mybatis/dynamic/sql/exception/InvalidSqlException.java | 3 +++ .../sql/exception/NonRenderingWhereClauseException.java | 3 +++ 4 files changed, 11 insertions(+) diff --git a/src/main/java/org/mybatis/dynamic/sql/exception/DuplicateTableAliasException.java b/src/main/java/org/mybatis/dynamic/sql/exception/DuplicateTableAliasException.java index ee8c1e2d1..89ad51fdb 100644 --- a/src/main/java/org/mybatis/dynamic/sql/exception/DuplicateTableAliasException.java +++ b/src/main/java/org/mybatis/dynamic/sql/exception/DuplicateTableAliasException.java @@ -15,6 +15,7 @@ */ package org.mybatis.dynamic.sql.exception; +import java.io.Serial; import java.util.Objects; import org.mybatis.dynamic.sql.SqlTable; @@ -34,6 +35,7 @@ */ public class DuplicateTableAliasException extends DynamicSqlException { + @Serial private static final long serialVersionUID = -2631664872557787391L; public DuplicateTableAliasException(SqlTable table, String newAlias, String existingAlias) { diff --git a/src/main/java/org/mybatis/dynamic/sql/exception/DynamicSqlException.java b/src/main/java/org/mybatis/dynamic/sql/exception/DynamicSqlException.java index 3a8bc5791..df7d61ce0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/exception/DynamicSqlException.java +++ b/src/main/java/org/mybatis/dynamic/sql/exception/DynamicSqlException.java @@ -15,7 +15,10 @@ */ package org.mybatis.dynamic.sql.exception; +import java.io.Serial; + public class DynamicSqlException extends RuntimeException { + @Serial private static final long serialVersionUID = 349021672061361244L; public DynamicSqlException(String message) { diff --git a/src/main/java/org/mybatis/dynamic/sql/exception/InvalidSqlException.java b/src/main/java/org/mybatis/dynamic/sql/exception/InvalidSqlException.java index 51ce3f787..ee1a13a9d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/exception/InvalidSqlException.java +++ b/src/main/java/org/mybatis/dynamic/sql/exception/InvalidSqlException.java @@ -15,7 +15,10 @@ */ package org.mybatis.dynamic.sql.exception; +import java.io.Serial; + public class InvalidSqlException extends DynamicSqlException { + @Serial private static final long serialVersionUID = 1666851020951347843L; public InvalidSqlException(String message) { diff --git a/src/main/java/org/mybatis/dynamic/sql/exception/NonRenderingWhereClauseException.java b/src/main/java/org/mybatis/dynamic/sql/exception/NonRenderingWhereClauseException.java index 3dfa0ed36..23210e5a4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/exception/NonRenderingWhereClauseException.java +++ b/src/main/java/org/mybatis/dynamic/sql/exception/NonRenderingWhereClauseException.java @@ -19,6 +19,8 @@ import org.mybatis.dynamic.sql.configuration.StatementConfiguration; import org.mybatis.dynamic.sql.util.Messages; +import java.io.Serial; + /** * This exception is thrown when the where clause in a statement will not render. * This can happen if all the optional conditions in a where clause fail to @@ -40,6 +42,7 @@ * @author Jeff Butler */ public class NonRenderingWhereClauseException extends DynamicSqlException { + @Serial private static final long serialVersionUID = 6619119078542625135L; public NonRenderingWhereClauseException() { From f03663176d3eea6286bc5e6c6646c3b7d39936ed Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 8 Aug 2024 12:28:47 -0400 Subject: [PATCH 058/260] Throw InvalidSqlException during rendering if an In condition is empty This changes the prior behavior where the condition would render as invalid SQL and a runtime exception from the database was expected. --- CHANGELOG.md | 4 + .../mybatis/dynamic/sql/util/Validator.java | 18 +- .../dynamic/sql/where/condition/IsIn.java | 2 + .../where/condition/IsInCaseInsensitive.java | 2 + .../dynamic/sql/where/condition/IsNotIn.java | 2 + .../condition/IsNotInCaseInsensitive.java | 2 + .../dynamic/sql/util/messages.properties | 1 + src/site/markdown/docs/conditions.md | 14 +- .../data/VariousListConditionsTest.java | 178 ++++++------------ .../sql/select/SelectStatementTest.java | 24 --- .../mybatis3/canonical/PersonMapperTest.kt | 12 -- 11 files changed, 83 insertions(+), 176 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ef040d6c..010c421c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,10 @@ Other important changes: - The library now requires Java 17 - Deprecated code from prior releases is removed - We now allow CASE expressions in ORDER BY Clauses +- The "In" conditions will now throw `InvalidSqlException` during rendering if the list of values is empty. Previously + an empty In condition would render as invalid SQL and would usually cause a runtime exception from the database. + With this change, the exception thrown is more predictable and the error is caught before sending the SQL to the + database. ## Release 1.5.2 - June 3, 2024 diff --git a/src/main/java/org/mybatis/dynamic/sql/util/Validator.java b/src/main/java/org/mybatis/dynamic/sql/util/Validator.java index 1d4b3f7b8..47814c7a2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/Validator.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/Validator.java @@ -26,12 +26,20 @@ public static void assertNotEmpty(Collection<?> collection, String messageNumber assertFalse(collection.isEmpty(), messageNumber); } + public static void assertNotEmpty(Collection<?> collection, String messageNumber, String p1) { + assertFalse(collection.isEmpty(), messageNumber, p1); + } + public static void assertFalse(boolean condition, String messageNumber) { - internalAssertFalse(condition, Messages.getString(messageNumber)); + if (condition) { + throw new InvalidSqlException(Messages.getString(messageNumber)); + } } public static void assertFalse(boolean condition, String messageNumber, String p1) { - internalAssertFalse(condition, Messages.getString(messageNumber, p1)); + if (condition) { + throw new InvalidSqlException(Messages.getString(messageNumber, p1)); + } } public static void assertTrue(boolean condition, String messageNumber) { @@ -41,10 +49,4 @@ public static void assertTrue(boolean condition, String messageNumber) { public static void assertTrue(boolean condition, String messageNumber, String p1) { assertFalse(!condition, messageNumber, p1); } - - private static void internalAssertFalse(boolean condition, String message) { - if (condition) { - throw new InvalidSqlException(message); - } - } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java index ce00047b5..ef6979b67 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java @@ -23,6 +23,7 @@ import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.util.Validator; public class IsIn<T> extends AbstractListValueCondition<T> { private static final IsIn<?> EMPTY = new IsIn<>(Collections.emptyList()); @@ -39,6 +40,7 @@ protected IsIn(Collection<T> values) { @Override public boolean shouldRender(RenderingContext renderingContext) { + Validator.assertNotEmpty(values, "ERROR.44", "IsIn"); //$NON-NLS-1$ //$NON-NLS-2$ return true; } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java index 3fe30c1ef..274226158 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java @@ -24,6 +24,7 @@ import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.StringUtilities; +import org.mybatis.dynamic.sql.util.Validator; public class IsInCaseInsensitive extends AbstractListValueCondition<String> implements CaseInsensitiveVisitableCondition { @@ -39,6 +40,7 @@ protected IsInCaseInsensitive(Collection<String> values) { @Override public boolean shouldRender(RenderingContext renderingContext) { + Validator.assertNotEmpty(values, "ERROR.44", "IsInCaseInsensitive"); //$NON-NLS-1$ //$NON-NLS-2$ return true; } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java index dc7358b2a..9c621f00b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java @@ -23,6 +23,7 @@ import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.util.Validator; public class IsNotIn<T> extends AbstractListValueCondition<T> { private static final IsNotIn<?> EMPTY = new IsNotIn<>(Collections.emptyList()); @@ -39,6 +40,7 @@ protected IsNotIn(Collection<T> values) { @Override public boolean shouldRender(RenderingContext renderingContext) { + Validator.assertNotEmpty(values, "ERROR.44", "IsNotIn"); //$NON-NLS-1$ //$NON-NLS-2$ return true; } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java index fa43af0b6..e91e893c6 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java @@ -24,6 +24,7 @@ import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.StringUtilities; +import org.mybatis.dynamic.sql.util.Validator; public class IsNotInCaseInsensitive extends AbstractListValueCondition<String> implements CaseInsensitiveVisitableCondition { @@ -39,6 +40,7 @@ protected IsNotInCaseInsensitive(Collection<String> values) { @Override public boolean shouldRender(RenderingContext renderingContext) { + Validator.assertNotEmpty(values, "ERROR.44", "IsNotInCaseInsensitive"); //$NON-NLS-1$ //$NON-NLS-2$ return true; } diff --git a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties index c25eb02c5..ef092e651 100644 --- a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties +++ b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties @@ -60,4 +60,5 @@ ERROR.40=Case expressions must have at least one "when" clause ERROR.41=You cannot call "then" in a Kotlin case expression more than once ERROR.42=You cannot call `else` in a Kotlin case expression more than once ERROR.43=A Kotlin cast expression must have one, and only one, `as` element +ERROR.44={0} conditions must contain at least one value INTERNAL.ERROR=Internal Error {0} diff --git a/src/site/markdown/docs/conditions.md b/src/site/markdown/docs/conditions.md index 55a2e6617..2e266e22b 100644 --- a/src/site/markdown/docs/conditions.md +++ b/src/site/markdown/docs/conditions.md @@ -204,8 +204,8 @@ mapping if you so desire. Starting with version 1.5.2, we made a change to the rendering rules for the "in" conditions. This was done to limit the danger of conditions failing to render and thus affecting more rows than expected. For the base conditions ("isIn", -"isNotIn", etc.), if the list of values is empty, then the condition will still render, but the resulting SQL will -be invalid and will cause a runtime exception. We believe this is the safest outcome. For example, suppose +"isNotIn", etc.), if the list of values is empty, then the library will throw +`org.mybatis.dynamic.sql.exception.InvalidSqlException`. We believe this is the safest outcome. For example, suppose a DELETE statement was coded as follows: ```java @@ -214,12 +214,6 @@ a DELETE statement was coded as follows: .and(id, isIn(Collections.emptyList())); ``` -This statement will be rendered as follows: - -```sql - delete from foo where status = ? and id in () -``` - This will cause a runtime error due to invalid SQL, but it eliminates the possibility of deleting ALL rows with active status. If you want to allow the "in" condition to drop from the SQL if the list is empty, then use the "inWhenPresent" condition. @@ -229,8 +223,8 @@ and the case-insensitive versions of these conditions: | Input | Effect | |------------------------------------------|-----------------------------------------------------------------------------------| -| isIn(null) | NullPointerException | -| isIn(Collections.emptyList()) | Rendered as "in ()" (Invalid SQL) | +| isIn(null) | NullPointerException thrown | +| isIn(Collections.emptyList()) | InvalidSqlException thrown | | isIn(2, 3, null) | Rendered as "in (?, ?, ?)" (Parameter values are 2, 3, and null) | | isInWhenPresent(null) | Condition Not Rendered | | isInWhenPresent(Collections.emptyList()) | Condition Not Rendered | diff --git a/src/test/java/examples/animal/data/VariousListConditionsTest.java b/src/test/java/examples/animal/data/VariousListConditionsTest.java index 469b64718..4e71ef668 100644 --- a/src/test/java/examples/animal/data/VariousListConditionsTest.java +++ b/src/test/java/examples/animal/data/VariousListConditionsTest.java @@ -34,14 +34,12 @@ import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DriverManager; -import java.sql.SQLSyntaxErrorException; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; 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; @@ -51,8 +49,10 @@ import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mybatis.dynamic.sql.exception.InvalidSqlException; import org.mybatis.dynamic.sql.render.RenderingStrategies; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; +import org.mybatis.dynamic.sql.util.Messages; import org.mybatis.dynamic.sql.util.mybatis3.CommonSelectMapper; class VariousListConditionsTest { @@ -136,26 +136,15 @@ void testInWhenPresentWithNull() { @Test void testInWithEmptyList() { - try (SqlSession sqlSession = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(id, animalName) - .from(animalData) - .where(id, isIn(Collections.emptyList())) - .orderBy(id) - .build() - .render(RenderingStrategies.MYBATIS3); - - assertThat(selectStatement.getSelectStatement()).isEqualTo( - "select id, animal_name from AnimalData " + - "where id in () " + - "order by id" - ); - - assertThatExceptionOfType(PersistenceException.class).isThrownBy(() -> - mapper.selectManyMappedRows(selectStatement) - ).withCauseInstanceOf(SQLSyntaxErrorException.class); - } + var selectModel = select(id, animalName) + .from(animalData) + .where(id, isIn(Collections.emptyList())) + .orderBy(id) + .build(); + + assertThatExceptionOfType(InvalidSqlException.class) + .isThrownBy(() -> selectModel.render(RenderingStrategies.MYBATIS3)) + .withMessage(Messages.getString("ERROR.44", "IsIn")); } @Test @@ -319,121 +308,66 @@ void testNotInCaseInsensitiveWhenPresentMap() { @Test void testInEventuallyEmpty() { - try (SqlSession sqlSession = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(id, animalName) - .from(animalData) - .where(id, isIn(1, 2).filter(s -> false)) - .orderBy(id) - .build() - .render(RenderingStrategies.MYBATIS3); - - assertThat(selectStatement.getSelectStatement()).isEqualTo( - "select id, animal_name from AnimalData " + - "where id in () " + - "order by id" - ); - - assertThatExceptionOfType(PersistenceException.class).isThrownBy( - () -> mapper.selectManyMappedRows(selectStatement)) - .withCauseInstanceOf(SQLSyntaxErrorException.class); - } + var selectModel = select(id, animalName) + .from(animalData) + .where(id, isIn(1, 2).filter(s -> false)) + .orderBy(id) + .build(); + + assertThatExceptionOfType(InvalidSqlException.class) + .isThrownBy(() -> selectModel.render(RenderingStrategies.MYBATIS3)) + .withMessage(Messages.getString("ERROR.44", "IsIn")); } @Test void testInCaseInsensitiveEventuallyEmpty() { - try (SqlSession sqlSession = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(id, animalName) - .from(animalData) - .where(animalName, isInCaseInsensitive("Fred", "Betty").filter(s -> false)) - .orderBy(id) - .build() - .render(RenderingStrategies.MYBATIS3); - - assertThat(selectStatement.getSelectStatement()).isEqualTo( - "select id, animal_name from AnimalData " + - "where upper(animal_name) in () " + - "order by id" - ); - - assertThatExceptionOfType(PersistenceException.class).isThrownBy( - () -> mapper.selectManyMappedRows(selectStatement)) - .withCauseInstanceOf(SQLSyntaxErrorException.class); - } + var selectModel = select(id, animalName) + .from(animalData) + .where(animalName, isInCaseInsensitive("Fred", "Betty").filter(s -> false)) + .orderBy(id) + .build(); + + assertThatExceptionOfType(InvalidSqlException.class) + .isThrownBy(() -> selectModel.render(RenderingStrategies.MYBATIS3)) + .withMessage(Messages.getString("ERROR.44", "IsInCaseInsensitive")); } @Test void testNotInEventuallyEmpty() { - try (SqlSession sqlSession = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(id, animalName) - .from(animalData) - .where(id, isNotIn(1, 2).filter(s -> false)) - .orderBy(id) - .build() - .render(RenderingStrategies.MYBATIS3); - - assertThat(selectStatement.getSelectStatement()).isEqualTo( - "select id, animal_name from AnimalData " + - "where id not in () " + - "order by id" - ); - - assertThatExceptionOfType(PersistenceException.class).isThrownBy( - () -> mapper.selectManyMappedRows(selectStatement)) - .withCauseInstanceOf(SQLSyntaxErrorException.class); - } + var selectModel = select(id, animalName) + .from(animalData) + .where(id, isNotIn(1, 2).filter(s -> false)) + .orderBy(id) + .build(); + + assertThatExceptionOfType(InvalidSqlException.class) + .isThrownBy(() -> selectModel.render(RenderingStrategies.MYBATIS3)) + .withMessage(Messages.getString("ERROR.44", "IsNotIn")); } @Test void testNotInCaseInsensitiveEventuallyEmpty() { - try (SqlSession sqlSession = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(id, animalName) - .from(animalData) - .where(animalName, isNotInCaseInsensitive("Fred", "Betty").filter(s -> false)) - .orderBy(id) - .build() - .render(RenderingStrategies.MYBATIS3); - - assertThat(selectStatement.getSelectStatement()).isEqualTo( - "select id, animal_name from AnimalData " + - "where upper(animal_name) not in () " + - "order by id" - ); - - assertThatExceptionOfType(PersistenceException.class).isThrownBy( - () -> mapper.selectManyMappedRows(selectStatement)) - .withCauseInstanceOf(SQLSyntaxErrorException.class); - } + var selectModel = select(id, animalName) + .from(animalData) + .where(animalName, isNotInCaseInsensitive("Fred", "Betty").filter(s -> false)) + .orderBy(id) + .build(); + + assertThatExceptionOfType(InvalidSqlException.class) + .isThrownBy(() -> selectModel.render(RenderingStrategies.MYBATIS3)) + .withMessage(Messages.getString("ERROR.44", "IsNotInCaseInsensitive")); } @Test void testInEventuallyEmptyDoubleFilter() { - try (SqlSession sqlSession = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(id, animalName) - .from(animalData) - .where(id, isIn(1, 2).filter(s -> false).filter(s -> false)) - .orderBy(id) - .build() - .render(RenderingStrategies.MYBATIS3); - - assertThat(selectStatement.getSelectStatement()).isEqualTo( - "select id, animal_name from AnimalData " + - "where id in () " + - "order by id" - ); - - assertThatExceptionOfType(PersistenceException.class).isThrownBy( - () -> mapper.selectManyMappedRows(selectStatement)) - .withCauseInstanceOf(SQLSyntaxErrorException.class); - } + var selectModel = select(id, animalName) + .from(animalData) + .where(id, isIn(1, 2).filter(s -> false).filter(s -> false)) + .orderBy(id) + .build(); + + assertThatExceptionOfType(InvalidSqlException.class) + .isThrownBy(() -> selectModel.render(RenderingStrategies.MYBATIS3)) + .withMessage(Messages.getString("ERROR.44", "IsIn")); } } diff --git a/src/test/java/org/mybatis/dynamic/sql/select/SelectStatementTest.java b/src/test/java/org/mybatis/dynamic/sql/select/SelectStatementTest.java index f548a4d71..6311403d8 100644 --- a/src/test/java/org/mybatis/dynamic/sql/select/SelectStatementTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/select/SelectStatementTest.java @@ -21,7 +21,6 @@ import static org.mybatis.dynamic.sql.SqlBuilder.*; import java.sql.JDBCType; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -283,18 +282,6 @@ void testGroupBySingleColumn() { ); } - @Test - void testInEmptyList() { - List<String> emptyList = Collections.emptyList(); - SelectStatementProvider selectStatement = select(column1, column3) - .from(table, "a") - .where(column3, isIn(emptyList)) - .build() - .render(RenderingStrategies.MYBATIS3); - - assertThat(selectStatement.getSelectStatement()).isEqualTo("select a.column1, a.column3 from foo a where a.column3 in ()"); - } - @Test void testNotInEmptyList() { List<String> emptyList = Collections.emptyList(); @@ -358,17 +345,6 @@ void testNotInWhenPresentEmptyList() { ); } - @Test - void testNotInCaseInsensitiveEmptyList() { - SelectStatementProvider selectStatement = select(column1, column3) - .from(table, "a") - .where(column3, isNotInCaseInsensitive(Collections.emptyList())) - .build() - .render(RenderingStrategies.MYBATIS3); - - assertThat(selectStatement.getSelectStatement()).isEqualTo("select a.column1, a.column3 from foo a where upper(a.column3) not in ()"); - } - @Test void testNotInCaseInsensitiveWhenPresentEmptyList() { SelectModel selectModel = select(column1, column3) diff --git a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperTest.kt index 75a703c09..6178e0326 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperTest.kt @@ -912,18 +912,6 @@ class PersonMapperTest { assertThat(insertStatement.insertStatement).isEqualTo(expected) } - @Test - fun testRenderingEmptyList() { - val selectStatement = select(id, firstName, lastName, birthDate, employed, occupation, addressId) { - from(person) - where { id isIn emptyList() } - } - - val expected = "select id, first_name, last_name, birth_date, employed, occupation, address_id from Person " + - "where id in ()" - assertThat(selectStatement.selectStatement).isEqualTo(expected) - } - @Test fun testSumWithCase() { sqlSessionFactory.openSession().use { session -> From f4309703757232f7b8ea5512324a88054a2d1dd6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 12 Aug 2024 01:28:57 +0000 Subject: [PATCH 059/260] Update dependency org.mybatis:mybatis-spring to v3.0.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ff30de791..9495ec37d 100644 --- a/pom.xml +++ b/pom.xml @@ -133,7 +133,7 @@ <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> - <version>3.0.3</version> + <version>3.0.4</version> <scope>test</scope> </dependency> <dependency> From 40d28e43701acd7ec904f1ee34e761a750dd3502 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 12 Aug 2024 20:34:47 -0400 Subject: [PATCH 060/260] Support Full Boolean Expressions in Joins --- .../org/mybatis/dynamic/sql/SqlBuilder.java | 26 +- .../mybatis/dynamic/sql/delete/DeleteDSL.java | 4 +- .../select/AbstractQueryExpressionDSL.java | 134 +- .../sql/select/QueryExpressionDSL.java | 81 +- .../sql/select/join/JoinSpecification.java | 35 +- .../sql/select/render/JoinRenderer.java | 39 +- .../render/JoinSpecificationRenderer.java | 44 + .../mybatis/dynamic/sql/update/UpdateDSL.java | 4 +- .../sql/where/AbstractWhereStarter.java | 22 +- .../mybatis/dynamic/sql/where/WhereDSL.java | 2 +- .../dynamic/sql/util/kotlin/JoinCollector.kt | 25 +- .../joins/NewSyntaxJoinMapperTest.java | 1270 +++++++++++++++++ 12 files changed, 1480 insertions(+), 206 deletions(-) create mode 100644 src/main/java/org/mybatis/dynamic/sql/select/render/JoinSpecificationRenderer.java create mode 100644 src/test/java/examples/joins/NewSyntaxJoinMapperTest.java diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java index df4292653..13f385e21 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java @@ -433,19 +433,9 @@ static AndOrCriteriaGroup and(List<AndOrCriteriaGroup> subCriteria) { } // join support - static <T> JoinCriterion<T> and(BindableColumn<T> joinColumn, JoinCondition<T> joinCondition) { - return new JoinCriterion.Builder<T>() - .withConnector("and") //$NON-NLS-1$ - .withJoinColumn(joinColumn) - .withJoinCondition(joinCondition) - .build(); - } - - static <T> JoinCriterion<T> on(BindableColumn<T> joinColumn, JoinCondition<T> joinCondition) { - return new JoinCriterion.Builder<T>() - .withConnector("on") //$NON-NLS-1$ - .withJoinColumn(joinColumn) - .withJoinCondition(joinCondition) + static <T> ColumnAndConditionCriterion<T> on(BindableColumn<T> joinColumn, VisitableCondition<T> joinCondition) { + return ColumnAndConditionCriterion.withColumn(joinColumn) + .withCondition(joinCondition) .build(); } @@ -460,12 +450,14 @@ static SearchedCaseDSL case_() { return SearchedCaseDSL.searchedCase(); } - static <T> EqualTo<T> equalTo(BindableColumn<T> column) { - return new EqualTo<>(column); + // TODO - Deprecate? + static <T> IsEqualToColumn<T> equalTo(BindableColumn<T> column) { + return IsEqualToColumn.of(column); } - static <T> EqualToValue<T> equalTo(T value) { - return new EqualToValue<>(value); + // TODO - Deprecate? + static <T> IsEqualTo<T> equalTo(T value) { + return IsEqualTo.of(value); } // aggregate support diff --git a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java index e7c1ad184..0ee9a99c9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java @@ -32,8 +32,8 @@ import org.mybatis.dynamic.sql.where.AbstractWhereStarter; import org.mybatis.dynamic.sql.where.EmbeddedWhereModel; -public class DeleteDSL<R> extends AbstractWhereStarter<DeleteDSL<R>.DeleteWhereBuilder, DeleteDSL<R>> - implements Buildable<R> { +public class DeleteDSL<R> implements AbstractWhereStarter<DeleteDSL<R>.DeleteWhereBuilder, DeleteDSL<R>>, + Buildable<R> { private final Function<DeleteModel, R> adapterFunction; private final SqlTable table; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/AbstractQueryExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/AbstractQueryExpressionDSL.java index d82076a49..a1a44d2ab 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/AbstractQueryExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/AbstractQueryExpressionDSL.java @@ -23,11 +23,13 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.function.Supplier; +import org.mybatis.dynamic.sql.AndOrCriteriaGroup; +import org.mybatis.dynamic.sql.SqlCriterion; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.TableExpression; import org.mybatis.dynamic.sql.exception.DuplicateTableAliasException; -import org.mybatis.dynamic.sql.select.join.JoinCriterion; import org.mybatis.dynamic.sql.select.join.JoinModel; import org.mybatis.dynamic.sql.select.join.JoinSpecification; import org.mybatis.dynamic.sql.select.join.JoinType; @@ -37,9 +39,9 @@ public abstract class AbstractQueryExpressionDSL<W extends AbstractWhereFinisher<?>, T extends AbstractQueryExpressionDSL<W, T>> - extends AbstractWhereStarter<W, T> { + implements AbstractWhereStarter<W, T> { - private final List<JoinSpecification.Builder> joinSpecificationBuilders = new ArrayList<>(); + private final List<Supplier<JoinSpecification>> joinSpecificationSuppliers = new ArrayList<>(); private final Map<SqlTable, String> tableAliases = new HashMap<>(); private final TableExpression table; @@ -51,151 +53,151 @@ public TableExpression table() { return table; } - public T join(SqlTable joinTable, JoinCriterion<?> onJoinCriterion, - JoinCriterion<?>... andJoinCriteria) { - addJoinSpecificationBuilder(joinTable, onJoinCriterion, JoinType.INNER, Arrays.asList(andJoinCriteria)); + public T join(SqlTable joinTable, SqlCriterion onJoinCriterion, + AndOrCriteriaGroup... andJoinCriteria) { + addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.INNER, Arrays.asList(andJoinCriteria)); return getThis(); } - public T join(SqlTable joinTable, String tableAlias, JoinCriterion<?> onJoinCriterion, - JoinCriterion<?>... andJoinCriteria) { + public T join(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion, + AndOrCriteriaGroup... andJoinCriteria) { addTableAlias(joinTable, tableAlias); return join(joinTable, onJoinCriterion, andJoinCriteria); } - public T join(SqlTable joinTable, JoinCriterion<?> onJoinCriterion, - List<JoinCriterion<?>> andJoinCriteria) { - addJoinSpecificationBuilder(joinTable, onJoinCriterion, JoinType.INNER, andJoinCriteria); + public T join(SqlTable joinTable, SqlCriterion onJoinCriterion, + List<AndOrCriteriaGroup> andJoinCriteria) { + addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.INNER, andJoinCriteria); return getThis(); } - public T join(SqlTable joinTable, String tableAlias, JoinCriterion<?> onJoinCriterion, - List<JoinCriterion<?>> andJoinCriteria) { + public T join(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion, + List<AndOrCriteriaGroup> andJoinCriteria) { addTableAlias(joinTable, tableAlias); return join(joinTable, onJoinCriterion, andJoinCriteria); } - public T join(Buildable<SelectModel> subQuery, String tableAlias, JoinCriterion<?> onJoinCriterion, - List<JoinCriterion<?>> andJoinCriteria) { - addJoinSpecificationBuilder(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.INNER, + public T join(Buildable<SelectModel> subQuery, String tableAlias, SqlCriterion onJoinCriterion, + List<AndOrCriteriaGroup> andJoinCriteria) { + addJoinSpecificationSupplier(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.INNER, andJoinCriteria); return getThis(); } - public T leftJoin(SqlTable joinTable, JoinCriterion<?> onJoinCriterion, - JoinCriterion<?>... andJoinCriteria) { - addJoinSpecificationBuilder(joinTable, onJoinCriterion, JoinType.LEFT, Arrays.asList(andJoinCriteria)); + public T leftJoin(SqlTable joinTable, SqlCriterion onJoinCriterion, + AndOrCriteriaGroup... andJoinCriteria) { + addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.LEFT, Arrays.asList(andJoinCriteria)); return getThis(); } - public T leftJoin(SqlTable joinTable, String tableAlias, JoinCriterion<?> onJoinCriterion, - JoinCriterion<?>... andJoinCriteria) { + public T leftJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion, + AndOrCriteriaGroup... andJoinCriteria) { addTableAlias(joinTable, tableAlias); return leftJoin(joinTable, onJoinCriterion, andJoinCriteria); } - public T leftJoin(SqlTable joinTable, JoinCriterion<?> onJoinCriterion, - List<JoinCriterion<?>> andJoinCriteria) { - addJoinSpecificationBuilder(joinTable, onJoinCriterion, JoinType.LEFT, andJoinCriteria); + public T leftJoin(SqlTable joinTable, SqlCriterion onJoinCriterion, + List<AndOrCriteriaGroup> andJoinCriteria) { + addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.LEFT, andJoinCriteria); return getThis(); } - public T leftJoin(SqlTable joinTable, String tableAlias, JoinCriterion<?> onJoinCriterion, - List<JoinCriterion<?>> andJoinCriteria) { + public T leftJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion, + List<AndOrCriteriaGroup> andJoinCriteria) { addTableAlias(joinTable, tableAlias); return leftJoin(joinTable, onJoinCriterion, andJoinCriteria); } - public T leftJoin(Buildable<SelectModel> subQuery, String tableAlias, JoinCriterion<?> onJoinCriterion, - List<JoinCriterion<?>> andJoinCriteria) { - addJoinSpecificationBuilder(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.LEFT, + public T leftJoin(Buildable<SelectModel> subQuery, String tableAlias, SqlCriterion onJoinCriterion, + List<AndOrCriteriaGroup> andJoinCriteria) { + addJoinSpecificationSupplier(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.LEFT, andJoinCriteria); return getThis(); } - public T rightJoin(SqlTable joinTable, JoinCriterion<?> onJoinCriterion, - JoinCriterion<?>... andJoinCriteria) { - addJoinSpecificationBuilder(joinTable, onJoinCriterion, JoinType.RIGHT, Arrays.asList(andJoinCriteria)); + public T rightJoin(SqlTable joinTable, SqlCriterion onJoinCriterion, + AndOrCriteriaGroup... andJoinCriteria) { + addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.RIGHT, Arrays.asList(andJoinCriteria)); return getThis(); } - public T rightJoin(SqlTable joinTable, String tableAlias, JoinCriterion<?> onJoinCriterion, - JoinCriterion<?>... andJoinCriteria) { + public T rightJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion, + AndOrCriteriaGroup... andJoinCriteria) { addTableAlias(joinTable, tableAlias); return rightJoin(joinTable, onJoinCriterion, andJoinCriteria); } - public T rightJoin(SqlTable joinTable, JoinCriterion<?> onJoinCriterion, - List<JoinCriterion<?>> andJoinCriteria) { - addJoinSpecificationBuilder(joinTable, onJoinCriterion, JoinType.RIGHT, andJoinCriteria); + public T rightJoin(SqlTable joinTable, SqlCriterion onJoinCriterion, + List<AndOrCriteriaGroup> andJoinCriteria) { + addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.RIGHT, andJoinCriteria); return getThis(); } - public T rightJoin(SqlTable joinTable, String tableAlias, JoinCriterion<?> onJoinCriterion, - List<JoinCriterion<?>> andJoinCriteria) { + public T rightJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion, + List<AndOrCriteriaGroup> andJoinCriteria) { addTableAlias(joinTable, tableAlias); return rightJoin(joinTable, onJoinCriterion, andJoinCriteria); } - public T rightJoin(Buildable<SelectModel> subQuery, String tableAlias, JoinCriterion<?> onJoinCriterion, - List<JoinCriterion<?>> andJoinCriteria) { - addJoinSpecificationBuilder(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.RIGHT, + public T rightJoin(Buildable<SelectModel> subQuery, String tableAlias, SqlCriterion onJoinCriterion, + List<AndOrCriteriaGroup> andJoinCriteria) { + addJoinSpecificationSupplier(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.RIGHT, andJoinCriteria); return getThis(); } - public T fullJoin(SqlTable joinTable, JoinCriterion<?> onJoinCriterion, - JoinCriterion<?>... andJoinCriteria) { - addJoinSpecificationBuilder(joinTable, onJoinCriterion, JoinType.FULL, Arrays.asList(andJoinCriteria)); + public T fullJoin(SqlTable joinTable, SqlCriterion onJoinCriterion, + AndOrCriteriaGroup... andJoinCriteria) { + addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.FULL, Arrays.asList(andJoinCriteria)); return getThis(); } - public T fullJoin(SqlTable joinTable, String tableAlias, JoinCriterion<?> onJoinCriterion, - JoinCriterion<?>... andJoinCriteria) { + public T fullJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion, + AndOrCriteriaGroup... andJoinCriteria) { addTableAlias(joinTable, tableAlias); return fullJoin(joinTable, onJoinCriterion, andJoinCriteria); } - public T fullJoin(SqlTable joinTable, JoinCriterion<?> onJoinCriterion, - List<JoinCriterion<?>> andJoinCriteria) { - addJoinSpecificationBuilder(joinTable, onJoinCriterion, JoinType.FULL, andJoinCriteria); + public T fullJoin(SqlTable joinTable, SqlCriterion onJoinCriterion, + List<AndOrCriteriaGroup> andJoinCriteria) { + addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.FULL, andJoinCriteria); return getThis(); } - public T fullJoin(SqlTable joinTable, String tableAlias, JoinCriterion<?> onJoinCriterion, - List<JoinCriterion<?>> andJoinCriteria) { + public T fullJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion, + List<AndOrCriteriaGroup> andJoinCriteria) { addTableAlias(joinTable, tableAlias); return fullJoin(joinTable, onJoinCriterion, andJoinCriteria); } - public T fullJoin(Buildable<SelectModel> subQuery, String tableAlias, JoinCriterion<?> onJoinCriterion, - List<JoinCriterion<?>> andJoinCriteria) { - addJoinSpecificationBuilder(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.FULL, + public T fullJoin(Buildable<SelectModel> subQuery, String tableAlias, SqlCriterion onJoinCriterion, + List<AndOrCriteriaGroup> andJoinCriteria) { + addJoinSpecificationSupplier(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.FULL, andJoinCriteria); return getThis(); } - private void addJoinSpecificationBuilder(TableExpression joinTable, JoinCriterion<?> onJoinCriterion, - JoinType joinType, List<JoinCriterion<?>> andJoinCriteria) { - joinSpecificationBuilders.add(new JoinSpecification.Builder() + private void addJoinSpecificationSupplier(TableExpression joinTable, SqlCriterion onJoinCriterion, + JoinType joinType, List<AndOrCriteriaGroup> andJoinCriteria) { + joinSpecificationSuppliers.add(() -> new JoinSpecification.Builder() .withJoinTable(joinTable) .withJoinType(joinType) - .withJoinCriterion(onJoinCriterion) - .withJoinCriteria(andJoinCriteria)); + .withInitialCriterion(onJoinCriterion) + .withSubCriteria(andJoinCriteria).build()); } - protected void addJoinSpecificationBuilder(JoinSpecification.Builder builder) { - joinSpecificationBuilders.add(builder); + protected void addJoinSpecificationSupplier(Supplier<JoinSpecification> joinSpecificationSupplier) { + joinSpecificationSuppliers.add(joinSpecificationSupplier); } protected Optional<JoinModel> buildJoinModel() { - if (joinSpecificationBuilders.isEmpty()) { + if (joinSpecificationSuppliers.isEmpty()) { return Optional.empty(); } - return Optional.of(JoinModel.of(joinSpecificationBuilders.stream() - .map(JoinSpecification.Builder::build) - .toList())); + return Optional.of(JoinModel.of(joinSpecificationSuppliers.stream() + .map(Supplier::get) + .toList())); } protected void addTableAlias(SqlTable table, String tableAlias) { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java index 593252979..4c025b660 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java @@ -23,15 +23,17 @@ import java.util.function.Consumer; import org.jetbrains.annotations.NotNull; +import org.mybatis.dynamic.sql.AndOrCriteriaGroup; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; +import org.mybatis.dynamic.sql.ColumnAndConditionCriterion; import org.mybatis.dynamic.sql.CriteriaGroup; import org.mybatis.dynamic.sql.SortSpecification; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.TableExpression; +import org.mybatis.dynamic.sql.VisitableCondition; +import org.mybatis.dynamic.sql.common.AbstractBooleanExpressionDSL; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; -import org.mybatis.dynamic.sql.select.join.JoinCondition; -import org.mybatis.dynamic.sql.select.join.JoinCriterion; import org.mybatis.dynamic.sql.select.join.JoinSpecification; import org.mybatis.dynamic.sql.select.join.JoinType; import org.mybatis.dynamic.sql.util.Buildable; @@ -339,50 +341,54 @@ public JoinSpecificationStarter(TableExpression joinTable, JoinType joinType) { this.joinType = joinType; } - public <T> JoinSpecificationFinisher on(BindableColumn<T> joinColumn, JoinCondition<T> joinCondition) { + public <T> JoinSpecificationFinisher on(BindableColumn<T> joinColumn, VisitableCondition<T> joinCondition) { return new JoinSpecificationFinisher(joinTable, joinColumn, joinCondition, joinType); } - public <T> JoinSpecificationFinisher on(BindableColumn<T> joinColumn, JoinCondition<T> onJoinCondition, - JoinCriterion<?>... andJoinCriteria) { - return new JoinSpecificationFinisher(joinTable, joinColumn, onJoinCondition, joinType, andJoinCriteria); + public <T> JoinSpecificationFinisher on(BindableColumn<T> joinColumn, VisitableCondition<T> onJoinCondition, + AndOrCriteriaGroup... subCriteria) { + return new JoinSpecificationFinisher(joinTable, joinColumn, onJoinCondition, joinType, subCriteria); } } - public class JoinSpecificationFinisher - extends AbstractWhereStarter<QueryExpressionWhereBuilder, JoinSpecificationFinisher> - implements Buildable<R> { - private final JoinSpecification.Builder joinSpecificationBuilder; + public class JoinSpecificationFinisher extends AbstractBooleanExpressionDSL<JoinSpecificationFinisher> + implements AbstractWhereStarter<QueryExpressionWhereBuilder, JoinSpecificationFinisher>, Buildable<R> { + private final TableExpression table; + private final JoinType joinType; public <T> JoinSpecificationFinisher(TableExpression table, BindableColumn<T> joinColumn, - JoinCondition<T> joinCondition, JoinType joinType) { - JoinCriterion<T> joinCriterion = new JoinCriterion.Builder<T>() - .withConnector("on") //$NON-NLS-1$ - .withJoinColumn(joinColumn) - .withJoinCondition(joinCondition) - .build(); + VisitableCondition<T> joinCondition, JoinType joinType) { + this.table = table; + this.joinType = joinType; + addJoinSpecificationSupplier(this::buildJoinSpecification); - joinSpecificationBuilder = JoinSpecification.withJoinTable(table) - .withJoinType(joinType) - .withJoinCriterion(joinCriterion); + ColumnAndConditionCriterion<T> c = ColumnAndConditionCriterion.withColumn(joinColumn) + .withCondition(joinCondition) + .build(); - addJoinSpecificationBuilder(joinSpecificationBuilder); + setInitialCriterion(c); } public <T> JoinSpecificationFinisher(TableExpression table, BindableColumn<T> joinColumn, - JoinCondition<T> joinCondition, JoinType joinType, JoinCriterion<?>... andJoinCriteria) { - JoinCriterion<T> onJoinCriterion = new JoinCriterion.Builder<T>() - .withConnector("on") //$NON-NLS-1$ - .withJoinColumn(joinColumn) - .withJoinCondition(joinCondition) + VisitableCondition<T> joinCondition, JoinType joinType, AndOrCriteriaGroup... subCriteria) { + this.table = table; + this.joinType = joinType; + addJoinSpecificationSupplier(this::buildJoinSpecification); + + ColumnAndConditionCriterion<T> c = ColumnAndConditionCriterion.withColumn(joinColumn) + .withCondition(joinCondition) + .withSubCriteria(Arrays.asList(subCriteria)) .build(); - joinSpecificationBuilder = JoinSpecification.withJoinTable(table) - .withJoinType(joinType) - .withJoinCriterion(onJoinCriterion) - .withJoinCriteria(Arrays.asList(andJoinCriteria)); + setInitialCriterion(c); + } - addJoinSpecificationBuilder(joinSpecificationBuilder); + private JoinSpecification buildJoinSpecification() { + return JoinSpecification.withJoinTable(table) + .withJoinType(joinType) + .withInitialCriterion(getInitialCriterion()) + .withSubCriteria(subCriteria) + .build(); } @NotNull @@ -402,16 +408,6 @@ public QueryExpressionWhereBuilder where() { return QueryExpressionDSL.this.where(); } - public <T> JoinSpecificationFinisher and(BindableColumn<T> joinColumn, JoinCondition<T> joinCondition) { - JoinCriterion<T> joinCriterion = new JoinCriterion.Builder<T>() - .withConnector("and") //$NON-NLS-1$ - .withJoinColumn(joinColumn) - .withJoinCondition(joinCondition) - .build(); - joinSpecificationBuilder.withJoinCriterion(joinCriterion); - return this; - } - public JoinSpecificationStarter join(SqlTable joinTable) { return QueryExpressionDSL.this.join(joinTable); } @@ -495,6 +491,11 @@ public SelectDSL<R>.OffsetFirstFinisher offset(long offset) { public SelectDSL<R>.FetchFirstFinisher fetchFirst(long fetchFirstRows) { return QueryExpressionDSL.this.fetchFirst(fetchFirstRows); } + + @Override + protected JoinSpecificationFinisher getThis() { + return this; + } } public class GroupByFinisher extends AbstractHavingStarter<QueryExpressionHavingBuilder> implements Buildable<R> { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/join/JoinSpecification.java b/src/main/java/org/mybatis/dynamic/sql/select/join/JoinSpecification.java index ab95dcf5e..9db5243d2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/join/JoinSpecification.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/join/JoinSpecification.java @@ -15,36 +15,29 @@ */ package org.mybatis.dynamic.sql.select.join; -import java.util.ArrayList; -import java.util.List; import java.util.Objects; -import java.util.stream.Stream; import org.mybatis.dynamic.sql.TableExpression; +import org.mybatis.dynamic.sql.common.AbstractBooleanExpressionModel; import org.mybatis.dynamic.sql.util.Validator; -public class JoinSpecification { +public class JoinSpecification extends AbstractBooleanExpressionModel { private final TableExpression table; - private final List<JoinCriterion<?>> joinCriteria; private final JoinType joinType; private JoinSpecification(Builder builder) { + super(builder); table = Objects.requireNonNull(builder.table); - joinCriteria = Objects.requireNonNull(builder.joinCriteria); joinType = Objects.requireNonNull(builder.joinType); - Validator.assertNotEmpty(joinCriteria, "ERROR.16"); //$NON-NLS-1$ + Validator.assertFalse(initialCriterion().isEmpty() && subCriteria().isEmpty(), + "ERROR.16"); //$NON-NLS-1$ } public TableExpression table() { return table; } - @SuppressWarnings("java:S1452") - public Stream<JoinCriterion<?>> joinCriteria() { - return joinCriteria.stream(); - } - public JoinType joinType() { return joinType; } @@ -53,9 +46,8 @@ public static Builder withJoinTable(TableExpression table) { return new Builder().withJoinTable(table); } - public static class Builder { + public static class Builder extends AbstractBuilder<Builder> { private TableExpression table; - private final List<JoinCriterion<?>> joinCriteria = new ArrayList<>(); private JoinType joinType; public Builder withJoinTable(TableExpression table) { @@ -63,16 +55,6 @@ public Builder withJoinTable(TableExpression table) { return this; } - public Builder withJoinCriterion(JoinCriterion<?> joinCriterion) { - this.joinCriteria.add(joinCriterion); - return this; - } - - public Builder withJoinCriteria(List<JoinCriterion<?>> joinCriteria) { - this.joinCriteria.addAll(joinCriteria); - return this; - } - public Builder withJoinType(JoinType joinType) { this.joinType = joinType; return this; @@ -81,5 +63,10 @@ public Builder withJoinType(JoinType joinType) { public JoinSpecification build() { return new JoinSpecification(this); } + + @Override + protected Builder getThis() { + return this; + } } } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/JoinRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/JoinRenderer.java index 667b4e299..0da029f59 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/JoinRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/JoinRenderer.java @@ -20,8 +20,8 @@ import java.util.Objects; import java.util.stream.Collectors; +import org.mybatis.dynamic.sql.exception.InvalidSqlException; import org.mybatis.dynamic.sql.render.RenderingContext; -import org.mybatis.dynamic.sql.select.join.JoinCriterion; import org.mybatis.dynamic.sql.select.join.JoinModel; import org.mybatis.dynamic.sql.select.join.JoinSpecification; import org.mybatis.dynamic.sql.util.FragmentAndParameters; @@ -47,41 +47,20 @@ public FragmentAndParameters render() { private FragmentAndParameters renderJoinSpecification(JoinSpecification joinSpecification) { FragmentAndParameters renderedTable = joinSpecification.table().accept(tableExpressionRenderer); - FragmentAndParameters renderedJoin = renderConditions(joinSpecification); + FragmentAndParameters renderedJoinSpecification = JoinSpecificationRenderer + .withJoinSpecification(joinSpecification) + .withRenderingContext(renderingContext) + .build() + .render() + .orElseThrow(() -> new InvalidSqlException("Join Specifications Must Render")); // TODO String fragment = joinSpecification.joinType().type() + spaceBefore(renderedTable.fragment()) - + spaceBefore(renderedJoin.fragment()); + + spaceBefore(renderedJoinSpecification.fragment()); return FragmentAndParameters.withFragment(fragment) .withParameters(renderedTable.parameters()) - .withParameters(renderedJoin.parameters()) - .build(); - } - - private FragmentAndParameters renderConditions(JoinSpecification joinSpecification) { - return joinSpecification.joinCriteria() - .map(this::renderCriterion) - .collect(FragmentCollector.collect()) - .toFragmentAndParameters(Collectors.joining(" ")); //$NON-NLS-1$ - } - - private <T> FragmentAndParameters renderCriterion(JoinCriterion<T> joinCriterion) { - FragmentAndParameters renderedColumn = joinCriterion.leftColumn().render(renderingContext); - - String prefix = joinCriterion.connector() - + spaceBefore(renderedColumn.fragment()); - - JoinConditionRenderer<T> joinConditionRenderer = new JoinConditionRenderer.Builder<T>() - .withRenderingContext(renderingContext) - .withLeftColumn(joinCriterion.leftColumn()) - .build(); - - FragmentAndParameters suffix = joinCriterion.joinCondition().accept(joinConditionRenderer); - - return FragmentAndParameters.withFragment(prefix + spaceBefore(suffix.fragment())) - .withParameters(suffix.parameters()) - .withParameters(renderedColumn.parameters()) + .withParameters(renderedJoinSpecification.parameters()) .build(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/JoinSpecificationRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/JoinSpecificationRenderer.java new file mode 100644 index 000000000..300e416d8 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/JoinSpecificationRenderer.java @@ -0,0 +1,44 @@ +/* + * Copyright 2016-2024 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 + * + * https://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.select.render; + +import org.mybatis.dynamic.sql.common.AbstractBooleanExpressionRenderer; +import org.mybatis.dynamic.sql.select.join.JoinSpecification; + +public class JoinSpecificationRenderer extends AbstractBooleanExpressionRenderer { + private JoinSpecificationRenderer(Builder builder) { + super("on", builder); //$NON-NLS-1$ + } + + public static JoinSpecificationRenderer.Builder withJoinSpecification(JoinSpecification joinSpecification) { + return new Builder(joinSpecification); + } + + public static class Builder extends AbstractBuilder<Builder> { + public Builder(JoinSpecification joinSpecification) { + super(joinSpecification); + } + + public JoinSpecificationRenderer build() { + return new JoinSpecificationRenderer(this); + } + + @Override + protected Builder getThis() { + return this; + } + } +} diff --git a/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java index 8cf7259a3..4daa99ccc 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java @@ -47,8 +47,8 @@ import org.mybatis.dynamic.sql.where.AbstractWhereStarter; import org.mybatis.dynamic.sql.where.EmbeddedWhereModel; -public class UpdateDSL<R> extends AbstractWhereStarter<UpdateDSL<R>.UpdateWhereBuilder, UpdateDSL<R>> - implements Buildable<R> { +public class UpdateDSL<R> implements AbstractWhereStarter<UpdateDSL<R>.UpdateWhereBuilder, UpdateDSL<R>>, + Buildable<R> { private final Function<UpdateModel, R> adapterFunction; private final List<AbstractColumnMapping> columnMappings = new ArrayList<>(); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereStarter.java b/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereStarter.java index 03da51bd8..e94f0a8a1 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereStarter.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereStarter.java @@ -35,14 +35,14 @@ * * @param <F> the implementation of the Where DSL customized for a particular SQL statement. */ -public abstract class AbstractWhereStarter<F extends AbstractWhereFinisher<?>, D extends AbstractWhereStarter<F, D>> - implements ConfigurableStatement<D> { +public interface AbstractWhereStarter<F extends AbstractWhereFinisher<?>, D extends AbstractWhereStarter<F, D>> + extends ConfigurableStatement<D> { - public <T> F where(BindableColumn<T> column, VisitableCondition<T> condition, AndOrCriteriaGroup... subCriteria) { + default <T> F where(BindableColumn<T> column, VisitableCondition<T> condition, AndOrCriteriaGroup... subCriteria) { return where(column, condition, Arrays.asList(subCriteria)); } - public <T> F where(BindableColumn<T> column, VisitableCondition<T> condition, + default <T> F where(BindableColumn<T> column, VisitableCondition<T> condition, List<AndOrCriteriaGroup> subCriteria) { SqlCriterion sqlCriterion = ColumnAndConditionCriterion.withColumn(column) .withCondition(condition) @@ -52,11 +52,11 @@ public <T> F where(BindableColumn<T> column, VisitableCondition<T> condition, return initialize(sqlCriterion); } - public F where(ExistsPredicate existsPredicate, AndOrCriteriaGroup... subCriteria) { + default F where(ExistsPredicate existsPredicate, AndOrCriteriaGroup... subCriteria) { return where(existsPredicate, Arrays.asList(subCriteria)); } - public F where(ExistsPredicate existsPredicate, List<AndOrCriteriaGroup> subCriteria) { + default F where(ExistsPredicate existsPredicate, List<AndOrCriteriaGroup> subCriteria) { ExistsCriterion sqlCriterion = new ExistsCriterion.Builder() .withExistsPredicate(existsPredicate) .withSubCriteria(subCriteria) @@ -65,11 +65,11 @@ public F where(ExistsPredicate existsPredicate, List<AndOrCriteriaGroup> subCrit return initialize(sqlCriterion); } - public F where(SqlCriterion initialCriterion, AndOrCriteriaGroup... subCriteria) { + default F where(SqlCriterion initialCriterion, AndOrCriteriaGroup... subCriteria) { return where(initialCriterion, Arrays.asList(subCriteria)); } - public F where(SqlCriterion initialCriterion, List<AndOrCriteriaGroup> subCriteria) { + default F where(SqlCriterion initialCriterion, List<AndOrCriteriaGroup> subCriteria) { SqlCriterion sqlCriterion = new CriteriaGroup.Builder() .withInitialCriterion(initialCriterion) .withSubCriteria(subCriteria) @@ -78,7 +78,7 @@ public F where(SqlCriterion initialCriterion, List<AndOrCriteriaGroup> subCriter return initialize(sqlCriterion); } - public F where(List<AndOrCriteriaGroup> subCriteria) { + default F where(List<AndOrCriteriaGroup> subCriteria) { SqlCriterion sqlCriterion = new CriteriaGroup.Builder() .withSubCriteria(subCriteria) .build(); @@ -86,9 +86,9 @@ public F where(List<AndOrCriteriaGroup> subCriteria) { return initialize(sqlCriterion); } - public abstract F where(); + F where(); - public F applyWhere(WhereApplier whereApplier) { + default F applyWhere(WhereApplier whereApplier) { F finisher = where(); whereApplier.accept(finisher); return finisher; diff --git a/src/main/java/org/mybatis/dynamic/sql/where/WhereDSL.java b/src/main/java/org/mybatis/dynamic/sql/where/WhereDSL.java index 0eb23f638..a4adc2967 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/WhereDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/WhereDSL.java @@ -26,7 +26,7 @@ * * <p>This can also be used to create reusable where clauses for different statements. */ -public class WhereDSL extends AbstractWhereStarter<WhereDSL.StandaloneWhereFinisher, WhereDSL> { +public class WhereDSL implements AbstractWhereStarter<WhereDSL.StandaloneWhereFinisher, WhereDSL> { private final StatementConfiguration statementConfiguration = new StatementConfiguration(); private final StandaloneWhereFinisher whereBuilder = new StandaloneWhereFinisher(); diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt index 3ba5c2acb..6212167c1 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt @@ -15,40 +15,39 @@ */ package org.mybatis.dynamic.sql.util.kotlin +import org.mybatis.dynamic.sql.AndOrCriteriaGroup import org.mybatis.dynamic.sql.BindableColumn +import org.mybatis.dynamic.sql.ColumnAndConditionCriterion import org.mybatis.dynamic.sql.SqlBuilder -import org.mybatis.dynamic.sql.select.join.JoinCondition -import org.mybatis.dynamic.sql.select.join.JoinCriterion +import org.mybatis.dynamic.sql.SqlCriterion +import org.mybatis.dynamic.sql.VisitableCondition typealias JoinReceiver = JoinCollector.() -> Unit @MyBatisDslMarker class JoinCollector { - private var onJoinCriterion: JoinCriterion<*>? = null - internal val andJoinCriteria = mutableListOf<JoinCriterion<*>>() + private var onJoinCriterion: SqlCriterion? = null + internal val andJoinCriteria = mutableListOf<AndOrCriteriaGroup>() - internal fun onJoinCriterion() : JoinCriterion<*> = invalidIfNull(onJoinCriterion, "ERROR.22") //$NON-NLS-1$ + internal fun onJoinCriterion() : SqlCriterion = invalidIfNull(onJoinCriterion, "ERROR.22") //$NON-NLS-1$ fun <T> on(leftColumn: BindableColumn<T>): RightColumnCollector<T> = RightColumnCollector { - onJoinCriterion = JoinCriterion.Builder<T>() - .withConnector("on") //$NON-NLS-1$ - .withJoinColumn(leftColumn) - .withJoinCondition(it) + onJoinCriterion = ColumnAndConditionCriterion.withColumn(leftColumn) + .withCondition(it) .build() } fun <T> and(leftColumn: BindableColumn<T>): RightColumnCollector<T> = RightColumnCollector { andJoinCriteria.add( - JoinCriterion.Builder<T>() + AndOrCriteriaGroup.Builder() .withConnector("and") //$NON-NLS-1$ - .withJoinColumn(leftColumn) - .withJoinCondition(it) + .withInitialCriterion(ColumnAndConditionCriterion.withColumn(leftColumn).withCondition(it).build()) .build() ) } } -class RightColumnCollector<T>(private val joinConditionConsumer: (JoinCondition<T>) -> Unit) { +class RightColumnCollector<T>(private val joinConditionConsumer: (VisitableCondition<T>) -> Unit) { infix fun equalTo(rightColumn: BindableColumn<T>) = joinConditionConsumer.invoke(SqlBuilder.equalTo(rightColumn)) infix fun equalTo(value: T) = joinConditionConsumer.invoke(SqlBuilder.equalTo(value)) diff --git a/src/test/java/examples/joins/NewSyntaxJoinMapperTest.java b/src/test/java/examples/joins/NewSyntaxJoinMapperTest.java new file mode 100644 index 000000000..ae8f5d0f0 --- /dev/null +++ b/src/test/java/examples/joins/NewSyntaxJoinMapperTest.java @@ -0,0 +1,1270 @@ +/* + * Copyright 2016-2024 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 + * + * https://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.joins; + +import org.apache.ibatis.datasource.unpooled.UnpooledDataSource; +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; +import org.mybatis.dynamic.sql.exception.DuplicateTableAliasException; +import org.mybatis.dynamic.sql.render.RenderingStrategies; +import org.mybatis.dynamic.sql.select.QueryExpressionDSL; +import org.mybatis.dynamic.sql.select.SelectModel; +import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; +import org.mybatis.dynamic.sql.util.Messages; +import org.mybatis.dynamic.sql.util.mybatis3.CommonSelectMapper; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.sql.Connection; +import java.sql.DriverManager; +import java.util.List; +import java.util.Map; + +import static examples.joins.ItemMasterDynamicSQLSupport.itemMaster; +import static examples.joins.OrderDetailDynamicSQLSupport.orderDetail; +import static examples.joins.OrderLineDynamicSQLSupport.orderLine; +import static examples.joins.OrderMasterDynamicSQLSupport.orderDate; +import static examples.joins.OrderMasterDynamicSQLSupport.orderMaster; +import static examples.joins.UserDynamicSQLSupport.user; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.mybatis.dynamic.sql.SqlBuilder.and; +import static org.mybatis.dynamic.sql.SqlBuilder.constant; +import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo; +import static org.mybatis.dynamic.sql.SqlBuilder.on; +import static org.mybatis.dynamic.sql.SqlBuilder.select; +import static org.mybatis.dynamic.sql.SqlBuilder.sortColumn; +import static org.mybatis.dynamic.sql.SqlBuilder.where; + +class NewSyntaxJoinMapperTest { + + private static final String JDBC_URL = "jdbc:hsqldb:mem:aname"; + private static final String JDBC_DRIVER = "org.hsqldb.jdbcDriver"; + + private SqlSessionFactory sqlSessionFactory; + + @BeforeEach + void setup() throws Exception { + Class.forName(JDBC_DRIVER); + InputStream is = getClass().getResourceAsStream("/examples/joins/CreateJoinDB.sql"); + assert is != null; + 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(JoinMapper.class); + config.addMapper(CommonSelectMapper.class); + sqlSessionFactory = new SqlSessionFactoryBuilder().build(config); + } + + @Test + void testSingleTableJoin1() { + try (SqlSession session = sqlSessionFactory.openSession()) { + JoinMapper mapper = session.getMapper(JoinMapper.class); + + SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) + .from(orderMaster, "om") + .join(orderDetail, "od").on(orderMaster.orderId, isEqualTo(orderDetail.orderId)) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" + + " from OrderMaster om join OrderDetail od on om.order_id = od.order_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<OrderMaster> rows = mapper.selectMany(selectStatement); + + assertThat(rows).hasSize(2); + OrderMaster orderMaster = rows.get(0); + assertThat(orderMaster.getId()).isEqualTo(1); + assertThat(orderMaster.getDetails()).hasSize(2); + OrderDetail orderDetail = orderMaster.getDetails().get(0); + assertThat(orderDetail.getLineNumber()).isEqualTo(1); + orderDetail = orderMaster.getDetails().get(1); + assertThat(orderDetail.getLineNumber()).isEqualTo(2); + + orderMaster = rows.get(1); + assertThat(orderMaster.getId()).isEqualTo(2); + assertThat(orderMaster.getDetails()).hasSize(1); + orderDetail = orderMaster.getDetails().get(0); + assertThat(orderDetail.getLineNumber()).isEqualTo(1); + } + } + + @Test + void testSingleTableJoin2() { + try (SqlSession session = sqlSessionFactory.openSession()) { + JoinMapper mapper = session.getMapper(JoinMapper.class); + + SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) + .from(orderMaster, "om") + .join(orderDetail, "od", on(orderMaster.orderId, isEqualTo(orderDetail.orderId))) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" + + " from OrderMaster om join OrderDetail od on om.order_id = od.order_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<OrderMaster> rows = mapper.selectMany(selectStatement); + + assertThat(rows).hasSize(2); + OrderMaster orderMaster = rows.get(0); + assertThat(orderMaster.getId()).isEqualTo(1); + assertThat(orderMaster.getDetails()).hasSize(2); + OrderDetail orderDetail = orderMaster.getDetails().get(0); + assertThat(orderDetail.getLineNumber()).isEqualTo(1); + orderDetail = orderMaster.getDetails().get(1); + assertThat(orderDetail.getLineNumber()).isEqualTo(2); + + orderMaster = rows.get(1); + assertThat(orderMaster.getId()).isEqualTo(2); + assertThat(orderMaster.getDetails()).hasSize(1); + orderDetail = orderMaster.getDetails().get(0); + assertThat(orderDetail.getLineNumber()).isEqualTo(1); + } + } + + @Test + void testCompoundJoin1() { + // this is a nonsensical join, but it does test the "and" capability + SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) + .from(orderMaster, "om") + .join(orderDetail, "od").on(orderMaster.orderId, isEqualTo(orderDetail.orderId), and(orderMaster.orderId, isEqualTo(orderDetail.orderId))) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" + + " from OrderMaster om join OrderDetail od on om.order_id = od.order_id and om.order_id = od.order_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + } + + @Test + void testCompoundJoin2() { + // this is a nonsensical join, but it does test the "and" capability + SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) + .from(orderMaster, "om") + .join(orderDetail, "od").on(orderMaster.orderId, isEqualTo(orderDetail.orderId)) + .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) + .and(orderMaster.orderId, isEqualTo(orderDetail.orderId)) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" + + " from OrderMaster om join OrderDetail od on om.order_id = od.order_id and om.order_id = od.order_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + } + + @Test + void testCompoundJoin3() { + // this is a nonsensical join, but it does test the "and" capability + SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) + .from(orderMaster, "om") + .join(orderDetail, "od", on(orderMaster.orderId, isEqualTo(orderDetail.orderId)), and(orderMaster.orderId, isEqualTo(orderDetail.orderId))) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" + + " from OrderMaster om join OrderDetail od on om.order_id = od.order_id and om.order_id = od.order_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + } + + @Test + void testCompoundJoin4() { + // this is a nonsensical join, but it does test the "and" capability + SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) + .from(orderMaster, "om") + .leftJoin(orderDetail, "od", on(orderMaster.orderId, isEqualTo(orderDetail.orderId)), and(orderMaster.orderId, isEqualTo(orderDetail.orderId))) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" + + " from OrderMaster om left join OrderDetail od on om.order_id = od.order_id and om.order_id = od.order_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + } + + @Test + void testCompoundJoin5() { + // this is a nonsensical join, but it does test the "and" capability + SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) + .from(orderMaster, "om") + .rightJoin(orderDetail, "od", on(orderMaster.orderId, isEqualTo(orderDetail.orderId)), and(orderMaster.orderId, isEqualTo(orderDetail.orderId))) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" + + " from OrderMaster om right join OrderDetail od on om.order_id = od.order_id and om.order_id = od.order_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + } + + @Test + void testCompoundJoin6() { + // this is a nonsensical join, but it does test the "and" capability + SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) + .from(orderMaster, "om") + .fullJoin(orderDetail, "od", on(orderMaster.orderId, isEqualTo(orderDetail.orderId)), and(orderMaster.orderId, isEqualTo(orderDetail.orderId))) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" + + " from OrderMaster om full join OrderDetail od on om.order_id = od.order_id and om.order_id = od.order_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + } + + @Test + void testMultipleTableJoinWithWhereClause() { + try (SqlSession session = sqlSessionFactory.openSession()) { + JoinMapper mapper = session.getMapper(JoinMapper.class); + + SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) + .from(orderMaster, "om") + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .join(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .where(orderMaster.orderId, isEqualTo(2)) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select om.order_id, om.order_date, ol.line_number, im.description, ol.quantity" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id join ItemMaster im on ol.item_id = im.item_id" + + " where om.order_id = #{parameters.p1,jdbcType=INTEGER}"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<OrderMaster> rows = mapper.selectMany(selectStatement); + + assertThat(rows).hasSize(1); + OrderMaster orderMaster = rows.get(0); + assertThat(orderMaster.getId()).isEqualTo(2); + assertThat(orderMaster.getDetails()).hasSize(2); + OrderDetail orderDetail = orderMaster.getDetails().get(0); + assertThat(orderDetail.getLineNumber()).isEqualTo(1); + orderDetail = orderMaster.getDetails().get(1); + assertThat(orderDetail.getLineNumber()).isEqualTo(2); + } + } + + @Test + void testMultipleTableJoinWithApplyWhere() { + try (SqlSession session = sqlSessionFactory.openSession()) { + JoinMapper mapper = session.getMapper(JoinMapper.class); + + SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) + .from(orderMaster, "om") + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .join(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .applyWhere(where(orderMaster.orderId, isEqualTo(2)).toWhereApplier()) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select om.order_id, om.order_date, ol.line_number, im.description, ol.quantity" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id join ItemMaster im on ol.item_id = im.item_id" + + " where om.order_id = #{parameters.p1,jdbcType=INTEGER}"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<OrderMaster> rows = mapper.selectMany(selectStatement); + + assertThat(rows).hasSize(1); + OrderMaster orderMaster = rows.get(0); + assertThat(orderMaster.getId()).isEqualTo(2); + assertThat(orderMaster.getDetails()).hasSize(2); + OrderDetail orderDetail = orderMaster.getDetails().get(0); + assertThat(orderDetail.getLineNumber()).isEqualTo(1); + orderDetail = orderMaster.getDetails().get(1); + assertThat(orderDetail.getLineNumber()).isEqualTo(2); + } + } + + @Test + void testMultipleTableJoinWithComplexWhereClause() { + try (SqlSession session = sqlSessionFactory.openSession()) { + JoinMapper mapper = session.getMapper(JoinMapper.class); + + SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) + .from(orderMaster, "om") + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .join(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .where(orderMaster.orderId, isEqualTo(2), and(orderLine.lineNumber, isEqualTo(2))) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select om.order_id, om.order_date, ol.line_number, im.description, ol.quantity" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id join ItemMaster im on ol.item_id = im.item_id" + + " where om.order_id = #{parameters.p1,jdbcType=INTEGER} and ol.line_number = #{parameters.p2,jdbcType=INTEGER}"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<OrderMaster> rows = mapper.selectMany(selectStatement); + + assertThat(rows).hasSize(1); + OrderMaster orderMaster = rows.get(0); + assertThat(orderMaster.getId()).isEqualTo(2); + assertThat(orderMaster.getDetails()).hasSize(1); + OrderDetail orderDetail = orderMaster.getDetails().get(0); + assertThat(orderDetail.getLineNumber()).isEqualTo(2); + } + } + + @Test + void testMultipleTableJoinWithOrderBy() { + try (SqlSession session = sqlSessionFactory.openSession()) { + JoinMapper mapper = session.getMapper(JoinMapper.class); + + SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) + .from(orderMaster, "om") + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .join(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .orderBy(orderMaster.orderId) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select om.order_id, om.order_date, ol.line_number, im.description, ol.quantity" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id join ItemMaster im on ol.item_id = im.item_id" + + " order by order_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<OrderMaster> rows = mapper.selectMany(selectStatement); + + assertThat(rows).hasSize(2); + OrderMaster orderMaster = rows.get(0); + assertThat(orderMaster.getId()).isEqualTo(1); + assertThat(orderMaster.getDetails()).hasSize(1); + OrderDetail orderDetail = orderMaster.getDetails().get(0); + assertThat(orderDetail.getLineNumber()).isEqualTo(1); + + orderMaster = rows.get(1); + assertThat(orderMaster.getId()).isEqualTo(2); + assertThat(orderMaster.getDetails()).hasSize(2); + orderDetail = orderMaster.getDetails().get(0); + assertThat(orderDetail.getLineNumber()).isEqualTo(1); + orderDetail = orderMaster.getDetails().get(1); + assertThat(orderDetail.getLineNumber()).isEqualTo(2); + } + } + + @Test + void testMultipleTableJoinNoAliasWithOrderBy() { + try (SqlSession session = sqlSessionFactory.openSession()) { + JoinMapper mapper = session.getMapper(JoinMapper.class); + + SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) + .from(orderMaster) + .join(orderLine).on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .join(itemMaster).on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .where(orderMaster.orderId, isEqualTo(2)) + .orderBy(orderMaster.orderId) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select OrderMaster.order_id, OrderMaster.order_date, OrderLine.line_number, ItemMaster.description, OrderLine.quantity" + + " from OrderMaster join OrderLine on OrderMaster.order_id = OrderLine.order_id join ItemMaster on OrderLine.item_id = ItemMaster.item_id" + + " where OrderMaster.order_id = #{parameters.p1,jdbcType=INTEGER}" + + " order by order_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<OrderMaster> rows = mapper.selectMany(selectStatement); + + assertThat(rows).hasSize(1); + OrderMaster orderMaster = rows.get(0); + assertThat(orderMaster.getId()).isEqualTo(2); + assertThat(orderMaster.getDetails()).hasSize(2); + OrderDetail orderDetail = orderMaster.getDetails().get(0); + assertThat(orderDetail.getLineNumber()).isEqualTo(1); + orderDetail = orderMaster.getDetails().get(1); + assertThat(orderDetail.getLineNumber()).isEqualTo(2); + } + } + + @Test + void testRightJoin() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(orderLine, "ol") + .rightJoin(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .orderBy(itemMaster.itemId) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from OrderLine ol right join ItemMaster im on ol.item_id = im.item_id" + + " order by item_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(5); + Map<String, Object> row = rows.get(2); + assertThat(row).containsEntry("ORDER_ID", 1); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "First Base Glove"); + assertThat(row).containsEntry("ITEM_ID", 33); + + row = rows.get(4); + assertThat(row).doesNotContainKey("ORDER_ID"); + assertThat(row).doesNotContainKey("QUANTITY"); + assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); + assertThat(row).containsEntry("ITEM_ID", 55); + } + } + + @Test + void testRightJoin2() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(orderMaster, "om") + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .rightJoin(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .orderBy(orderLine.orderId, itemMaster.itemId) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" + + " right join ItemMaster im on ol.item_id = im.item_id" + + " order by order_id, item_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(5); + Map<String, Object> row = rows.get(0); + assertThat(row).doesNotContainKey("ORDER_ID"); + assertThat(row).doesNotContainKey("QUANTITY"); + assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); + assertThat(row).containsEntry("ITEM_ID", 55); + + row = rows.get(4); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); + assertThat(row).containsEntry("ITEM_ID", 44); + } + } + + @Test + void testRightJoin3() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(orderMaster, "om") + .join(orderLine, "ol", on(orderMaster.orderId, isEqualTo(orderLine.orderId))) + .rightJoin(itemMaster, "im", on(orderLine.itemId, isEqualTo(itemMaster.itemId))) + .orderBy(orderLine.orderId, itemMaster.itemId) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" + + " right join ItemMaster im on ol.item_id = im.item_id" + + " order by order_id, item_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(5); + Map<String, Object> row = rows.get(0); + assertThat(row).doesNotContainKey("ORDER_ID"); + assertThat(row).doesNotContainKey("QUANTITY"); + assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); + assertThat(row).containsEntry("ITEM_ID", 55); + + row = rows.get(4); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); + assertThat(row).containsEntry("ITEM_ID", 44); + } + } + + @Test + void testRightJoinNoAliases() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(orderMaster) + .join(orderLine).on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .rightJoin(itemMaster).on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .orderBy(orderLine.orderId, itemMaster.itemId) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select OrderLine.order_id, OrderLine.quantity, ItemMaster.item_id, ItemMaster.description" + + " from OrderMaster join OrderLine on OrderMaster.order_id = OrderLine.order_id" + + " right join ItemMaster on OrderLine.item_id = ItemMaster.item_id" + + " order by order_id, item_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(5); + Map<String, Object> row = rows.get(0); + assertThat(row).doesNotContainKey("ORDER_ID"); + assertThat(row).doesNotContainKey("QUANTITY"); + assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); + assertThat(row).containsEntry("ITEM_ID", 55); + + row = rows.get(4); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); + assertThat(row).containsEntry("ITEM_ID", 44); + } + } + + @Test + void testLeftJoin() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(itemMaster, "im") + .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .orderBy(itemMaster.itemId) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from ItemMaster im left join OrderLine ol on ol.item_id = im.item_id" + + " order by item_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(5); + Map<String, Object> row = rows.get(2); + assertThat(row).containsEntry("ORDER_ID", 1); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "First Base Glove"); + assertThat(row).containsEntry("ITEM_ID", 33); + + row = rows.get(4); + assertThat(row).doesNotContainKey("ORDER_ID"); + assertThat(row).doesNotContainKey("QUANTITY"); + assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); + assertThat(row).containsEntry("ITEM_ID", 55); + } + } + + @Test + void testLeftJoin2() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(orderMaster, "om") + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .leftJoin(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .orderBy(orderLine.orderId, itemMaster.itemId) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" + + " left join ItemMaster im on ol.item_id = im.item_id" + + " order by order_id, item_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(5); + Map<String, Object> row = rows.get(2); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 6); + assertThat(row).doesNotContainKey("DESCRIPTION"); + assertThat(row).doesNotContainKey("ITEM_ID"); + + row = rows.get(4); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); + assertThat(row).containsEntry("ITEM_ID", 44); + } + } + + @Test + void testLeftJoin3() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(orderMaster, "om") + .join(orderLine, "ol", on(orderMaster.orderId, isEqualTo(orderLine.orderId))) + .leftJoin(itemMaster, "im", on(orderLine.itemId, isEqualTo(itemMaster.itemId))) + .orderBy(orderLine.orderId, itemMaster.itemId) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" + + " left join ItemMaster im on ol.item_id = im.item_id" + + " order by order_id, item_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(5); + Map<String, Object> row = rows.get(2); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 6); + assertThat(row).doesNotContainKey("DESCRIPTION"); + assertThat(row).doesNotContainKey("ITEM_ID"); + + row = rows.get(4); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); + assertThat(row).containsEntry("ITEM_ID", 44); + } + } + + @Test + void testLeftJoinNoAliases() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(orderMaster) + .join(orderLine).on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .leftJoin(itemMaster).on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .orderBy(orderLine.orderId, itemMaster.itemId) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select OrderLine.order_id, OrderLine.quantity, ItemMaster.item_id, ItemMaster.description" + + " from OrderMaster join OrderLine on OrderMaster.order_id = OrderLine.order_id" + + " left join ItemMaster on OrderLine.item_id = ItemMaster.item_id" + + " order by order_id, item_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(5); + Map<String, Object> row = rows.get(2); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 6); + assertThat(row).doesNotContainKey("DESCRIPTION"); + assertThat(row).doesNotContainKey("ITEM_ID"); + + row = rows.get(4); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); + assertThat(row).containsEntry("ITEM_ID", 44); + } + } + + @Test + void testFullJoin() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, orderLine.itemId.as("ol_itemid"), itemMaster.itemId.as("im_itemid"), itemMaster.description) + .from(itemMaster, "im") + .fullJoin(orderLine, "ol").on(itemMaster.itemId, isEqualTo(orderLine.itemId)) + .orderBy(orderLine.orderId, sortColumn("im_itemid")) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, ol.item_id as ol_itemid, im.item_id as im_itemid, im.description" + + " from ItemMaster im full join OrderLine ol on im.item_id = ol.item_id" + + " order by order_id, im_itemid"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(6); + Map<String, Object> row = rows.get(0); + assertThat(row).doesNotContainKey("ORDER_ID"); + assertThat(row).doesNotContainKey("QUANTITY"); + assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); + assertThat(row).containsEntry("IM_ITEMID", 55); + + row = rows.get(2); + assertThat(row).containsEntry("ORDER_ID", 1); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "First Base Glove"); + assertThat(row).containsEntry("IM_ITEMID", 33); + + row = rows.get(3); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 6); + assertThat(row).containsEntry("OL_ITEMID", 66); + assertThat(row).doesNotContainKey("DESCRIPTION"); + assertThat(row).doesNotContainKey("IM_ITEMID"); + } + } + + @Test + void testFullJoin2() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(orderMaster, "om") + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .fullJoin(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .orderBy(orderLine.orderId, itemMaster.itemId) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" + + " full join ItemMaster im on ol.item_id = im.item_id" + + " order by order_id, item_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(6); + Map<String, Object> row = rows.get(0); + assertThat(row).doesNotContainKey("ORDER_ID"); + assertThat(row).doesNotContainKey("QUANTITY"); + assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); + assertThat(row).containsEntry("ITEM_ID", 55); + + row = rows.get(3); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 6); + assertThat(row).doesNotContainKey("DESCRIPTION"); + assertThat(row).doesNotContainKey("ITEM_ID"); + + row = rows.get(5); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); + assertThat(row).containsEntry("ITEM_ID", 44); + } + } + + @Test + void testFullJoin3() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(orderMaster, "om") + .join(orderLine, "ol", on(orderMaster.orderId, isEqualTo(orderLine.orderId))) + .fullJoin(itemMaster, "im", on(orderLine.itemId, isEqualTo(itemMaster.itemId))) + .orderBy(orderLine.orderId, itemMaster.itemId) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" + + " full join ItemMaster im on ol.item_id = im.item_id" + + " order by order_id, item_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(6); + Map<String, Object> row = rows.get(0); + assertThat(row).doesNotContainKey("ORDER_ID"); + assertThat(row).doesNotContainKey("QUANTITY"); + assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); + assertThat(row).containsEntry("ITEM_ID", 55); + + row = rows.get(3); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 6); + assertThat(row).doesNotContainKey("DESCRIPTION"); + assertThat(row).doesNotContainKey("ITEM_ID"); + + row = rows.get(5); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); + assertThat(row).containsEntry("ITEM_ID", 44); + } + } + + @Test + void testFullJoin4() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.description) + .from(orderMaster, "om") + .join(orderLine, "ol", on(orderMaster.orderId, isEqualTo(orderLine.orderId))) + .fullJoin(itemMaster, "im", on(orderLine.itemId, isEqualTo(itemMaster.itemId))) + .orderBy(orderLine.orderId, sortColumn("im", itemMaster.itemId)) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, im.description" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" + + " full join ItemMaster im on ol.item_id = im.item_id" + + " order by order_id, im.item_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(6); + Map<String, Object> row = rows.get(0); + assertThat(row).doesNotContainKey("ORDER_ID"); + assertThat(row).doesNotContainKey("QUANTITY"); + assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); + + row = rows.get(3); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 6); + assertThat(row).doesNotContainKey("DESCRIPTION"); + + row = rows.get(5); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); + } + } + + @Test + void testFullJoin5() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.description) + .from(orderMaster, "om") + .join(orderLine, "ol", on(orderMaster.orderId, isEqualTo(orderLine.orderId))) + .fullJoin(itemMaster, "im", on(orderLine.itemId, isEqualTo(itemMaster.itemId))) + .orderBy(orderLine.orderId, sortColumn("im", itemMaster.itemId).descending()) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, im.description" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" + + " full join ItemMaster im on ol.item_id = im.item_id" + + " order by order_id, im.item_id DESC"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(6); + Map<String, Object> row = rows.get(0); + assertThat(row).doesNotContainKey("ORDER_ID"); + assertThat(row).doesNotContainKey("QUANTITY"); + assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); + + row = rows.get(3); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 6); + assertThat(row).doesNotContainKey("DESCRIPTION"); + + row = rows.get(5); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Helmet"); + } + } + + @Test + void testFullJoinNoAliases() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(orderMaster) + .join(orderLine).on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .fullJoin(itemMaster).on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .orderBy(orderLine.orderId, itemMaster.itemId) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select OrderLine.order_id, OrderLine.quantity, ItemMaster.item_id, ItemMaster.description" + + " from OrderMaster join OrderLine on OrderMaster.order_id = OrderLine.order_id" + + " full join ItemMaster on OrderLine.item_id = ItemMaster.item_id" + + " order by order_id, item_id"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(6); + Map<String, Object> row = rows.get(0); + assertThat(row).doesNotContainKey("ORDER_ID"); + assertThat(row).doesNotContainKey("QUANTITY"); + assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); + assertThat(row).containsEntry("ITEM_ID", 55); + + row = rows.get(3); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 6); + assertThat(row).doesNotContainKey("DESCRIPTION"); + assertThat(row).doesNotContainKey("ITEM_ID"); + + row = rows.get(5); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); + assertThat(row).containsEntry("ITEM_ID", 44); + } + } + + @Test + void testSelf() { + try (SqlSession session = sqlSessionFactory.openSession()) { + JoinMapper mapper = session.getMapper(JoinMapper.class); + + // create second table instance for self-join + UserDynamicSQLSupport.User user2 = new UserDynamicSQLSupport.User(); + + // get Bamm Bamm's parent - should be Barney + SelectStatementProvider selectStatement = select(user.userId, user.userName, user.parentId) + .from(user, "u1") + .join(user2, "u2").on(user.userId, isEqualTo(user2.parentId)) + .where(user2.userId, isEqualTo(4)) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select u1.user_id, u1.user_name, u1.parent_id" + + " from User u1 join User u2 on u1.user_id = u2.parent_id" + + " where u2.user_id = #{parameters.p1,jdbcType=INTEGER}"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<User> rows = mapper.selectUsers(selectStatement); + + assertThat(rows).hasSize(1); + User row = rows.get(0); + assertThat(row.getUserId()).isEqualTo(2); + assertThat(row.getUserName()).isEqualTo("Barney"); + assertThat(row.getParentId()).isNull(); + } + } + + @Test + void testSelfWithDuplicateAlias() { + QueryExpressionDSL<SelectModel> dsl = select(user.userId, user.userName, user.parentId) + .from(user, "u1"); + + assertThatExceptionOfType(DuplicateTableAliasException.class).isThrownBy(() -> dsl.join(user, "u2")) + .withMessage(Messages.getString("ERROR.1", user.tableName(), "u2", "u1")); + } + + @Test + void testSelfWithNewAlias() { + try (SqlSession session = sqlSessionFactory.openSession()) { + JoinMapper mapper = session.getMapper(JoinMapper.class); + + // create second table instance for self-join + UserDynamicSQLSupport.User user2 = user.withAlias("u2"); + + // get Bamm Bamm's parent - should be Barney + SelectStatementProvider selectStatement = select(user.userId, user.userName, user.parentId) + .from(user) + .join(user2).on(user.userId, isEqualTo(user2.parentId)) + .where(user2.userId, isEqualTo(4)) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select User.user_id, User.user_name, User.parent_id" + + " from User join User u2 on User.user_id = u2.parent_id" + + " where u2.user_id = #{parameters.p1,jdbcType=INTEGER}"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<User> rows = mapper.selectUsers(selectStatement); + + assertThat(rows).hasSize(1); + User row = rows.get(0); + assertThat(row.getUserId()).isEqualTo(2); + assertThat(row.getUserName()).isEqualTo("Barney"); + assertThat(row.getParentId()).isNull(); + } + } + + @Test + void testSelfWithNewAliasAndOverride() { + try (SqlSession session = sqlSessionFactory.openSession()) { + JoinMapper mapper = session.getMapper(JoinMapper.class); + + // create second table instance for self-join + UserDynamicSQLSupport.User user2 = user.withAlias("other_user"); + + // get Bamm Bamm's parent - should be Barney + SelectStatementProvider selectStatement = select(user.userId, user.userName, user.parentId) + .from(user, "u1") + .join(user2, "u2").on(user.userId, isEqualTo(user2.parentId)) + .where(user2.userId, isEqualTo(4)) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select u1.user_id, u1.user_name, u1.parent_id" + + " from User u1 join User u2 on u1.user_id = u2.parent_id" + + " where u2.user_id = #{parameters.p1,jdbcType=INTEGER}"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<User> rows = mapper.selectUsers(selectStatement); + + assertThat(rows).hasSize(1); + User row = rows.get(0); + assertThat(row.getUserId()).isEqualTo(2); + assertThat(row.getUserName()).isEqualTo("Barney"); + assertThat(row.getParentId()).isNull(); + } + } + + @Test + void testLimitAndOffsetAfterJoin() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(itemMaster, "im") + .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .limit(2) + .offset(1) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from ItemMaster im left join OrderLine ol on ol.item_id = im.item_id" + + " limit #{parameters.p1} offset #{parameters.p2}"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(2); + Map<String, Object> row = rows.get(0); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Helmet"); + assertThat(row).containsEntry("ITEM_ID", 22); + + row = rows.get(1); + assertThat(row).containsEntry("ORDER_ID", 1); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "First Base Glove"); + assertThat(row).containsEntry("ITEM_ID", 33); + } + } + + @Test + void testLimitOnlyAfterJoin() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(itemMaster, "im") + .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .limit(2) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from ItemMaster im left join OrderLine ol on ol.item_id = im.item_id" + + " limit #{parameters.p1}"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(2); + Map<String, Object> row = rows.get(0); + assertThat(row).containsEntry("ORDER_ID", 1); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Helmet"); + assertThat(row).containsEntry("ITEM_ID", 22); + + row = rows.get(1); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Helmet"); + assertThat(row).containsEntry("ITEM_ID", 22); + } + } + + @Test + void testOffsetOnlyAfterJoin() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(itemMaster, "im") + .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .offset(2) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from ItemMaster im left join OrderLine ol on ol.item_id = im.item_id" + + " offset #{parameters.p1} rows"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(3); + Map<String, Object> row = rows.get(0); + assertThat(row).containsEntry("ORDER_ID", 1); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "First Base Glove"); + assertThat(row).containsEntry("ITEM_ID", 33); + + row = rows.get(1); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); + assertThat(row).containsEntry("ITEM_ID", 44); + } + } + + @Test + void testOffsetAndFetchFirstAfterJoin() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(itemMaster, "im") + .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .offset(1) + .fetchFirst(2).rowsOnly() + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from ItemMaster im left join OrderLine ol on ol.item_id = im.item_id" + + " offset #{parameters.p1} rows fetch first #{parameters.p2} rows only"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(2); + Map<String, Object> row = rows.get(0); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Helmet"); + assertThat(row).containsEntry("ITEM_ID", 22); + + row = rows.get(1); + assertThat(row).containsEntry("ORDER_ID", 1); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "First Base Glove"); + assertThat(row).containsEntry("ITEM_ID", 33); + } + } + + @Test + void testFetchFirstOnlyAfterJoin() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(itemMaster, "im") + .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .fetchFirst(2).rowsOnly() + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from ItemMaster im left join OrderLine ol on ol.item_id = im.item_id" + + " fetch first #{parameters.p1} rows only"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(2); + Map<String, Object> row = rows.get(0); + assertThat(row).containsEntry("ORDER_ID", 1); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Helmet"); + assertThat(row).containsEntry("ITEM_ID", 22); + + row = rows.get(1); + assertThat(row).containsEntry("ORDER_ID", 2); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Helmet"); + assertThat(row).containsEntry("ITEM_ID", 22); + } + } + + @Test + void testJoinWithParameterValue() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(itemMaster, "im") + .join(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .and(orderLine.orderId, isEqualTo(1)) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from ItemMaster im join OrderLine ol on ol.item_id = im.item_id" + + " and ol.order_id = #{parameters.p1,jdbcType=INTEGER}"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(2); + Map<String, Object> row = rows.get(0); + assertThat(row).containsEntry("ORDER_ID", 1); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Helmet"); + assertThat(row).containsEntry("ITEM_ID", 22); + + row = rows.get(1); + assertThat(row).containsEntry("ORDER_ID", 1); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "First Base Glove"); + assertThat(row).containsEntry("ITEM_ID", 33); + } + } + + @Test + void testJoinWithConstant() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) + .from(itemMaster, "im") + .join(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .and(orderLine.orderId, isEqualTo(constant("1"))) + .build() + .render(RenderingStrategies.MYBATIS3); + + String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from ItemMaster im join OrderLine ol on ol.item_id = im.item_id" + + " and ol.order_id = 1"; + assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + + assertThat(rows).hasSize(2); + Map<String, Object> row = rows.get(0); + assertThat(row).containsEntry("ORDER_ID", 1); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "Helmet"); + assertThat(row).containsEntry("ITEM_ID", 22); + + row = rows.get(1); + assertThat(row).containsEntry("ORDER_ID", 1); + assertThat(row).containsEntry("QUANTITY", 1); + assertThat(row).containsEntry("DESCRIPTION", "First Base Glove"); + assertThat(row).containsEntry("ITEM_ID", 33); + } + } +} From 6816dacbe6097495adfd044d8f3cd71607a026a2 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 12 Aug 2024 20:46:31 -0400 Subject: [PATCH 061/260] Remove obsolete code --- .../org/mybatis/dynamic/sql/SqlBuilder.java | 4 - .../sql/select/QueryExpressionDSL.java | 8 +- .../select/join/ColumnBasedJoinCondition.java | 37 ---------- .../dynamic/sql/select/join/EqualTo.java | 30 -------- .../dynamic/sql/select/join/EqualToValue.java | 27 ------- .../sql/select/join/JoinCondition.java | 22 ------ .../sql/select/join/JoinConditionVisitor.java | 22 ------ .../sql/select/join/JoinCriterion.java | 70 ------------------ .../sql/select/join/TypedJoinCondition.java | 35 --------- .../select/render/JoinConditionRenderer.java | 73 ------------------- 10 files changed, 4 insertions(+), 324 deletions(-) delete mode 100644 src/main/java/org/mybatis/dynamic/sql/select/join/ColumnBasedJoinCondition.java delete mode 100644 src/main/java/org/mybatis/dynamic/sql/select/join/EqualTo.java delete mode 100644 src/main/java/org/mybatis/dynamic/sql/select/join/EqualToValue.java delete mode 100644 src/main/java/org/mybatis/dynamic/sql/select/join/JoinCondition.java delete mode 100644 src/main/java/org/mybatis/dynamic/sql/select/join/JoinConditionVisitor.java delete mode 100644 src/main/java/org/mybatis/dynamic/sql/select/join/JoinCriterion.java delete mode 100644 src/main/java/org/mybatis/dynamic/sql/select/join/TypedJoinCondition.java delete mode 100644 src/main/java/org/mybatis/dynamic/sql/select/render/JoinConditionRenderer.java diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java index 13f385e21..88871f6f0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java @@ -56,10 +56,6 @@ import org.mybatis.dynamic.sql.select.function.Substring; import org.mybatis.dynamic.sql.select.function.Subtract; import org.mybatis.dynamic.sql.select.function.Upper; -import org.mybatis.dynamic.sql.select.join.EqualTo; -import org.mybatis.dynamic.sql.select.join.EqualToValue; -import org.mybatis.dynamic.sql.select.join.JoinCondition; -import org.mybatis.dynamic.sql.select.join.JoinCriterion; import org.mybatis.dynamic.sql.update.UpdateDSL; import org.mybatis.dynamic.sql.update.UpdateModel; import org.mybatis.dynamic.sql.util.Buildable; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java index 4c025b660..be1121c85 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java @@ -362,11 +362,11 @@ public <T> JoinSpecificationFinisher(TableExpression table, BindableColumn<T> jo this.joinType = joinType; addJoinSpecificationSupplier(this::buildJoinSpecification); - ColumnAndConditionCriterion<T> c = ColumnAndConditionCriterion.withColumn(joinColumn) + ColumnAndConditionCriterion<T> criterion = ColumnAndConditionCriterion.withColumn(joinColumn) .withCondition(joinCondition) .build(); - setInitialCriterion(c); + setInitialCriterion(criterion); } public <T> JoinSpecificationFinisher(TableExpression table, BindableColumn<T> joinColumn, @@ -375,12 +375,12 @@ public <T> JoinSpecificationFinisher(TableExpression table, BindableColumn<T> jo this.joinType = joinType; addJoinSpecificationSupplier(this::buildJoinSpecification); - ColumnAndConditionCriterion<T> c = ColumnAndConditionCriterion.withColumn(joinColumn) + ColumnAndConditionCriterion<T> criterion = ColumnAndConditionCriterion.withColumn(joinColumn) .withCondition(joinCondition) .withSubCriteria(Arrays.asList(subCriteria)) .build(); - setInitialCriterion(c); + setInitialCriterion(criterion); } private JoinSpecification buildJoinSpecification() { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/join/ColumnBasedJoinCondition.java b/src/main/java/org/mybatis/dynamic/sql/select/join/ColumnBasedJoinCondition.java deleted file mode 100644 index 712010ca6..000000000 --- a/src/main/java/org/mybatis/dynamic/sql/select/join/ColumnBasedJoinCondition.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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.select.join; - -import java.util.Objects; - -import org.mybatis.dynamic.sql.BasicColumn; - -public abstract class ColumnBasedJoinCondition<T> implements JoinCondition<T> { - private final BasicColumn rightColumn; - - protected ColumnBasedJoinCondition(BasicColumn rightColumn) { - this.rightColumn = Objects.requireNonNull(rightColumn); - } - - public BasicColumn rightColumn() { - return rightColumn; - } - - @Override - public <R> R accept(JoinConditionVisitor<T, R> visitor) { - return visitor.visit(this); - } -} diff --git a/src/main/java/org/mybatis/dynamic/sql/select/join/EqualTo.java b/src/main/java/org/mybatis/dynamic/sql/select/join/EqualTo.java deleted file mode 100644 index 6f12eb052..000000000 --- a/src/main/java/org/mybatis/dynamic/sql/select/join/EqualTo.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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.select.join; - -import org.mybatis.dynamic.sql.BasicColumn; - -public class EqualTo<T> extends ColumnBasedJoinCondition<T> { - - public EqualTo(BasicColumn rightColumn) { - super(rightColumn); - } - - @Override - public String operator() { - return "="; //$NON-NLS-1$ - } -} diff --git a/src/main/java/org/mybatis/dynamic/sql/select/join/EqualToValue.java b/src/main/java/org/mybatis/dynamic/sql/select/join/EqualToValue.java deleted file mode 100644 index 2d038aa21..000000000 --- a/src/main/java/org/mybatis/dynamic/sql/select/join/EqualToValue.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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.select.join; - -public class EqualToValue<T> extends TypedJoinCondition<T> { - public EqualToValue(T value) { - super(value); - } - - @Override - public String operator() { - return "="; //$NON-NLS-1$ - } -} diff --git a/src/main/java/org/mybatis/dynamic/sql/select/join/JoinCondition.java b/src/main/java/org/mybatis/dynamic/sql/select/join/JoinCondition.java deleted file mode 100644 index 183bd9a02..000000000 --- a/src/main/java/org/mybatis/dynamic/sql/select/join/JoinCondition.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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.select.join; - -public interface JoinCondition<T> { - String operator(); - - <R> R accept(JoinConditionVisitor<T, R> visitor); -} diff --git a/src/main/java/org/mybatis/dynamic/sql/select/join/JoinConditionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/select/join/JoinConditionVisitor.java deleted file mode 100644 index 582b332f1..000000000 --- a/src/main/java/org/mybatis/dynamic/sql/select/join/JoinConditionVisitor.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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.select.join; - -public interface JoinConditionVisitor<T, R> { - R visit(TypedJoinCondition<T> condition); - - R visit(ColumnBasedJoinCondition<T> condition); -} diff --git a/src/main/java/org/mybatis/dynamic/sql/select/join/JoinCriterion.java b/src/main/java/org/mybatis/dynamic/sql/select/join/JoinCriterion.java deleted file mode 100644 index 81925f0e4..000000000 --- a/src/main/java/org/mybatis/dynamic/sql/select/join/JoinCriterion.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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.select.join; - -import java.util.Objects; - -import org.mybatis.dynamic.sql.BindableColumn; - -public class JoinCriterion<T> { - - private final String connector; - private final BindableColumn<T> leftColumn; - private final JoinCondition<T> joinCondition; - - private JoinCriterion(Builder<T> builder) { - connector = Objects.requireNonNull(builder.connector); - leftColumn = Objects.requireNonNull(builder.joinColumn); - joinCondition = Objects.requireNonNull(builder.joinCondition); - } - - public String connector() { - return connector; - } - - public BindableColumn<T> leftColumn() { - return leftColumn; - } - - public JoinCondition<T> joinCondition() { - return joinCondition; - } - - public static class Builder<T> { - private String connector; - private BindableColumn<T> joinColumn; - private JoinCondition<T> joinCondition; - - public Builder<T> withConnector(String connector) { - this.connector = connector; - return this; - } - - public Builder<T> withJoinColumn(BindableColumn<T> joinColumn) { - this.joinColumn = joinColumn; - return this; - } - - public Builder<T> withJoinCondition(JoinCondition<T> joinCondition) { - this.joinCondition = joinCondition; - return this; - } - - public JoinCriterion<T> build() { - return new JoinCriterion<>(this); - } - } -} diff --git a/src/main/java/org/mybatis/dynamic/sql/select/join/TypedJoinCondition.java b/src/main/java/org/mybatis/dynamic/sql/select/join/TypedJoinCondition.java deleted file mode 100644 index 12b310d1f..000000000 --- a/src/main/java/org/mybatis/dynamic/sql/select/join/TypedJoinCondition.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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.select.join; - -import java.util.Objects; - -public abstract class TypedJoinCondition<T> implements JoinCondition<T> { - private final T value; - - protected TypedJoinCondition(T value) { - this.value = Objects.requireNonNull(value); - } - - public T value() { - return value; - } - - @Override - public <R> R accept(JoinConditionVisitor<T, R> visitor) { - return visitor.visit(this); - } -} diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/JoinConditionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/JoinConditionRenderer.java deleted file mode 100644 index 2cba1a951..000000000 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/JoinConditionRenderer.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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.select.render; - -import static org.mybatis.dynamic.sql.util.StringUtilities.spaceBefore; - -import java.util.Objects; - -import org.mybatis.dynamic.sql.BindableColumn; -import org.mybatis.dynamic.sql.render.RenderedParameterInfo; -import org.mybatis.dynamic.sql.render.RenderingContext; -import org.mybatis.dynamic.sql.select.join.ColumnBasedJoinCondition; -import org.mybatis.dynamic.sql.select.join.JoinConditionVisitor; -import org.mybatis.dynamic.sql.select.join.TypedJoinCondition; -import org.mybatis.dynamic.sql.util.FragmentAndParameters; - -public class JoinConditionRenderer<T> implements JoinConditionVisitor<T, FragmentAndParameters> { - private final BindableColumn<T> leftColumn; - private final RenderingContext renderingContext; - - private JoinConditionRenderer(Builder<T> builder) { - leftColumn = Objects.requireNonNull(builder.leftColumn); - renderingContext = Objects.requireNonNull(builder.renderingContext); - } - - @Override - public FragmentAndParameters visit(TypedJoinCondition<T> condition) { - RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo(leftColumn); - - return FragmentAndParameters - .withFragment(condition.operator() + spaceBefore(parameterInfo.renderedPlaceHolder())) - .withParameter(parameterInfo.parameterMapKey(), condition.value()) - .build(); - } - - @Override - public FragmentAndParameters visit(ColumnBasedJoinCondition<T> condition) { - return condition.rightColumn().render(renderingContext) - .mapFragment(s -> condition.operator() + spaceBefore(s)); - } - - public static class Builder<T> { - private BindableColumn<T> leftColumn; - private RenderingContext renderingContext; - - public Builder<T> withLeftColumn(BindableColumn<T> leftColumn) { - this.leftColumn = leftColumn; - return this; - } - - public Builder<T> withRenderingContext(RenderingContext renderingContext) { - this.renderingContext = renderingContext; - return this; - } - - public JoinConditionRenderer<T> build() { - return new JoinConditionRenderer<>(this); - } - } -} From 3cc83da9613e8c6fb04044ba91ac888c90ed42be Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 13 Aug 2024 20:55:43 -0400 Subject: [PATCH 062/260] Update Kotlin DSL for new Join syntax --- .../dynamic/sql/util/kotlin/JoinCollector.kt | 19 +- .../sql/util/kotlin/KotlinBaseBuilders.kt | 24 +- .../mybatis3/joins/JoinMapperNewSyntaxTest.kt | 818 ++++++++++++++++++ 3 files changed, 844 insertions(+), 17 deletions(-) create mode 100644 src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt index 6212167c1..0cb43d1d4 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt @@ -26,19 +26,28 @@ typealias JoinReceiver = JoinCollector.() -> Unit @MyBatisDslMarker class JoinCollector { - private var onJoinCriterion: SqlCriterion? = null - internal val andJoinCriteria = mutableListOf<AndOrCriteriaGroup>() + private var initialCriterion: SqlCriterion? = null + internal val subCriteria = mutableListOf<AndOrCriteriaGroup>() - internal fun onJoinCriterion() : SqlCriterion = invalidIfNull(onJoinCriterion, "ERROR.22") //$NON-NLS-1$ + internal fun initialCriterion() : SqlCriterion = invalidIfNull(initialCriterion, "ERROR.22") //$NON-NLS-1$ + fun on (receiver: GroupingCriteriaReceiver) { + GroupingCriteriaCollector().apply(receiver).also { + initialCriterion = it.initialCriterion + subCriteria.addAll(it.subCriteria) + } + } + + // TODO - Deprecate? fun <T> on(leftColumn: BindableColumn<T>): RightColumnCollector<T> = RightColumnCollector { - onJoinCriterion = ColumnAndConditionCriterion.withColumn(leftColumn) + initialCriterion = ColumnAndConditionCriterion.withColumn(leftColumn) .withCondition(it) .build() } + // TODO - Deprecate? fun <T> and(leftColumn: BindableColumn<T>): RightColumnCollector<T> = RightColumnCollector { - andJoinCriteria.add( + subCriteria.add( AndOrCriteriaGroup.Builder() .withConnector("and") //$NON-NLS-1$ .withInitialCriterion(ColumnAndConditionCriterion.withColumn(leftColumn).withCondition(it).build()) diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt index 4207905c6..e9d070320 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt @@ -66,12 +66,12 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> : fun join(table: SqlTable, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> - join(table, jc.onJoinCriterion(), jc.andJoinCriteria) + join(table, jc.initialCriterion(), jc.subCriteria) } fun join(table: SqlTable, alias: String, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> - join(table, alias, jc.onJoinCriterion(), jc.andJoinCriteria) + join(table, alias, jc.initialCriterion(), jc.subCriteria) } fun join( @@ -79,17 +79,17 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> : joinCriteria: JoinReceiver ): Unit = applyToDsl(subQuery, joinCriteria) { sq, jc -> - join(sq, sq.correlationName, jc.onJoinCriterion(), jc.andJoinCriteria) + join(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria) } fun fullJoin(table: SqlTable, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> - fullJoin(table, jc.onJoinCriterion(), jc.andJoinCriteria) + fullJoin(table, jc.initialCriterion(), jc.subCriteria) } fun fullJoin(table: SqlTable, alias: String, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> - fullJoin(table, alias, jc.onJoinCriterion(), jc.andJoinCriteria) + fullJoin(table, alias, jc.initialCriterion(), jc.subCriteria) } fun fullJoin( @@ -97,17 +97,17 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> : joinCriteria: JoinReceiver ): Unit = applyToDsl(subQuery, joinCriteria) { sq, jc -> - fullJoin(sq, sq.correlationName, jc.onJoinCriterion(), jc.andJoinCriteria) + fullJoin(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria) } fun leftJoin(table: SqlTable, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> - leftJoin(table, jc.onJoinCriterion(), jc.andJoinCriteria) + leftJoin(table, jc.initialCriterion(), jc.subCriteria) } fun leftJoin(table: SqlTable, alias: String, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> - leftJoin(table, alias, jc.onJoinCriterion(), jc.andJoinCriteria) + leftJoin(table, alias, jc.initialCriterion(), jc.subCriteria) } fun leftJoin( @@ -115,17 +115,17 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> : joinCriteria: JoinReceiver ): Unit = applyToDsl(subQuery, joinCriteria) { sq, jc -> - leftJoin(sq, sq.correlationName, jc.onJoinCriterion(), jc.andJoinCriteria) + leftJoin(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria) } fun rightJoin(table: SqlTable, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> - rightJoin(table, jc.onJoinCriterion(), jc.andJoinCriteria) + rightJoin(table, jc.initialCriterion(), jc.subCriteria) } fun rightJoin(table: SqlTable, alias: String, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> - rightJoin(table, alias, jc.onJoinCriterion(), jc.andJoinCriteria) + rightJoin(table, alias, jc.initialCriterion(), jc.subCriteria) } fun rightJoin( @@ -133,7 +133,7 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> : joinCriteria: JoinReceiver ): Unit = applyToDsl(subQuery, joinCriteria) { sq, jc -> - rightJoin(sq, sq.correlationName, jc.onJoinCriterion(), jc.andJoinCriteria) + rightJoin(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria) } private fun applyToDsl(joinCriteria: JoinReceiver, applyJoin: D.(JoinCollector) -> Unit) { diff --git a/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt new file mode 100644 index 000000000..a99124a12 --- /dev/null +++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt @@ -0,0 +1,818 @@ +/* + * Copyright 2016-2024 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 + * + * https://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.kotlin.mybatis3.joins + +import examples.kotlin.mybatis3.TestUtils +import examples.kotlin.mybatis3.joins.ItemMasterDynamicSQLSupport.itemMaster +import examples.kotlin.mybatis3.joins.OrderDetailDynamicSQLSupport.orderDetail +import examples.kotlin.mybatis3.joins.OrderLineDynamicSQLSupport.orderLine +import examples.kotlin.mybatis3.joins.OrderMasterDynamicSQLSupport.orderMaster +import examples.kotlin.mybatis3.joins.UserDynamicSQLSupport.user +import org.apache.ibatis.session.SqlSessionFactory +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.assertThatExceptionOfType +import org.assertj.core.api.Assertions.entry +import org.junit.jupiter.api.BeforeAll +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance +import org.mybatis.dynamic.sql.util.Messages +import org.mybatis.dynamic.sql.util.kotlin.KInvalidSQLException +import org.mybatis.dynamic.sql.util.kotlin.elements.constant +import org.mybatis.dynamic.sql.util.kotlin.elements.invoke +import org.mybatis.dynamic.sql.util.kotlin.mybatis3.select + +@Suppress("LargeClass") +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class JoinMapperNewSyntaxTest { + private lateinit var sqlSessionFactory: SqlSessionFactory + + @BeforeAll + fun setup() { + sqlSessionFactory = TestUtils.buildSqlSessionFactory { + withInitializationScript("/examples/kotlin/mybatis3/joins/CreateJoinDB.sql") + withMapper(JoinMapper::class) + } + } + + @Test + fun testSingleTableJoin() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(JoinMapper::class.java) + + val selectStatement = select( + orderMaster.orderId, orderMaster.orderDate, + orderDetail.lineNumber, orderDetail.description, orderDetail.quantity + ) { + from(orderMaster, "om") + join(orderDetail, "od") { + on { orderMaster.orderId isEqualTo orderDetail.orderId } + } + } + + val expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" + + " from OrderMaster om join OrderDetail od on om.order_id = od.order_id" + + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + + val rows = mapper.selectMany(selectStatement) + + assertThat(rows).hasSize(2) + + with(rows[0]) { + assertThat(id).isEqualTo(1) + assertThat(details).hasSize(2) + assertThat(details?.get(0)?.lineNumber).isEqualTo(1) + assertThat(details?.get(1)?.lineNumber).isEqualTo(2) + } + + with(rows[1]) { + assertThat(id).isEqualTo(2) + assertThat(details).hasSize(1) + assertThat(details?.get(0)?.lineNumber).isEqualTo(1) + } + } + } + + @Test + fun testSingleTableJoinWithValue() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(JoinMapper::class.java) + + val selectStatement = select( + orderMaster.orderId, orderMaster.orderDate, + orderDetail.lineNumber, orderDetail.description, orderDetail.quantity + ) { + from(orderMaster, "om") + join(orderDetail, "od") { + on { + orderMaster.orderId isEqualTo orderDetail.orderId + and { orderMaster.orderId isEqualTo 1 } + } + } + } + + val expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" + + " from OrderMaster om join OrderDetail od on om.order_id = od.order_id" + + " and om.order_id = #{parameters.p1,jdbcType=INTEGER}" + + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + + val rows = mapper.selectMany(selectStatement) + + assertThat(rows).hasSize(1) + + with(rows[0]) { + assertThat(id).isEqualTo(1) + assertThat(details).hasSize(2) + assertThat(details?.get(0)?.lineNumber).isEqualTo(1) + assertThat(details?.get(1)?.lineNumber).isEqualTo(2) + } + } + } + + @Test + fun testSingleTableJoinWithConstant() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(JoinMapper::class.java) + + val selectStatement = select( + orderMaster.orderId, orderMaster.orderDate, + orderDetail.lineNumber, orderDetail.description, orderDetail.quantity + ) { + from(orderMaster, "om") + join(orderDetail, "od") { + on { + orderMaster.orderId isEqualTo orderDetail.orderId + and { orderMaster.orderId isEqualTo constant<Int>("1") } + } + } + } + + val expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" + + " from OrderMaster om join OrderDetail od on om.order_id = od.order_id" + + " and om.order_id = 1" + + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + + val rows = mapper.selectMany(selectStatement) + + assertThat(rows).hasSize(1) + + with(rows[0]) { + assertThat(id).isEqualTo(1) + assertThat(details).hasSize(2) + assertThat(details?.get(0)?.lineNumber).isEqualTo(1) + assertThat(details?.get(1)?.lineNumber).isEqualTo(2) + } + } + } + + @Test + fun testCompoundJoin1() { + // this is a nonsensical join, but it does test the "and" capability + val selectStatement = select( + orderMaster.orderId, orderMaster.orderDate, orderDetail.lineNumber, + orderDetail.description, orderDetail.quantity + ) { + from(orderMaster, "om") + join(orderDetail, "od") { + on { + orderMaster.orderId isEqualTo orderDetail.orderId + and { orderMaster.orderId isEqualTo orderDetail.orderId } + } + } + } + + val expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" + + " from OrderMaster om join OrderDetail od on om.order_id = od.order_id and om.order_id = od.order_id" + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + } + + @Test + fun testCompoundJoin2() { + // this is a nonsensical join, but it does test the "and" capability + val selectStatement = select( + orderMaster.orderId, orderMaster.orderDate, orderDetail.lineNumber, + orderDetail.description, orderDetail.quantity + ) { + from(orderMaster, "om") + join(orderDetail, "od") { + on { + orderMaster.orderId isEqualTo orderDetail.orderId + and { orderMaster.orderId isEqualTo orderDetail.orderId } + } + } + where { orderMaster.orderId isEqualTo 1 } + } + + val expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" + + " from OrderMaster om join OrderDetail od on om.order_id = od.order_id and om.order_id = od.order_id" + + " where om.order_id = #{parameters.p1,jdbcType=INTEGER}" + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + } + + @Test + fun testMultipleTableJoinWithWhereClause() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(JoinMapper::class.java) + + val selectStatement = select( + orderMaster.orderId, orderMaster.orderDate, orderLine.lineNumber, + itemMaster.description, orderLine.quantity + ) { + from(orderMaster, "om") + join(orderLine, "ol") { + on { orderMaster.orderId isEqualTo orderLine.orderId } + } + join(itemMaster, "im") { + on { orderLine.itemId isEqualTo itemMaster.itemId } + } + where { orderMaster.orderId isEqualTo 2 } + } + + val expectedStatement = "select om.order_id, om.order_date, ol.line_number, im.description, ol.quantity" + + " from OrderMaster om join OrderLine ol" + + " on om.order_id = ol.order_id join ItemMaster im on ol.item_id = im.item_id" + + " where om.order_id = #{parameters.p1,jdbcType=INTEGER}" + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + + val rows = mapper.selectMany(selectStatement) + + assertThat(rows).hasSize(1) + with(rows[0]) { + assertThat(id).isEqualTo(2) + assertThat(details).hasSize(2) + assertThat(details?.get(0)?.lineNumber).isEqualTo(1) + assertThat(details?.get(1)?.lineNumber).isEqualTo(2) + } + } + } + + @Test + fun testFullJoinWithAliases() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(JoinMapper::class.java) + + val selectStatement = select( + orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description + ) { + from(orderMaster, "om") + join(orderLine, "ol") { + on { orderMaster.orderId isEqualTo orderLine.orderId } + } + fullJoin(itemMaster, "im") { + on { orderLine.itemId isEqualTo itemMaster.itemId } + } + orderBy(orderLine.orderId, itemMaster.itemId) + } + + val expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" + + " full join ItemMaster im on ol.item_id = im.item_id" + + " order by order_id, item_id" + + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + + data class OrderDetail(val itemId: Int?, val orderId: Int?, val quantity: Int?, val description: String?) + + val rows = mapper.selectMany(selectStatement) { + OrderDetail( + it["ITEM_ID"] as Int?, + it["ORDER_ID"] as Int?, + it["QUANTITY"] as Int?, + it["DESCRIPTION"] as String? + ) + } + + assertThat(rows).hasSize(6) + + with(rows[0]) { + assertThat(itemId).isEqualTo(55) + assertThat(orderId).isNull() + assertThat(quantity).isNull() + assertThat(description).isEqualTo("Catcher Glove") + } + + with(rows[3]) { + assertThat(itemId).isNull() + assertThat(orderId).isEqualTo(2) + assertThat(quantity).isEqualTo(6) + assertThat(description).isNull() + } + + with(rows[5]) { + assertThat(itemId).isEqualTo(44) + assertThat(orderId).isEqualTo(2) + assertThat(quantity).isEqualTo(1) + assertThat(description).isEqualTo("Outfield Glove") + } + } + } + + @Test + @Suppress("LongMethod") + fun testFullJoinWithSubQuery() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(JoinMapper::class.java) + + val selectStatement = select( + "ol"(orderLine.orderId), orderLine.quantity, "im"(itemMaster.itemId), + itemMaster.description + ) { + from { + select(orderMaster.allColumns()) { + from(orderMaster) + } + + "om" + } + join( + subQuery = { + select(orderLine.allColumns()) { + from(orderLine) + } + + "ol" + }, + joinCriteria = { + on { "om"(orderMaster.orderId) isEqualTo "ol"(orderLine.orderId) } + } + ) + fullJoin( + { + select(itemMaster.allColumns()) { + from(itemMaster) + } + + "im" + } + ) { + on { "ol"(orderLine.itemId) isEqualTo "im"(itemMaster.itemId) } + } + orderBy(orderLine.orderId, itemMaster.itemId) + } + + val expectedStatement = "select ol.order_id, quantity, im.item_id, description" + + " from (select * from OrderMaster) om" + + " join (select * from OrderLine) ol on om.order_id = ol.order_id" + + " full join (select * from ItemMaster) im on ol.item_id = im.item_id" + + " order by order_id, item_id" + + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + + data class OrderDetail(val itemId: Int?, val orderId: Int?, val quantity: Int?, val description: String?) + + val rows = mapper.selectMany(selectStatement) { + OrderDetail( + it["ITEM_ID"] as Int?, + it["ORDER_ID"] as Int?, + it["QUANTITY"] as Int?, + it["DESCRIPTION"] as String? + ) + } + + assertThat(rows).hasSize(6) + + with(rows[0]) { + assertThat(itemId).isEqualTo(55) + assertThat(orderId).isNull() + assertThat(quantity).isNull() + assertThat(description).isEqualTo("Catcher Glove") + } + + with(rows[3]) { + assertThat(itemId).isNull() + assertThat(orderId).isEqualTo(2) + assertThat(quantity).isEqualTo(6) + assertThat(description).isNull() + } + + with(rows[5]) { + assertThat(itemId).isEqualTo(44) + assertThat(orderId).isEqualTo(2) + assertThat(quantity).isEqualTo(1) + assertThat(description).isEqualTo("Outfield Glove") + } + } + } + + @Test + fun testFullJoinWithoutAliases() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(JoinMapper::class.java) + + val selectStatement = select( + orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description + ) { + from(orderMaster, "om") + join(orderLine, "ol") { + on { orderMaster.orderId isEqualTo orderLine.orderId } + } + fullJoin(itemMaster) { + on { orderLine.itemId isEqualTo itemMaster.itemId } + } + orderBy(orderLine.orderId, itemMaster.itemId) + } + + val expectedStatement = "select ol.order_id, ol.quantity, ItemMaster.item_id, ItemMaster.description" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" + + " full join ItemMaster on ol.item_id = ItemMaster.item_id" + + " order by order_id, item_id" + + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + + val rows = mapper.selectManyMappedRows(selectStatement) + + assertThat(rows).hasSize(6) + + assertThat(rows[0]).containsExactly( + entry("DESCRIPTION", "Catcher Glove"), + entry("ITEM_ID", 55) + ) + + assertThat(rows[3]).containsExactly( + entry("ORDER_ID", 2), + entry("QUANTITY", 6) + ) + + assertThat(rows[5]).containsExactly( + entry("ORDER_ID", 2), + entry("QUANTITY", 1), + entry("DESCRIPTION", "Outfield Glove"), + entry("ITEM_ID", 44) + ) + } + } + + @Test + fun testLeftJoinWithAliases() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(JoinMapper::class.java) + + val selectStatement = select( + orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description + ) { + from(orderMaster, "om") + join(orderLine, "ol") { + on { orderMaster.orderId isEqualTo orderLine.orderId } + } + leftJoin(itemMaster, "im") { + on { orderLine.itemId isEqualTo itemMaster.itemId } + } + orderBy(orderLine.orderId, itemMaster.itemId) + } + + val expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" + + " left join ItemMaster im on ol.item_id = im.item_id" + + " order by order_id, item_id" + + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + + val rows = mapper.selectManyMappedRows(selectStatement) + + assertThat(rows).hasSize(5) + + assertThat(rows[2]).containsExactly( + entry("ORDER_ID", 2), + entry("QUANTITY", 6) + ) + + assertThat(rows[4]).containsExactly( + entry("ORDER_ID", 2), + entry("QUANTITY", 1), + entry("DESCRIPTION", "Outfield Glove"), + entry("ITEM_ID", 44) + ) + } + } + + @Test + fun testLeftJoinWithSubQuery() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(JoinMapper::class.java) + + val selectStatement = select( + orderLine.orderId, orderLine.quantity, "im"(itemMaster.itemId), + itemMaster.description + ) { + from(orderMaster, "om") + join(orderLine, "ol") { + on { orderMaster.orderId isEqualTo orderLine.orderId } + } + leftJoin( + { + select(itemMaster.allColumns()) { + from(itemMaster) + } + + "im" + } + ) { + on { orderLine.itemId isEqualTo "im"(itemMaster.itemId) } + } + orderBy(orderLine.orderId, itemMaster.itemId) + } + + val expectedStatement = "select ol.order_id, ol.quantity, im.item_id, description" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" + + " left join (select * from ItemMaster) im on ol.item_id = im.item_id" + + " order by order_id, item_id" + + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + + val rows = mapper.selectManyMappedRows(selectStatement) + + assertThat(rows).hasSize(5) + + assertThat(rows[2]).containsExactly( + entry("ORDER_ID", 2), + entry("QUANTITY", 6) + ) + + assertThat(rows[4]).containsExactly( + entry("ORDER_ID", 2), + entry("QUANTITY", 1), + entry("DESCRIPTION", "Outfield Glove"), + entry("ITEM_ID", 44) + ) + } + } + + @Test + fun testLeftJoinWithoutAliases() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(JoinMapper::class.java) + + val selectStatement = select( + orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description + ) { + from(orderMaster, "om") + join(orderLine, "ol") { + on { orderMaster.orderId isEqualTo orderLine.orderId } + } + leftJoin(itemMaster) { + on { orderLine.itemId isEqualTo itemMaster.itemId } + } + orderBy(orderLine.orderId, itemMaster.itemId) + } + + val expectedStatement = "select ol.order_id, ol.quantity, ItemMaster.item_id, ItemMaster.description" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" + + " left join ItemMaster on ol.item_id = ItemMaster.item_id" + + " order by order_id, item_id" + + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + + val rows = mapper.selectManyMappedRows(selectStatement) + + assertThat(rows).hasSize(5) + + assertThat(rows[2]).containsExactly( + entry("ORDER_ID", 2), + entry("QUANTITY", 6) + ) + + assertThat(rows[4]).containsExactly( + entry("ORDER_ID", 2), + entry("QUANTITY", 1), + entry("DESCRIPTION", "Outfield Glove"), + entry("ITEM_ID", 44) + ) + } + } + + @Test + fun testRightJoinWithAliases() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(JoinMapper::class.java) + + val selectStatement = select( + orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description + ) { + from(orderMaster, "om") + join(orderLine, "ol") { + on { orderMaster.orderId isEqualTo orderLine.orderId } + } + rightJoin(itemMaster, "im") { + on { orderLine.itemId isEqualTo itemMaster.itemId } + } + orderBy(orderLine.orderId, itemMaster.itemId) + } + + val expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" + + " right join ItemMaster im on ol.item_id = im.item_id" + + " order by order_id, item_id" + + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + + val rows = mapper.selectManyMappedRows(selectStatement) + + assertThat(rows).hasSize(5) + + assertThat(rows[0]).containsExactly( + entry("DESCRIPTION", "Catcher Glove"), + entry("ITEM_ID", 55) + ) + + assertThat(rows[4]).containsExactly( + entry("ORDER_ID", 2), + entry("QUANTITY", 1), + entry("DESCRIPTION", "Outfield Glove"), + entry("ITEM_ID", 44) + ) + } + } + + @Test + fun testRightJoinWithSubQuery() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(JoinMapper::class.java) + + val selectStatement = select( + orderLine.orderId, orderLine.quantity, + "im"(itemMaster.itemId), itemMaster.description + ) { + from(orderMaster, "om") + join(orderLine, "ol") { + on { orderMaster.orderId isEqualTo orderLine.orderId } + } + rightJoin( + { + select(itemMaster.allColumns()) { + from(itemMaster) + } + + "im" + } + ) { + on { orderLine.itemId isEqualTo "im"(itemMaster.itemId) } + } + orderBy(orderLine.orderId, itemMaster.itemId) + } + + val expectedStatement = "select ol.order_id, ol.quantity, im.item_id, description" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" + + " right join (select * from ItemMaster) im on ol.item_id = im.item_id" + + " order by order_id, item_id" + + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + + val rows = mapper.selectManyMappedRows(selectStatement) + + assertThat(rows).hasSize(5) + + assertThat(rows[0]).containsExactly( + entry("DESCRIPTION", "Catcher Glove"), + entry("ITEM_ID", 55) + ) + + assertThat(rows[4]).containsExactly( + entry("ORDER_ID", 2), + entry("QUANTITY", 1), + entry("DESCRIPTION", "Outfield Glove"), + entry("ITEM_ID", 44) + ) + } + } + + @Test + fun testRightJoinWithoutAliases() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(JoinMapper::class.java) + + val selectStatement = select( + orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description + ) { + from(orderMaster, "om") + join(orderLine, "ol") { + on { orderMaster.orderId isEqualTo orderLine.orderId } + } + rightJoin(itemMaster) { + on { orderLine.itemId isEqualTo itemMaster.itemId } + } + orderBy(orderLine.orderId, itemMaster.itemId) + } + + val expectedStatement = "select ol.order_id, ol.quantity, ItemMaster.item_id, ItemMaster.description" + + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" + + " right join ItemMaster on ol.item_id = ItemMaster.item_id" + + " order by order_id, item_id" + + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + + val rows = mapper.selectManyMappedRows(selectStatement) + + assertThat(rows).hasSize(5) + + assertThat(rows[0]).containsExactly( + entry("DESCRIPTION", "Catcher Glove"), + entry("ITEM_ID", 55) + ) + + assertThat(rows[4]).containsExactly( + entry("ORDER_ID", 2), + entry("QUANTITY", 1), + entry("DESCRIPTION", "Outfield Glove"), + entry("ITEM_ID", 44) + ) + } + } + + @Test + fun testSelf() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(JoinMapper::class.java) + + // create second table instance for self-join + val user2 = UserDynamicSQLSupport.User() + + // get Bamm Bamm's parent - should be Barney + val selectStatement = select(user.userId, user.userName, user.parentId) { + from(user, "u1") + join(user2, "u2") { + on { user.userId isEqualTo user2.parentId } + } + where { user2.userId isEqualTo 4 } + } + + val expectedStatement = "select u1.user_id, u1.user_name, u1.parent_id" + + " from User u1 join User u2 on u1.user_id = u2.parent_id" + + " where u2.user_id = #{parameters.p1,jdbcType=INTEGER}" + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + val rows = mapper.selectManyMappedRows(selectStatement) + + assertThat(rows).hasSize(1) + assertThat(rows[0]).containsExactly( + entry("USER_ID", 2), + entry("USER_NAME", "Barney"), + ) + } + } + + @Test + fun testSelfWithNewAlias() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(JoinMapper::class.java) + + // create second table instance for self-join + val user2 = user.withAlias("u2") + + // get Bamm Bamm's parent - should be Barney + val selectStatement = select(user.userId, user.userName, user.parentId) { + from(user) + join(user2) { + on { user.userId isEqualTo user2.parentId } + } + where { user2.userId isEqualTo 4 } + } + + val expectedStatement = "select User.user_id, User.user_name, User.parent_id" + + " from User join User u2 on User.user_id = u2.parent_id" + + " where u2.user_id = #{parameters.p1,jdbcType=INTEGER}" + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + + val rows = mapper.selectManyMappedRows(selectStatement) + assertThat(rows).hasSize(1) + + assertThat(rows[0]).containsExactly( + entry("USER_ID", 2), + entry("USER_NAME", "Barney"), + ) + } + } + + @Test + fun testSelfWithNewAliasAndOverride() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(JoinMapper::class.java) + + // create second table instance for self-join + val user2 = user.withAlias("other_user") + + // get Bamm Bamm's parent - should be Barney + val selectStatement = select(user.userId, user.userName, user.parentId) { + from(user, "u1") + join(user2, "u2") { + on { user.userId isEqualTo user2.parentId } + } + where { user2.userId isEqualTo 4 } + } + + val expectedStatement = "select u1.user_id, u1.user_name, u1.parent_id" + + " from User u1 join User u2 on u1.user_id = u2.parent_id" + + " where u2.user_id = #{parameters.p1,jdbcType=INTEGER}" + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + val rows = mapper.selectManyMappedRows(selectStatement) + assertThat(rows).hasSize(1) + + assertThat(rows[0]).containsExactly( + entry("USER_ID", 2), + entry("USER_NAME", "Barney"), + ) + } + } + + @Test + fun testJoinWithNoOnCondition() { + // create second table instance for self-join + val user2 = user.withAlias("other_user") + + assertThatExceptionOfType(KInvalidSQLException::class.java).isThrownBy { + select(user.userId, user.userName, user.parentId) { + from(user, "u1") + join(user2, "u2") { } + where { user2.userId isEqualTo 4 } + } + }.withMessage(Messages.getString("ERROR.22")) //$NON-NLS-1$ + } +} From d623287d61d214e5350efa0dd745080e84660298 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 11:50:46 +0000 Subject: [PATCH 063/260] Update dependency org.springframework:spring-jdbc to v6.1.12 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9495ec37d..3e5d312db 100644 --- a/pom.xml +++ b/pom.xml @@ -94,7 +94,7 @@ <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> - <version>6.1.11</version> + <version>6.1.12</version> <scope>provided</scope> <optional>true</optional> </dependency> From 86859a2fa5974c2790cb54e56b4eaf422d43eac3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 14 Aug 2024 11:50:50 +0000 Subject: [PATCH 064/260] Update junit5 monorepo to v5.11.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9495ec37d..41c591522 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ <properties> <java.version>17</java.version> <java.release.version>17</java.release.version> - <junit.jupiter.version>5.10.3</junit.jupiter.version> + <junit.jupiter.version>5.11.0</junit.jupiter.version> <spring.batch.version>5.1.2</spring.batch.version> <checkstyle.config>checkstyle-override.xml</checkstyle.config> From f1c736229b5c972012ac476d89b46067caf653f3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 15 Aug 2024 17:35:50 +0000 Subject: [PATCH 065/260] Update dependency ch.qos.logback:logback-classic to v1.5.7 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b1a34f202..1cef97f04 100644 --- a/pom.xml +++ b/pom.xml @@ -163,7 +163,7 @@ <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> - <version>1.5.6</version> + <version>1.5.7</version> <scope>test</scope> </dependency> <dependency> From 22bc77f5b1f54a1e16268d116181e3bc6d8ad831 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 16 Aug 2024 15:22:48 -0400 Subject: [PATCH 066/260] Add "WhenPresent" versions of the paging methods --- .../mybatis/dynamic/sql/delete/DeleteDSL.java | 10 +- .../dynamic/sql/select/MultiSelectDSL.java | 25 +++- .../sql/select/QueryExpressionDSL.java | 90 ++++++++++-- .../mybatis/dynamic/sql/select/SelectDSL.java | 25 +++- .../mybatis/dynamic/sql/update/UpdateDSL.java | 10 +- .../sql/util/kotlin/KotlinDeleteBuilder.kt | 6 +- .../util/kotlin/KotlinMultiSelectBuilder.kt | 20 ++- .../sql/util/kotlin/KotlinSelectBuilder.kt | 18 ++- .../sql/util/kotlin/KotlinUpdateBuilder.kt | 6 +- .../examples/animal/data/AnimalDataTest.java | 18 +++ .../VariousPagingAndLimitScenariosTest.java | 132 ++++++++++++++++++ 11 files changed, 328 insertions(+), 32 deletions(-) create mode 100644 src/test/java/examples/animal/data/VariousPagingAndLimitScenariosTest.java diff --git a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java index e7c1ad184..825eaa699 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java @@ -56,6 +56,10 @@ public DeleteWhereBuilder where() { } public DeleteDSL<R> limit(long limit) { + return limitWhenPresent(limit); + } + + public DeleteDSL<R> limitWhenPresent(Long limit) { this.limit = limit; return this; } @@ -115,7 +119,11 @@ private DeleteWhereBuilder() { } public DeleteDSL<R> limit(long limit) { - return DeleteDSL.this.limit(limit); + return limitWhenPresent(limit); + } + + public DeleteDSL<R> limitWhenPresent(Long limit) { + return DeleteDSL.this.limitWhenPresent(limit); } public DeleteDSL<R> orderBy(SortSpecification... columns) { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java index ad0f2aba3..d23c6deb9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java @@ -62,16 +62,28 @@ public MultiSelectDSL orderBy(Collection<? extends SortSpecification> columns) { } public LimitFinisher limit(long limit) { + return limitWhenPresent(limit); + } + + public LimitFinisher limitWhenPresent(Long limit) { this.limit = limit; return new LimitFinisher(); } public OffsetFirstFinisher offset(long offset) { + return offsetWhenPresent(offset); + } + + public OffsetFirstFinisher offsetWhenPresent(Long offset) { this.offset = offset; return new OffsetFirstFinisher(); } public FetchFirstFinisher fetchFirst(long fetchFirstRows) { + return fetchFirstWhenPresent(fetchFirstRows); + } + + public FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { this.fetchFirstRows = fetchFirstRows; return new FetchFirstFinisher(); } @@ -104,7 +116,11 @@ public MultiSelectDSL configureStatement(Consumer<StatementConfiguration> consum public class LimitFinisher implements Buildable<MultiSelectModel> { public OffsetFinisher offset(long offset) { - MultiSelectDSL.this.offset(offset); + return offsetWhenPresent(offset); + } + + public OffsetFinisher offsetWhenPresent(Long offset) { + MultiSelectDSL.this.offsetWhenPresent(offset); return new OffsetFinisher(); } @@ -125,8 +141,11 @@ public MultiSelectModel build() { public class OffsetFirstFinisher implements Buildable<MultiSelectModel> { public FetchFirstFinisher fetchFirst(long fetchFirstRows) { - MultiSelectDSL.this.fetchFirst(fetchFirstRows); - return new FetchFirstFinisher(); + return fetchFirstWhenPresent(fetchFirstRows); + } + + public FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { + return MultiSelectDSL.this.fetchFirstWhenPresent(fetchFirstRows); } @NotNull diff --git a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java index 593252979..0fab5ad4c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java @@ -195,15 +195,27 @@ protected QueryExpressionModel buildModel() { } public SelectDSL<R>.LimitFinisher limit(long limit) { - return selectDSL.limit(limit); + return limitWhenPresent(limit); + } + + public SelectDSL<R>.LimitFinisher limitWhenPresent(Long limit) { + return selectDSL.limitWhenPresent(limit); } public SelectDSL<R>.OffsetFirstFinisher offset(long offset) { - return selectDSL.offset(offset); + return offsetWhenPresent(offset); + } + + public SelectDSL<R>.OffsetFirstFinisher offsetWhenPresent(Long offset) { + return selectDSL.offsetWhenPresent(offset); } public SelectDSL<R>.FetchFirstFinisher fetchFirst(long fetchFirstRows) { - return selectDSL.fetchFirst(fetchFirstRows); + return fetchFirstWhenPresent(fetchFirstRows); + } + + public SelectDSL<R>.FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { + return selectDSL.fetchFirstWhenPresent(fetchFirstRows); } @Override @@ -303,15 +315,27 @@ public GroupByFinisher groupBy(Collection<? extends BasicColumn> columns) { } public SelectDSL<R>.LimitFinisher limit(long limit) { - return QueryExpressionDSL.this.limit(limit); + return limitWhenPresent(limit); + } + + public SelectDSL<R>.LimitFinisher limitWhenPresent(Long limit) { + return QueryExpressionDSL.this.limitWhenPresent(limit); } public SelectDSL<R>.OffsetFirstFinisher offset(long offset) { - return QueryExpressionDSL.this.offset(offset); + return offsetWhenPresent(offset); + } + + public SelectDSL<R>.OffsetFirstFinisher offsetWhenPresent(Long offset) { + return QueryExpressionDSL.this.offsetWhenPresent(offset); } public SelectDSL<R>.FetchFirstFinisher fetchFirst(long fetchFirstRows) { - return QueryExpressionDSL.this.fetchFirst(fetchFirstRows); + return fetchFirstWhenPresent(fetchFirstRows); + } + + public SelectDSL<R>.FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { + return QueryExpressionDSL.this.fetchFirstWhenPresent(fetchFirstRows); } @NotNull @@ -485,15 +509,27 @@ public SelectDSL<R> orderBy(Collection<? extends SortSpecification> columns) { } public SelectDSL<R>.LimitFinisher limit(long limit) { - return QueryExpressionDSL.this.limit(limit); + return limitWhenPresent(limit); + } + + public SelectDSL<R>.LimitFinisher limitWhenPresent(Long limit) { + return QueryExpressionDSL.this.limitWhenPresent(limit); } public SelectDSL<R>.OffsetFirstFinisher offset(long offset) { - return QueryExpressionDSL.this.offset(offset); + return offsetWhenPresent(offset); + } + + public SelectDSL<R>.OffsetFirstFinisher offsetWhenPresent(Long offset) { + return QueryExpressionDSL.this.offsetWhenPresent(offset); } public SelectDSL<R>.FetchFirstFinisher fetchFirst(long fetchFirstRows) { - return QueryExpressionDSL.this.fetchFirst(fetchFirstRows); + return fetchFirstWhenPresent(fetchFirstRows); + } + + public SelectDSL<R>.FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { + return QueryExpressionDSL.this.fetchFirstWhenPresent(fetchFirstRows); } } @@ -521,15 +557,27 @@ public UnionBuilder unionAll() { } public SelectDSL<R>.LimitFinisher limit(long limit) { - return QueryExpressionDSL.this.limit(limit); + return limitWhenPresent(limit); + } + + public SelectDSL<R>.LimitFinisher limitWhenPresent(Long limit) { + return QueryExpressionDSL.this.limitWhenPresent(limit); } public SelectDSL<R>.OffsetFirstFinisher offset(long offset) { - return QueryExpressionDSL.this.offset(offset); + return offsetWhenPresent(offset); + } + + public SelectDSL<R>.OffsetFirstFinisher offsetWhenPresent(Long offset) { + return QueryExpressionDSL.this.offsetWhenPresent(offset); } public SelectDSL<R>.FetchFirstFinisher fetchFirst(long fetchFirstRows) { - return QueryExpressionDSL.this.fetchFirst(fetchFirstRows); + return fetchFirstWhenPresent(fetchFirstRows); + } + + public SelectDSL<R>.FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { + return QueryExpressionDSL.this.fetchFirstWhenPresent(fetchFirstRows); } @Override @@ -575,15 +623,27 @@ public class QueryExpressionHavingBuilder extends AbstractHavingFinisher<QueryEx implements Buildable<R> { public SelectDSL<R>.FetchFirstFinisher fetchFirst(long fetchFirstRows) { - return QueryExpressionDSL.this.fetchFirst(fetchFirstRows); + return fetchFirstWhenPresent(fetchFirstRows); + } + + public SelectDSL<R>.FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { + return QueryExpressionDSL.this.fetchFirstWhenPresent(fetchFirstRows); } public SelectDSL<R>.OffsetFirstFinisher offset(long offset) { - return QueryExpressionDSL.this.offset(offset); + return offsetWhenPresent(offset); + } + + public SelectDSL<R>.OffsetFirstFinisher offsetWhenPresent(Long offset) { + return QueryExpressionDSL.this.offsetWhenPresent(offset); } public SelectDSL<R>.LimitFinisher limit(long limit) { - return QueryExpressionDSL.this.limit(limit); + return limitWhenPresent(limit); + } + + public SelectDSL<R>.LimitFinisher limitWhenPresent(Long limit) { + return QueryExpressionDSL.this.limitWhenPresent(limit); } public SelectDSL<R> orderBy(SortSpecification... columns) { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java index cb1fae92d..2c9aaea36 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java @@ -108,16 +108,28 @@ void orderBy(Collection<? extends SortSpecification> columns) { } public LimitFinisher limit(long limit) { + return limitWhenPresent(limit); + } + + public LimitFinisher limitWhenPresent(Long limit) { this.limit = limit; return new LimitFinisher(); } public OffsetFirstFinisher offset(long offset) { + return offsetWhenPresent(offset); + } + + public OffsetFirstFinisher offsetWhenPresent(Long offset) { this.offset = offset; return new OffsetFirstFinisher(); } public FetchFirstFinisher fetchFirst(long fetchFirstRows) { + return fetchFirstWhenPresent(fetchFirstRows); + } + + public FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { this.fetchFirstRows = fetchFirstRows; return new FetchFirstFinisher(); } @@ -155,7 +167,11 @@ private Optional<PagingModel> buildPagingModel() { public class LimitFinisher implements Buildable<R> { public OffsetFinisher offset(long offset) { - SelectDSL.this.offset(offset); + return offsetWhenPresent(offset); + } + + public OffsetFinisher offsetWhenPresent(Long offset) { + SelectDSL.this.offsetWhenPresent(offset); return new OffsetFinisher(); } @@ -176,8 +192,11 @@ public R build() { public class OffsetFirstFinisher implements Buildable<R> { public FetchFirstFinisher fetchFirst(long fetchFirstRows) { - SelectDSL.this.fetchFirst(fetchFirstRows); - return new FetchFirstFinisher(); + return fetchFirstWhenPresent(fetchFirstRows); + } + + public FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { + return SelectDSL.this.fetchFirstWhenPresent(fetchFirstRows); } @NotNull diff --git a/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java index 8cf7259a3..15f021b16 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java @@ -76,6 +76,10 @@ public UpdateWhereBuilder where() { } public UpdateDSL<R> limit(long limit) { + return limitWhenPresent(limit); + } + + public UpdateDSL<R> limitWhenPresent(Long limit) { this.limit = limit; return this; } @@ -196,7 +200,11 @@ private UpdateWhereBuilder() { } public UpdateDSL<R> limit(long limit) { - return UpdateDSL.this.limit(limit); + return limitWhenPresent(limit); + } + + public UpdateDSL<R> limitWhenPresent(Long limit) { + return UpdateDSL.this.limitWhenPresent(limit); } public UpdateDSL<R> orderBy(SortSpecification... columns) { diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt index 011928b9e..3146d5e11 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt @@ -30,7 +30,11 @@ class KotlinDeleteBuilder(private val dsl: DeleteDSL<DeleteModel>) : } fun limit(limit: Long) { - dsl.limit(limit) + limitWhenPresent(limit) + } + + fun limitWhenPresent(limit: Long?) { + dsl.limitWhenPresent(limit) } override fun build(): DeleteModel = dsl.build() diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiSelectBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiSelectBuilder.kt index 440232397..3c3ab1f71 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiSelectBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiSelectBuilder.kt @@ -28,7 +28,7 @@ typealias MultiSelectCompleter = KotlinMultiSelectBuilder.() -> Unit @MyBatisDslMarker class KotlinMultiSelectBuilder: Buildable<MultiSelectModel> { private var dsl: MultiSelectDSL? = null - private set(value) { + set(value) { assertNull(field, "ERROR.33") //$NON-NLS-1$ field = value } @@ -64,15 +64,27 @@ class KotlinMultiSelectBuilder: Buildable<MultiSelectModel> { } fun limit(limit: Long) { - getDsl().limit(limit) + limitWhenPresent(limit) + } + + fun limitWhenPresent(limit: Long?) { + getDsl().limitWhenPresent(limit) } fun offset(offset: Long) { - getDsl().offset(offset) + offsetWhenPresent(offset) + } + + fun offsetWhenPresent(offset: Long?) { + getDsl().offsetWhenPresent(offset) } fun fetchFirst(fetchFirstRows: Long) { - getDsl().fetchFirst(fetchFirstRows).rowsOnly() + fetchFirstWhenPresent(fetchFirstRows) + } + + fun fetchFirstWhenPresent(fetchFirstRows: Long?) { + getDsl().fetchFirstWhenPresent(fetchFirstRows).rowsOnly() } fun configureStatement(c: StatementConfiguration.() -> Unit) { diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSelectBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSelectBuilder.kt index e62b5ef26..4bd8cdefa 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSelectBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSelectBuilder.kt @@ -59,15 +59,27 @@ class KotlinSelectBuilder(private val fromGatherer: QueryExpressionDSL.FromGathe } fun limit(limit: Long) { - getDsl().limit(limit) + limitWhenPresent(limit) + } + + fun limitWhenPresent(limit: Long?) { + getDsl().limitWhenPresent(limit) } fun offset(offset: Long) { - getDsl().offset(offset) + offsetWhenPresent(offset) + } + + fun offsetWhenPresent(offset: Long?) { + getDsl().offsetWhenPresent(offset) } fun fetchFirst(fetchFirstRows: Long) { - getDsl().fetchFirst(fetchFirstRows).rowsOnly() + fetchFirstWhenPresent(fetchFirstRows) + } + + fun fetchFirstWhenPresent(fetchFirstRows: Long?) { + getDsl().fetchFirstWhenPresent(fetchFirstRows).rowsOnly() } fun union(union: KotlinUnionBuilder.() -> Unit): Unit = diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt index ef7eb6804..93dbfaa8a 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt @@ -34,7 +34,11 @@ class KotlinUpdateBuilder(private val dsl: UpdateDSL<UpdateModel>) : } fun limit(limit: Long) { - dsl.limit(limit) + limitWhenPresent(limit) + } + + fun limitWhenPresent(limit: Long?) { + dsl.limitWhenPresent(limit) } override fun build(): UpdateModel = dsl.build() diff --git a/src/test/java/examples/animal/data/AnimalDataTest.java b/src/test/java/examples/animal/data/AnimalDataTest.java index d751decab..12a21e3f6 100644 --- a/src/test/java/examples/animal/data/AnimalDataTest.java +++ b/src/test/java/examples/animal/data/AnimalDataTest.java @@ -108,6 +108,24 @@ void testSelectAllRows() { } } + @Test + void testSelectAllRowsWithNullLimit() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); + SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) + .from(animalData) + .limitWhenPresent(null) + .build() + .render(RenderingStrategies.MYBATIS3); + List<AnimalData> animals = mapper.selectMany(selectStatement); + + assertAll( + () -> assertThat(animals).hasSize(65), + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + ); + } + } + @Test void testSelectAllRowsWithRowBounds() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { diff --git a/src/test/java/examples/animal/data/VariousPagingAndLimitScenariosTest.java b/src/test/java/examples/animal/data/VariousPagingAndLimitScenariosTest.java new file mode 100644 index 000000000..1fde45c49 --- /dev/null +++ b/src/test/java/examples/animal/data/VariousPagingAndLimitScenariosTest.java @@ -0,0 +1,132 @@ +/* + * Copyright 2016-2024 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 + * + * https://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.animal.data; + +import static examples.animal.data.AnimalDataDynamicSqlSupport.animalData; +import static examples.animal.data.AnimalDataDynamicSqlSupport.id; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mybatis.dynamic.sql.SqlBuilder.deleteFrom; +import static org.mybatis.dynamic.sql.SqlBuilder.isLessThan; +import static org.mybatis.dynamic.sql.SqlBuilder.select; +import static org.mybatis.dynamic.sql.SqlBuilder.update; + +import org.junit.jupiter.api.Test; +import org.mybatis.dynamic.sql.render.RenderingStrategies; + +class VariousPagingAndLimitScenariosTest { + + @Test + void testOptionalLimitOnDelete() { + var deleteStatement = deleteFrom(animalData) + .limitWhenPresent(null) + .build() + .render(RenderingStrategies.SPRING_NAMED_PARAMETER); + + assertThat(deleteStatement.getDeleteStatement()).isEqualTo("delete from AnimalData"); + } + + @Test + void testOptionalLimitOnDeleteWithWhere() { + var deleteStatement = deleteFrom(animalData) + .where(id, isLessThan(22)) + .limitWhenPresent(null) + .build() + .render(RenderingStrategies.SPRING_NAMED_PARAMETER); + + assertThat(deleteStatement.getDeleteStatement()) + .isEqualTo("delete from AnimalData where id < :p1"); + } + + @Test + void testOptionalLimitOnUpdate() { + var updateStatement = update(animalData) + .set(id).equalTo(1) + .limitWhenPresent(null) + .build() + .render(RenderingStrategies.SPRING_NAMED_PARAMETER); + + assertThat(updateStatement.getUpdateStatement()).isEqualTo("update AnimalData set id = :p1"); + } + + @Test + void testOptionalLimitOnUpdateWithWhere() { + var updateStatement = update(animalData) + .set(id).equalTo(1) + .where(id, isLessThan(22)) + .limitWhenPresent(null) + .build() + .render(RenderingStrategies.SPRING_NAMED_PARAMETER); + + assertThat(updateStatement.getUpdateStatement()).isEqualTo("update AnimalData set id = :p1 where id < :p2"); + } + + @Test + void testOptionalLimitOnSelect() { + var selectStatement = select(animalData.allColumns()) + .from(animalData) + .limitWhenPresent(null) + .build() + .render(RenderingStrategies.SPRING_NAMED_PARAMETER); + + assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData"); + } + + @Test + void testOptionalOffsetOnSelect() { + var selectStatement = select(animalData.allColumns()) + .from(animalData) + .offsetWhenPresent(null) + .build() + .render(RenderingStrategies.SPRING_NAMED_PARAMETER); + + assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData"); + } + + @Test + void testOptionalFetchFirstOnSelect() { + var selectStatement = select(animalData.allColumns()) + .from(animalData) + .fetchFirstWhenPresent(null).rowsOnly() + .build() + .render(RenderingStrategies.SPRING_NAMED_PARAMETER); + + assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData"); + } + + @Test + void testOptionalLimitAndOffsetOnSelect() { + var selectStatement = select(animalData.allColumns()) + .from(animalData) + .limitWhenPresent(null) + .offsetWhenPresent(null) + .build() + .render(RenderingStrategies.SPRING_NAMED_PARAMETER); + + assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData"); + } + + @Test + void testOptionalOffsetAndFetchOnSelect() { + var selectStatement = select(animalData.allColumns()) + .from(animalData) + .offsetWhenPresent(null) + .fetchFirstWhenPresent(null).rowsOnly() + .build() + .render(RenderingStrategies.SPRING_NAMED_PARAMETER); + + assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData"); + } +} From 5e275f10799e7e3eccd40266e34236f437ab4411 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 16 Aug 2024 17:36:16 -0400 Subject: [PATCH 067/260] Refactor Paging --- .../dynamic/sql/select/MultiSelectDSL.java | 74 +++------- .../mybatis/dynamic/sql/select/PagingDSL.java | 58 ++++++++ .../sql/select/QueryExpressionDSL.java | 120 +++++----------- .../mybatis/dynamic/sql/select/SelectDSL.java | 70 +++------ .../java/issues/gh100/FromGroupByTest.java | 8 +- .../java/issues/gh100/FromJoinWhereTest.java | 136 +++++++++--------- 6 files changed, 210 insertions(+), 256 deletions(-) create mode 100644 src/main/java/org/mybatis/dynamic/sql/select/PagingDSL.java diff --git a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java index d23c6deb9..6b01f3696 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java @@ -29,7 +29,8 @@ import org.mybatis.dynamic.sql.util.Buildable; import org.mybatis.dynamic.sql.util.ConfigurableStatement; -public class MultiSelectDSL implements Buildable<MultiSelectModel>, ConfigurableStatement<MultiSelectDSL> { +public class MultiSelectDSL implements Buildable<MultiSelectModel>, ConfigurableStatement<MultiSelectDSL>, + PagingDSL<MultiSelectModel> { private final List<UnionQuery> unionQueries = new ArrayList<>(); private final SelectModel initialSelect; private OrderByModel orderByModel; @@ -61,31 +62,22 @@ public MultiSelectDSL orderBy(Collection<? extends SortSpecification> columns) { return this; } - public LimitFinisher limit(long limit) { - return limitWhenPresent(limit); - } - - public LimitFinisher limitWhenPresent(Long limit) { + @Override + public LimitFinisher<MultiSelectModel> limitWhenPresent(Long limit) { this.limit = limit; - return new LimitFinisher(); + return new LF(); } - public OffsetFirstFinisher offset(long offset) { - return offsetWhenPresent(offset); - } - - public OffsetFirstFinisher offsetWhenPresent(Long offset) { + @Override + public OffsetFirstFinisher<MultiSelectModel> offsetWhenPresent(Long offset) { this.offset = offset; - return new OffsetFirstFinisher(); + return new OFF(); } - public FetchFirstFinisher fetchFirst(long fetchFirstRows) { - return fetchFirstWhenPresent(fetchFirstRows); - } - - public FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { + @Override + public FetchFirstFinisher<MultiSelectModel> fetchFirstWhenPresent(Long fetchFirstRows) { this.fetchFirstRows = fetchFirstRows; - return new FetchFirstFinisher(); + return new FFF(); } @NotNull @@ -114,38 +106,18 @@ public MultiSelectDSL configureStatement(Consumer<StatementConfiguration> consum return this; } - public class LimitFinisher implements Buildable<MultiSelectModel> { - public OffsetFinisher offset(long offset) { - return offsetWhenPresent(offset); - } - - public OffsetFinisher offsetWhenPresent(Long offset) { - MultiSelectDSL.this.offsetWhenPresent(offset); - return new OffsetFinisher(); - } - - @NotNull + class FFF implements FetchFirstFinisher<MultiSelectModel> { @Override - public MultiSelectModel build() { - return MultiSelectDSL.this.build(); + public Buildable<MultiSelectModel> rowsOnly() { + return MultiSelectDSL.this; } } - public class OffsetFinisher implements Buildable<MultiSelectModel> { - @NotNull + class LF implements LimitFinisher<MultiSelectModel> { @Override - public MultiSelectModel build() { - return MultiSelectDSL.this.build(); - } - } - - public class OffsetFirstFinisher implements Buildable<MultiSelectModel> { - public FetchFirstFinisher fetchFirst(long fetchFirstRows) { - return fetchFirstWhenPresent(fetchFirstRows); - } - - public FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { - return MultiSelectDSL.this.fetchFirstWhenPresent(fetchFirstRows); + public Buildable<MultiSelectModel> offsetWhenPresent(Long offset) { + MultiSelectDSL.this.offset = offset; + return MultiSelectDSL.this; } @NotNull @@ -155,13 +127,13 @@ public MultiSelectModel build() { } } - public class FetchFirstFinisher { - public RowsOnlyFinisher rowsOnly() { - return new RowsOnlyFinisher(); + class OFF implements OffsetFirstFinisher<MultiSelectModel> { + @Override + public FetchFirstFinisher<MultiSelectModel> fetchFirstWhenPresent(Long fetchFirstRows) { + MultiSelectDSL.this.fetchFirstRows = fetchFirstRows; + return new FFF(); } - } - public class RowsOnlyFinisher implements Buildable<MultiSelectModel> { @NotNull @Override public MultiSelectModel build() { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/PagingDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/PagingDSL.java new file mode 100644 index 000000000..89cfafafb --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/select/PagingDSL.java @@ -0,0 +1,58 @@ +/* + * Copyright 2016-2024 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 + * + * https://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.select; + +import org.mybatis.dynamic.sql.util.Buildable; + +public interface PagingDSL<T> { + default LimitFinisher<T> limit(long limit) { + return limitWhenPresent(limit); + } + + LimitFinisher<T> limitWhenPresent(Long limit); + + default OffsetFirstFinisher<T> offset(long offset) { + return offsetWhenPresent(offset); + } + + OffsetFirstFinisher<T> offsetWhenPresent(Long offset); + + default FetchFirstFinisher<T> fetchFirst(long fetchFirstRows) { + return fetchFirstWhenPresent(fetchFirstRows); + } + + FetchFirstFinisher<T> fetchFirstWhenPresent(Long fetchFirstRows); + + interface LimitFinisher<T> extends Buildable<T> { + default Buildable<T> offset(long offset) { + return offsetWhenPresent(offset); + } + + Buildable<T> offsetWhenPresent(Long offset); + } + + interface OffsetFirstFinisher<T> extends Buildable<T> { + default FetchFirstFinisher<T> fetchFirst(long fetchFirstRows) { + return fetchFirstWhenPresent(fetchFirstRows); + } + + FetchFirstFinisher<T> fetchFirstWhenPresent(Long fetchFirstRows); + } + + interface FetchFirstFinisher<T> { + Buildable<T> rowsOnly(); + } +} diff --git a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java index 0fab5ad4c..4e8bb4d76 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java @@ -42,7 +42,7 @@ public class QueryExpressionDSL<R> extends AbstractQueryExpressionDSL<QueryExpressionDSL<R>.QueryExpressionWhereBuilder, QueryExpressionDSL<R>> - implements Buildable<R> { + implements Buildable<R>, PagingDSL<R> { private final String connector; private final SelectDSL<R> selectDSL; @@ -194,27 +194,18 @@ protected QueryExpressionModel buildModel() { .build(); } - public SelectDSL<R>.LimitFinisher limit(long limit) { - return limitWhenPresent(limit); - } - - public SelectDSL<R>.LimitFinisher limitWhenPresent(Long limit) { + @Override + public PagingDSL.LimitFinisher<R> limitWhenPresent(Long limit) { return selectDSL.limitWhenPresent(limit); } - public SelectDSL<R>.OffsetFirstFinisher offset(long offset) { - return offsetWhenPresent(offset); - } - - public SelectDSL<R>.OffsetFirstFinisher offsetWhenPresent(Long offset) { + @Override + public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(Long offset) { return selectDSL.offsetWhenPresent(offset); } - public SelectDSL<R>.FetchFirstFinisher fetchFirst(long fetchFirstRows) { - return fetchFirstWhenPresent(fetchFirstRows); - } - - public SelectDSL<R>.FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { + @Override + public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(Long fetchFirstRows) { return selectDSL.fetchFirstWhenPresent(fetchFirstRows); } @@ -285,7 +276,7 @@ public FromGatherer<R> build() { } public class QueryExpressionWhereBuilder extends AbstractWhereFinisher<QueryExpressionWhereBuilder> - implements Buildable<R> { + implements Buildable<R>, PagingDSL<R> { private QueryExpressionWhereBuilder() { super(QueryExpressionDSL.this); } @@ -314,27 +305,18 @@ public GroupByFinisher groupBy(Collection<? extends BasicColumn> columns) { return QueryExpressionDSL.this.groupBy(columns); } - public SelectDSL<R>.LimitFinisher limit(long limit) { - return limitWhenPresent(limit); - } - - public SelectDSL<R>.LimitFinisher limitWhenPresent(Long limit) { + @Override + public PagingDSL.LimitFinisher<R> limitWhenPresent(Long limit) { return QueryExpressionDSL.this.limitWhenPresent(limit); } - public SelectDSL<R>.OffsetFirstFinisher offset(long offset) { - return offsetWhenPresent(offset); - } - - public SelectDSL<R>.OffsetFirstFinisher offsetWhenPresent(Long offset) { + @Override + public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(Long offset) { return QueryExpressionDSL.this.offsetWhenPresent(offset); } - public SelectDSL<R>.FetchFirstFinisher fetchFirst(long fetchFirstRows) { - return fetchFirstWhenPresent(fetchFirstRows); - } - - public SelectDSL<R>.FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { + @Override + public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(Long fetchFirstRows) { return QueryExpressionDSL.this.fetchFirstWhenPresent(fetchFirstRows); } @@ -375,7 +357,7 @@ public <T> JoinSpecificationFinisher on(BindableColumn<T> joinColumn, JoinCondit public class JoinSpecificationFinisher extends AbstractWhereStarter<QueryExpressionWhereBuilder, JoinSpecificationFinisher> - implements Buildable<R> { + implements Buildable<R>, PagingDSL<R> { private final JoinSpecification.Builder joinSpecificationBuilder; public <T> JoinSpecificationFinisher(TableExpression table, BindableColumn<T> joinColumn, @@ -508,32 +490,24 @@ public SelectDSL<R> orderBy(Collection<? extends SortSpecification> columns) { return QueryExpressionDSL.this.orderBy(columns); } - public SelectDSL<R>.LimitFinisher limit(long limit) { - return limitWhenPresent(limit); - } - - public SelectDSL<R>.LimitFinisher limitWhenPresent(Long limit) { + @Override + public PagingDSL.LimitFinisher<R> limitWhenPresent(Long limit) { return QueryExpressionDSL.this.limitWhenPresent(limit); } - public SelectDSL<R>.OffsetFirstFinisher offset(long offset) { - return offsetWhenPresent(offset); - } - - public SelectDSL<R>.OffsetFirstFinisher offsetWhenPresent(Long offset) { + @Override + public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(Long offset) { return QueryExpressionDSL.this.offsetWhenPresent(offset); } - public SelectDSL<R>.FetchFirstFinisher fetchFirst(long fetchFirstRows) { - return fetchFirstWhenPresent(fetchFirstRows); - } - - public SelectDSL<R>.FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { + @Override + public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(Long fetchFirstRows) { return QueryExpressionDSL.this.fetchFirstWhenPresent(fetchFirstRows); } } - public class GroupByFinisher extends AbstractHavingStarter<QueryExpressionHavingBuilder> implements Buildable<R> { + public class GroupByFinisher extends AbstractHavingStarter<QueryExpressionHavingBuilder> + implements Buildable<R>, PagingDSL<R> { public SelectDSL<R> orderBy(SortSpecification... columns) { return orderBy(Arrays.asList(columns)); } @@ -556,27 +530,18 @@ public UnionBuilder unionAll() { return QueryExpressionDSL.this.unionAll(); } - public SelectDSL<R>.LimitFinisher limit(long limit) { - return limitWhenPresent(limit); - } - - public SelectDSL<R>.LimitFinisher limitWhenPresent(Long limit) { + @Override + public PagingDSL.LimitFinisher<R> limitWhenPresent(Long limit) { return QueryExpressionDSL.this.limitWhenPresent(limit); } - public SelectDSL<R>.OffsetFirstFinisher offset(long offset) { - return offsetWhenPresent(offset); - } - - public SelectDSL<R>.OffsetFirstFinisher offsetWhenPresent(Long offset) { + @Override + public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(Long offset) { return QueryExpressionDSL.this.offsetWhenPresent(offset); } - public SelectDSL<R>.FetchFirstFinisher fetchFirst(long fetchFirstRows) { - return fetchFirstWhenPresent(fetchFirstRows); - } - - public SelectDSL<R>.FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { + @Override + public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(Long fetchFirstRows) { return QueryExpressionDSL.this.fetchFirstWhenPresent(fetchFirstRows); } @@ -620,30 +585,21 @@ public FromGatherer<R> selectDistinct(List<BasicColumn> selectList) { } public class QueryExpressionHavingBuilder extends AbstractHavingFinisher<QueryExpressionHavingBuilder> - implements Buildable<R> { - - public SelectDSL<R>.FetchFirstFinisher fetchFirst(long fetchFirstRows) { - return fetchFirstWhenPresent(fetchFirstRows); - } - - public SelectDSL<R>.FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { - return QueryExpressionDSL.this.fetchFirstWhenPresent(fetchFirstRows); - } + implements Buildable<R>, PagingDSL<R> { - public SelectDSL<R>.OffsetFirstFinisher offset(long offset) { - return offsetWhenPresent(offset); + @Override + public PagingDSL.LimitFinisher<R> limitWhenPresent(Long limit) { + return QueryExpressionDSL.this.limitWhenPresent(limit); } - public SelectDSL<R>.OffsetFirstFinisher offsetWhenPresent(Long offset) { + @Override + public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(Long offset) { return QueryExpressionDSL.this.offsetWhenPresent(offset); } - public SelectDSL<R>.LimitFinisher limit(long limit) { - return limitWhenPresent(limit); - } - - public SelectDSL<R>.LimitFinisher limitWhenPresent(Long limit) { - return QueryExpressionDSL.this.limitWhenPresent(limit); + @Override + public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(Long fetchFirstRows) { + return QueryExpressionDSL.this.fetchFirstWhenPresent(fetchFirstRows); } public SelectDSL<R> orderBy(SortSpecification... columns) { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java index 2c9aaea36..82e55aefb 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java @@ -41,7 +41,7 @@ * @param <R> * the type of model produced by this builder, typically SelectModel */ -public class SelectDSL<R> implements Buildable<R>, ConfigurableStatement<SelectDSL<R>> { +public class SelectDSL<R> implements Buildable<R>, ConfigurableStatement<SelectDSL<R>>, PagingDSL<R> { private final Function<SelectModel, R> adapterFunction; private final List<QueryExpressionDSL<R>> queryExpressions = new ArrayList<>(); @@ -107,31 +107,19 @@ void orderBy(Collection<? extends SortSpecification> columns) { orderByModel = OrderByModel.of(columns); } - public LimitFinisher limit(long limit) { - return limitWhenPresent(limit); - } - - public LimitFinisher limitWhenPresent(Long limit) { + public LimitFinisher<R> limitWhenPresent(Long limit) { this.limit = limit; - return new LimitFinisher(); - } - - public OffsetFirstFinisher offset(long offset) { - return offsetWhenPresent(offset); + return new LF(); } - public OffsetFirstFinisher offsetWhenPresent(Long offset) { + public OffsetFirstFinisher<R> offsetWhenPresent(Long offset) { this.offset = offset; - return new OffsetFirstFinisher(); - } - - public FetchFirstFinisher fetchFirst(long fetchFirstRows) { - return fetchFirstWhenPresent(fetchFirstRows); + return new OFF(); } - public FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { + public FetchFirstFinisher<R> fetchFirstWhenPresent(Long fetchFirstRows) { this.fetchFirstRows = fetchFirstRows; - return new FetchFirstFinisher(); + return new FFF(); } @Override @@ -165,38 +153,18 @@ private Optional<PagingModel> buildPagingModel() { .build(); } - public class LimitFinisher implements Buildable<R> { - public OffsetFinisher offset(long offset) { - return offsetWhenPresent(offset); - } - - public OffsetFinisher offsetWhenPresent(Long offset) { - SelectDSL.this.offsetWhenPresent(offset); - return new OffsetFinisher(); - } - - @NotNull + class FFF implements FetchFirstFinisher<R> { @Override - public R build() { - return SelectDSL.this.build(); + public Buildable<R> rowsOnly() { + return SelectDSL.this; } } - public class OffsetFinisher implements Buildable<R> { - @NotNull + class LF implements LimitFinisher<R> { @Override - public R build() { - return SelectDSL.this.build(); - } - } - - public class OffsetFirstFinisher implements Buildable<R> { - public FetchFirstFinisher fetchFirst(long fetchFirstRows) { - return fetchFirstWhenPresent(fetchFirstRows); - } - - public FetchFirstFinisher fetchFirstWhenPresent(Long fetchFirstRows) { - return SelectDSL.this.fetchFirstWhenPresent(fetchFirstRows); + public Buildable<R> offsetWhenPresent(Long offset) { + SelectDSL.this.offset = offset; + return SelectDSL.this; } @NotNull @@ -206,13 +174,13 @@ public R build() { } } - public class FetchFirstFinisher { - public RowsOnlyFinisher rowsOnly() { - return new RowsOnlyFinisher(); + class OFF implements OffsetFirstFinisher<R> { + @Override + public FetchFirstFinisher<R> fetchFirstWhenPresent(Long fetchFirstRows) { + SelectDSL.this.fetchFirstRows = fetchFirstRows; + return new FFF(); } - } - public class RowsOnlyFinisher implements Buildable<R> { @NotNull @Override public R build() { diff --git a/src/test/java/issues/gh100/FromGroupByTest.java b/src/test/java/issues/gh100/FromGroupByTest.java index 65b095f68..64fd15a04 100644 --- a/src/test/java/issues/gh100/FromGroupByTest.java +++ b/src/test/java/issues/gh100/FromGroupByTest.java @@ -105,7 +105,7 @@ void testFromGroupByLimitB3() { QueryExpressionDSL<SelectModel>.GroupByFinisher builder2 = builder1.groupBy(StudentDynamicSqlSupport.name); - SelectDSL<SelectModel>.LimitFinisher builder3 = builder2.limit(3); + var builder3 = builder2.limit(3); String expected = "select name, count(*)" + " from student" @@ -162,7 +162,7 @@ void testFromGroupByOffsetB3() { QueryExpressionDSL<SelectModel>.GroupByFinisher builder2 = builder1.groupBy(StudentDynamicSqlSupport.name); - SelectDSL<SelectModel>.OffsetFirstFinisher builder3 = builder2.offset(3); + var builder3 = builder2.offset(3); String expected = "select name, count(*)" + " from student" @@ -219,7 +219,7 @@ void testFromGroupByFetchFirstB3() { QueryExpressionDSL<SelectModel>.GroupByFinisher builder2 = builder1.groupBy(StudentDynamicSqlSupport.name); - SelectDSL<SelectModel>.RowsOnlyFinisher builder3 = builder2.fetchFirst(2).rowsOnly(); + var builder3 = builder2.fetchFirst(2).rowsOnly(); String expected = "select name, count(*)" + " from student" @@ -363,7 +363,7 @@ void testFromGroupByOrderByOffsetB4() { SelectDSL<SelectModel> builder3 = builder2.orderBy(StudentDynamicSqlSupport.name); - SelectDSL<SelectModel>.OffsetFirstFinisher builder4 = builder3.offset(2); + var builder4 = builder3.offset(2); String expected = "select name, count(*)" + " from student" diff --git a/src/test/java/issues/gh100/FromJoinWhereTest.java b/src/test/java/issues/gh100/FromJoinWhereTest.java index 651580e95..47867128d 100644 --- a/src/test/java/issues/gh100/FromJoinWhereTest.java +++ b/src/test/java/issues/gh100/FromJoinWhereTest.java @@ -793,7 +793,7 @@ void testFromJoinWhereUnionOrderByLimitB6() { SelectDSL<SelectModel> builder5 = builder4.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.LimitFinisher builder6 = builder5.limit(3); + var builder6 = builder5.limit(3); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -826,7 +826,7 @@ void testFromJoinWhereUnionOrderByLimitOffsetB1() { SelectDSL<SelectModel> builder5 = builder4.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.LimitFinisher builder6 = builder5.limit(3); + var builder6 = builder5.limit(3); builder6.offset(2); @@ -862,7 +862,7 @@ void testFromJoinWhereUnionOrderByLimitOffsetB2() { SelectDSL<SelectModel> builder5 = builder4.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.LimitFinisher builder6 = builder5.limit(3); + var builder6 = builder5.limit(3); builder6.offset(2); @@ -898,7 +898,7 @@ void testFromJoinWhereUnionOrderByLimitOffsetB3() { SelectDSL<SelectModel> builder5 = builder4.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.LimitFinisher builder6 = builder5.limit(3); + var builder6 = builder5.limit(3); builder6.offset(2); @@ -934,7 +934,7 @@ void testFromJoinWhereUnionOrderByLimitOffsetB4() { SelectDSL<SelectModel> builder5 = builder4.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.LimitFinisher builder6 = builder5.limit(3); + var builder6 = builder5.limit(3); builder6.offset(2); @@ -970,7 +970,7 @@ void testFromJoinWhereUnionOrderByLimitOffsetB5() { SelectDSL<SelectModel> builder5 = builder4.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.LimitFinisher builder6 = builder5.limit(3); + var builder6 = builder5.limit(3); builder6.offset(2); @@ -1006,7 +1006,7 @@ void testFromJoinWhereUnionOrderByLimitOffsetB6() { SelectDSL<SelectModel> builder5 = builder4.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.LimitFinisher builder6 = builder5.limit(3); + var builder6 = builder5.limit(3); builder6.offset(2); @@ -1042,9 +1042,9 @@ void testFromJoinWhereUnionOrderByLimitOffsetB7() { SelectDSL<SelectModel> builder5 = builder4.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.LimitFinisher builder6 = builder5.limit(3); + var builder6 = builder5.limit(3); - SelectDSL<SelectModel>.OffsetFinisher builder7 = builder6.offset(2); + var builder7 = builder6.offset(2); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -1248,7 +1248,7 @@ void testFromJoinWhereUnionOrderByOffsetB6() { SelectDSL<SelectModel> builder5 = builder4.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.OffsetFirstFinisher builder6 = builder5.offset(2); + var builder6 = builder5.offset(2); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -1282,7 +1282,7 @@ void testFromJoinWhereUnionOrderByOffsetFetchFirstB1() { SelectDSL<SelectModel> builder5 = builder4.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.OffsetFirstFinisher builder6 = builder5.offset(2); + var builder6 = builder5.offset(2); builder6.fetchFirst(3).rowsOnly(); @@ -1318,7 +1318,7 @@ void testFromJoinWhereUnionOrderByOffsetFetchFirstB2() { SelectDSL<SelectModel> builder5 = builder4.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.OffsetFirstFinisher builder6 = builder5.offset(2); + var builder6 = builder5.offset(2); builder6.fetchFirst(3).rowsOnly(); @@ -1354,7 +1354,7 @@ void testFromJoinWhereUnionOrderByOffsetFetchFirstB3() { SelectDSL<SelectModel> builder5 = builder4.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.OffsetFirstFinisher builder6 = builder5.offset(2); + var builder6 = builder5.offset(2); builder6.fetchFirst(3).rowsOnly(); @@ -1390,7 +1390,7 @@ void testFromJoinWhereUnionOrderByOffsetFetchFirstB4() { SelectDSL<SelectModel> builder5 = builder4.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.OffsetFirstFinisher builder6 = builder5.offset(2); + var builder6 = builder5.offset(2); builder6.fetchFirst(3).rowsOnly(); @@ -1426,7 +1426,7 @@ void testFromJoinWhereUnionOrderByOffsetFetchFirstB5() { SelectDSL<SelectModel> builder5 = builder4.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.OffsetFirstFinisher builder6 = builder5.offset(2); + var builder6 = builder5.offset(2); builder6.fetchFirst(3).rowsOnly(); @@ -1462,7 +1462,7 @@ void testFromJoinWhereUnionOrderByOffsetFetchFirstB6() { SelectDSL<SelectModel> builder5 = builder4.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.OffsetFirstFinisher builder6 = builder5.offset(2); + var builder6 = builder5.offset(2); builder6.fetchFirst(3).rowsOnly(); @@ -1498,9 +1498,9 @@ void testFromJoinWhereUnionOrderByOffsetFetchFirstB7() { SelectDSL<SelectModel> builder5 = builder4.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.OffsetFirstFinisher builder6 = builder5.offset(2); + var builder6 = builder5.offset(2); - SelectDSL<SelectModel>.RowsOnlyFinisher builder7 = builder6.fetchFirst(3).rowsOnly(); + var builder7 = builder6.fetchFirst(3).rowsOnly(); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -1699,7 +1699,7 @@ void testFromJoinWhereUnionOrderByFetchFirstB6() { SelectDSL<SelectModel> builder5 = builder4.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.RowsOnlyFinisher builder6 = builder5.fetchFirst(3).rowsOnly(); + var builder6 = builder5.fetchFirst(3).rowsOnly(); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -1850,7 +1850,7 @@ void testFromJoinWhereUnionLimitB5() { .select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student); - SelectDSL<SelectModel>.LimitFinisher builder5 = builder4.limit(3); + var builder5 = builder4.limit(3); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -1880,7 +1880,7 @@ void testFromJoinWhereUnionLimitOffsetB1() { .select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student); - SelectDSL<SelectModel>.LimitFinisher builder5 = builder4.limit(3); + var builder5 = builder4.limit(3); builder5.offset(2); @@ -1913,7 +1913,7 @@ void testFromJoinWhereUnionLimitOffsetB2() { .select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student); - SelectDSL<SelectModel>.LimitFinisher builder5 = builder4.limit(3); + var builder5 = builder4.limit(3); builder5.offset(2); @@ -1946,7 +1946,7 @@ void testFromJoinWhereUnionLimitOffsetB3() { .select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student); - SelectDSL<SelectModel>.LimitFinisher builder5 = builder4.limit(3); + var builder5 = builder4.limit(3); builder5.offset(2); @@ -1979,7 +1979,7 @@ void testFromJoinWhereUnionLimitOffsetB4() { .select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student); - SelectDSL<SelectModel>.LimitFinisher builder5 = builder4.limit(3); + var builder5 = builder4.limit(3); builder5.offset(2); @@ -2012,7 +2012,7 @@ void testFromJoinWhereUnionLimitOffsetB5() { .select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student); - SelectDSL<SelectModel>.LimitFinisher builder5 = builder4.limit(3); + var builder5 = builder4.limit(3); builder5.offset(2); @@ -2045,9 +2045,9 @@ void testFromJoinWhereUnionLimitOffsetB6() { .select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student); - SelectDSL<SelectModel>.LimitFinisher builder5 = builder4.limit(3); + var builder5 = builder4.limit(3); - SelectDSL<SelectModel>.OffsetFinisher builder6 = builder5.offset(2); + var builder6 = builder5.offset(2); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -2198,7 +2198,7 @@ void testFromJoinWhereUnionOffsetB5() { .select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student); - SelectDSL<SelectModel>.OffsetFirstFinisher builder5 = builder4.offset(2); + var builder5 = builder4.offset(2); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -2228,7 +2228,7 @@ void testFromJoinWhereUnionOffsetFetchFirstB1() { .select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student); - SelectDSL<SelectModel>.OffsetFirstFinisher builder5 = builder4.offset(2); + var builder5 = builder4.offset(2); builder5.fetchFirst(2).rowsOnly(); @@ -2261,7 +2261,7 @@ void testFromJoinWhereUnionOffsetFetchFirstB2() { .select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student); - SelectDSL<SelectModel>.OffsetFirstFinisher builder5 = builder4.offset(2); + var builder5 = builder4.offset(2); builder5.fetchFirst(2).rowsOnly(); @@ -2294,7 +2294,7 @@ void testFromJoinWhereUnionOffsetFetchFirstB3() { .select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student); - SelectDSL<SelectModel>.OffsetFirstFinisher builder5 = builder4.offset(2); + var builder5 = builder4.offset(2); builder5.fetchFirst(2).rowsOnly(); @@ -2327,7 +2327,7 @@ void testFromJoinWhereUnionOffsetFetchFirstB4() { .select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student); - SelectDSL<SelectModel>.OffsetFirstFinisher builder5 = builder4.offset(2); + var builder5 = builder4.offset(2); builder5.fetchFirst(2).rowsOnly(); @@ -2360,7 +2360,7 @@ void testFromJoinWhereUnionOffsetFetchFirstB5() { .select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student); - SelectDSL<SelectModel>.OffsetFirstFinisher builder5 = builder4.offset(2); + var builder5 = builder4.offset(2); builder5.fetchFirst(2).rowsOnly(); @@ -2393,9 +2393,9 @@ void testFromJoinWhereUnionOffsetFetchFirstB6() { .select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student); - SelectDSL<SelectModel>.OffsetFirstFinisher builder5 = builder4.offset(2); + var builder5 = builder4.offset(2); - SelectDSL<SelectModel>.RowsOnlyFinisher builder6 = builder5.fetchFirst(2).rowsOnly(); + var builder6 = builder5.fetchFirst(2).rowsOnly(); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -2546,7 +2546,7 @@ void testFromJoinWhereUnionFetchFirstB5() { .select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student); - SelectDSL<SelectModel>.RowsOnlyFinisher builder5 = builder4.fetchFirst(2).rowsOnly(); + var builder5 = builder4.fetchFirst(2).rowsOnly(); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -2770,7 +2770,7 @@ void testFromJoinWhereOrderByLimitB5() { SelectDSL<SelectModel> builder4 = builder3.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.LimitFinisher builder5 = builder4.limit(3); + var builder5 = builder4.limit(3); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -2796,7 +2796,7 @@ void testFromJoinWhereOrderByLimitOffsetB1() { SelectDSL<SelectModel> builder4 = builder3.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.LimitFinisher builder5 = builder4.limit(3); + var builder5 = builder4.limit(3); builder5.offset(2); @@ -2825,7 +2825,7 @@ void testFromJoinWhereOrderByLimitOffsetB2() { SelectDSL<SelectModel> builder4 = builder3.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.LimitFinisher builder5 = builder4.limit(3); + var builder5 = builder4.limit(3); builder5.offset(2); @@ -2854,7 +2854,7 @@ void testFromJoinWhereOrderByLimitOffsetB3() { SelectDSL<SelectModel> builder4 = builder3.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.LimitFinisher builder5 = builder4.limit(3); + var builder5 = builder4.limit(3); builder5.offset(2); @@ -2883,7 +2883,7 @@ void testFromJoinWhereOrderByLimitOffsetB4() { SelectDSL<SelectModel> builder4 = builder3.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.LimitFinisher builder5 = builder4.limit(3); + var builder5 = builder4.limit(3); builder5.offset(2); @@ -2912,7 +2912,7 @@ void testFromJoinWhereOrderByLimitOffsetB5() { SelectDSL<SelectModel> builder4 = builder3.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.LimitFinisher builder5 = builder4.limit(3); + var builder5 = builder4.limit(3); builder5.offset(2); @@ -2941,9 +2941,9 @@ void testFromJoinWhereOrderByLimitOffsetB6() { SelectDSL<SelectModel> builder4 = builder3.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.LimitFinisher builder5 = builder4.limit(3); + var builder5 = builder4.limit(3); - SelectDSL<SelectModel>.OffsetFinisher builder6 = builder5.offset(2); + var builder6 = builder5.offset(2); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -3074,7 +3074,7 @@ void testFromJoinWhereOrderByOffsetB5() { SelectDSL<SelectModel> builder4 = builder3.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.OffsetFirstFinisher builder5 = builder4.offset(2); + var builder5 = builder4.offset(2); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -3100,7 +3100,7 @@ void testFromJoinWhereOrderByOffsetFetchFirstB1() { SelectDSL<SelectModel> builder4 = builder3.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.OffsetFirstFinisher builder5 = builder4.offset(2); + var builder5 = builder4.offset(2); builder5.fetchFirst(3).rowsOnly(); @@ -3129,7 +3129,7 @@ void testFromJoinWhereOrderByOffsetFetchFirstB2() { SelectDSL<SelectModel> builder4 = builder3.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.OffsetFirstFinisher builder5 = builder4.offset(2); + var builder5 = builder4.offset(2); builder5.fetchFirst(3).rowsOnly(); @@ -3158,7 +3158,7 @@ void testFromJoinWhereOrderByOffsetFetchFirstB3() { SelectDSL<SelectModel> builder4 = builder3.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.OffsetFirstFinisher builder5 = builder4.offset(2); + var builder5 = builder4.offset(2); builder5.fetchFirst(3).rowsOnly(); @@ -3187,7 +3187,7 @@ void testFromJoinWhereOrderByOffsetFetchFirstB4() { SelectDSL<SelectModel> builder4 = builder3.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.OffsetFirstFinisher builder5 = builder4.offset(2); + var builder5 = builder4.offset(2); builder5.fetchFirst(3).rowsOnly(); @@ -3216,7 +3216,7 @@ void testFromJoinWhereOrderByOffsetFetchFirstB5() { SelectDSL<SelectModel> builder4 = builder3.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.OffsetFirstFinisher builder5 = builder4.offset(2); + var builder5 = builder4.offset(2); builder5.fetchFirst(3).rowsOnly(); @@ -3245,9 +3245,9 @@ void testFromJoinWhereOrderByOffsetFetchFirstB6() { SelectDSL<SelectModel> builder4 = builder3.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.OffsetFirstFinisher builder5 = builder4.offset(2); + var builder5 = builder4.offset(2); - SelectDSL<SelectModel>.RowsOnlyFinisher builder6 = builder5.fetchFirst(3).rowsOnly(); + var builder6 = builder5.fetchFirst(3).rowsOnly(); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -3378,7 +3378,7 @@ void testFromJoinWhereOrderByFetchFirstB5() { SelectDSL<SelectModel> builder4 = builder3.orderBy(StudentDynamicSqlSupport.id); - SelectDSL<SelectModel>.RowsOnlyFinisher builder5 = builder4.fetchFirst(3).rowsOnly(); + var builder5 = builder4.fetchFirst(3).rowsOnly(); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -3471,7 +3471,7 @@ void testFromJoinWhereLimitB4() { QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); - SelectDSL<SelectModel>.LimitFinisher builder4 = builder3.limit(2); + var builder4 = builder3.limit(2); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -3494,7 +3494,7 @@ void testFromJoinWhereLimitOffsetB1() { QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); - SelectDSL<SelectModel>.LimitFinisher builder4 = builder3.limit(2); + var builder4 = builder3.limit(2); builder4.offset(3); @@ -3520,7 +3520,7 @@ void testFromJoinWhereLimitOffsetB2() { QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); - SelectDSL<SelectModel>.LimitFinisher builder4 = builder3.limit(2); + var builder4 = builder3.limit(2); builder4.offset(3); @@ -3546,7 +3546,7 @@ void testFromJoinWhereLimitOffsetB3() { QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); - SelectDSL<SelectModel>.LimitFinisher builder4 = builder3.limit(2); + var builder4 = builder3.limit(2); builder4.offset(3); @@ -3572,7 +3572,7 @@ void testFromJoinWhereLimitOffsetB4() { QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); - SelectDSL<SelectModel>.LimitFinisher builder4 = builder3.limit(2); + var builder4 = builder3.limit(2); builder4.offset(3); @@ -3598,9 +3598,9 @@ void testFromJoinWhereLimitOffsetB5() { QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); - SelectDSL<SelectModel>.LimitFinisher builder4 = builder3.limit(2); + var builder4 = builder3.limit(2); - SelectDSL<SelectModel>.OffsetFinisher builder5 = builder4.offset(3); + var builder5 = builder4.offset(3); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -3693,7 +3693,7 @@ void testFromJoinWhereOffsetB4() { QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); - SelectDSL<SelectModel>.OffsetFirstFinisher builder4 = builder3.offset(3); + var builder4 = builder3.offset(3); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -3716,7 +3716,7 @@ void testFromJoinWhereOffsetFetchFirstB1() { QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); - SelectDSL<SelectModel>.OffsetFirstFinisher builder4 = builder3.offset(3); + var builder4 = builder3.offset(3); builder4.fetchFirst(2).rowsOnly(); @@ -3742,7 +3742,7 @@ void testFromJoinWhereOffsetFetchFirstB2() { QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); - SelectDSL<SelectModel>.OffsetFirstFinisher builder4 = builder3.offset(3); + var builder4 = builder3.offset(3); builder4.fetchFirst(2).rowsOnly(); @@ -3768,7 +3768,7 @@ void testFromJoinWhereOffsetFetchFirstB3() { QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); - SelectDSL<SelectModel>.OffsetFirstFinisher builder4 = builder3.offset(3); + var builder4 = builder3.offset(3); builder4.fetchFirst(2).rowsOnly(); @@ -3794,7 +3794,7 @@ void testFromJoinWhereOffsetFetchFirstB4() { QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); - SelectDSL<SelectModel>.OffsetFirstFinisher builder4 = builder3.offset(3); + var builder4 = builder3.offset(3); builder4.fetchFirst(2).rowsOnly(); @@ -3820,9 +3820,9 @@ void testFromJoinWhereOffsetFetchFirstB5() { QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); - SelectDSL<SelectModel>.OffsetFirstFinisher builder4 = builder3.offset(3); + var builder4 = builder3.offset(3); - SelectDSL<SelectModel>.RowsOnlyFinisher builder5 = builder4.fetchFirst(2).rowsOnly(); + var builder5 = builder4.fetchFirst(2).rowsOnly(); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -3915,7 +3915,7 @@ void testFromJoinWhereFetchFirstB4() { QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); - SelectDSL<SelectModel>.RowsOnlyFinisher builder4 = builder3.fetchFirst(2).rowsOnly(); + var builder4 = builder3.fetchFirst(2).rowsOnly(); String expected = "select student.id, student.name, student.idcard" + " from student" From 016ea3711118b138142c3590a4c5829399f77a94 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 16 Aug 2024 17:38:12 -0400 Subject: [PATCH 068/260] Checkstyle --- .../sql/exception/NonRenderingWhereClauseException.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/exception/NonRenderingWhereClauseException.java b/src/main/java/org/mybatis/dynamic/sql/exception/NonRenderingWhereClauseException.java index 23210e5a4..bcdcbf9a0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/exception/NonRenderingWhereClauseException.java +++ b/src/main/java/org/mybatis/dynamic/sql/exception/NonRenderingWhereClauseException.java @@ -15,12 +15,12 @@ */ package org.mybatis.dynamic.sql.exception; +import java.io.Serial; + import org.mybatis.dynamic.sql.configuration.GlobalConfiguration; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; import org.mybatis.dynamic.sql.util.Messages; -import java.io.Serial; - /** * This exception is thrown when the where clause in a statement will not render. * This can happen if all the optional conditions in a where clause fail to From 35706cdaa5361c50e6226b017c84d76defb6638f Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 16 Aug 2024 18:02:39 -0400 Subject: [PATCH 069/260] Refactor Kotlin Paging DSL --- .../util/kotlin/KotlinMultiSelectBuilder.kt | 20 +++-------- .../sql/util/kotlin/KotlinPagingDSL.kt | 36 +++++++++++++++++++ .../sql/util/kotlin/KotlinSelectBuilder.kt | 20 +++-------- 3 files changed, 44 insertions(+), 32 deletions(-) create mode 100644 src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinPagingDSL.kt diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiSelectBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiSelectBuilder.kt index 3c3ab1f71..b0512ed1f 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiSelectBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiSelectBuilder.kt @@ -26,7 +26,7 @@ import org.mybatis.dynamic.sql.util.Buildable typealias MultiSelectCompleter = KotlinMultiSelectBuilder.() -> Unit @MyBatisDslMarker -class KotlinMultiSelectBuilder: Buildable<MultiSelectModel> { +class KotlinMultiSelectBuilder: Buildable<MultiSelectModel>, KotlinPagingDSL { private var dsl: MultiSelectDSL? = null set(value) { assertNull(field, "ERROR.33") //$NON-NLS-1$ @@ -63,27 +63,15 @@ class KotlinMultiSelectBuilder: Buildable<MultiSelectModel> { getDsl().orderBy(columns.asList()) } - fun limit(limit: Long) { - limitWhenPresent(limit) - } - - fun limitWhenPresent(limit: Long?) { + override fun limitWhenPresent(limit: Long?) { getDsl().limitWhenPresent(limit) } - fun offset(offset: Long) { - offsetWhenPresent(offset) - } - - fun offsetWhenPresent(offset: Long?) { + override fun offsetWhenPresent(offset: Long?) { getDsl().offsetWhenPresent(offset) } - fun fetchFirst(fetchFirstRows: Long) { - fetchFirstWhenPresent(fetchFirstRows) - } - - fun fetchFirstWhenPresent(fetchFirstRows: Long?) { + override fun fetchFirstWhenPresent(fetchFirstRows: Long?) { getDsl().fetchFirstWhenPresent(fetchFirstRows).rowsOnly() } diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinPagingDSL.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinPagingDSL.kt new file mode 100644 index 000000000..f0b898dd1 --- /dev/null +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinPagingDSL.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2016-2024 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 + * + * https://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.util.kotlin + +interface KotlinPagingDSL { + fun limit(limit: Long) { + limitWhenPresent(limit) + } + + fun limitWhenPresent(limit: Long?) + + fun offset(offset: Long) { + offsetWhenPresent(offset) + } + + fun offsetWhenPresent(offset: Long?) + + fun fetchFirst(fetchFirstRows: Long) { + fetchFirstWhenPresent(fetchFirstRows) + } + + fun fetchFirstWhenPresent(fetchFirstRows: Long?) +} diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSelectBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSelectBuilder.kt index 4bd8cdefa..abaefebdc 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSelectBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSelectBuilder.kt @@ -28,7 +28,7 @@ typealias SelectCompleter = KotlinSelectBuilder.() -> Unit @Suppress("TooManyFunctions") class KotlinSelectBuilder(private val fromGatherer: QueryExpressionDSL.FromGatherer<SelectModel>) : - KotlinBaseJoiningBuilder<QueryExpressionDSL<SelectModel>>(), Buildable<SelectModel> { + KotlinBaseJoiningBuilder<QueryExpressionDSL<SelectModel>>(), Buildable<SelectModel>, KotlinPagingDSL { private var dsl: KQueryExpressionDSL? = null @@ -58,27 +58,15 @@ class KotlinSelectBuilder(private val fromGatherer: QueryExpressionDSL.FromGathe getDsl().orderBy(columns.toList()) } - fun limit(limit: Long) { - limitWhenPresent(limit) - } - - fun limitWhenPresent(limit: Long?) { + override fun limitWhenPresent(limit: Long?) { getDsl().limitWhenPresent(limit) } - fun offset(offset: Long) { - offsetWhenPresent(offset) - } - - fun offsetWhenPresent(offset: Long?) { + override fun offsetWhenPresent(offset: Long?) { getDsl().offsetWhenPresent(offset) } - fun fetchFirst(fetchFirstRows: Long) { - fetchFirstWhenPresent(fetchFirstRows) - } - - fun fetchFirstWhenPresent(fetchFirstRows: Long?) { + override fun fetchFirstWhenPresent(fetchFirstRows: Long?) { getDsl().fetchFirstWhenPresent(fetchFirstRows).rowsOnly() } From e48c7f62a64ced24ff4bddb27412fd5caa64dbdc Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 16 Aug 2024 18:02:45 -0400 Subject: [PATCH 070/260] Docs --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 010c421c2..b4c7526c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,8 @@ Other important changes: an empty In condition would render as invalid SQL and would usually cause a runtime exception from the database. With this change, the exception thrown is more predictable and the error is caught before sending the SQL to the database. +- All the paging methods (limit, offset, fetchFirst) now have "WhenPresent" variations that will drop the phrase from + rendering if a null value is passed in ## Release 1.5.2 - June 3, 2024 From 52d897a8c537c8c79cd3dd2cb3a19c851cc192f7 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Sat, 17 Aug 2024 07:45:14 -0400 Subject: [PATCH 071/260] Add some kotlin error checking --- .../dynamic/sql/util/kotlin/JoinCollector.kt | 27 ++++++------------- .../sql/util/kotlin/KotlinBaseBuilders.kt | 24 ++++++++--------- .../dynamic/sql/util/messages.properties | 1 + .../mybatis3/joins/JoinMapperNewSyntaxTest.kt | 17 ++++++++++++ .../kotlin/mybatis3/joins/JoinMapperTest.kt | 17 ++++++++++++ 5 files changed, 55 insertions(+), 31 deletions(-) diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt index 0cb43d1d4..ec63179db 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt @@ -15,44 +15,33 @@ */ package org.mybatis.dynamic.sql.util.kotlin -import org.mybatis.dynamic.sql.AndOrCriteriaGroup import org.mybatis.dynamic.sql.BindableColumn -import org.mybatis.dynamic.sql.ColumnAndConditionCriterion import org.mybatis.dynamic.sql.SqlBuilder -import org.mybatis.dynamic.sql.SqlCriterion import org.mybatis.dynamic.sql.VisitableCondition typealias JoinReceiver = JoinCollector.() -> Unit @MyBatisDslMarker class JoinCollector { - private var initialCriterion: SqlCriterion? = null - internal val subCriteria = mutableListOf<AndOrCriteriaGroup>() + private val criteriaCollector = GroupingCriteriaCollector() - internal fun initialCriterion() : SqlCriterion = invalidIfNull(initialCriterion, "ERROR.22") //$NON-NLS-1$ + internal fun initialCriterion() = invalidIfNull(criteriaCollector.initialCriterion, "ERROR.22") //$NON-NLS-1$ + internal fun subCriteria() = criteriaCollector.subCriteria fun on (receiver: GroupingCriteriaReceiver) { - GroupingCriteriaCollector().apply(receiver).also { - initialCriterion = it.initialCriterion - subCriteria.addAll(it.subCriteria) - } + assertNull(criteriaCollector.initialCriterion, "ERROR.45") //$NON-NLS-1$ + criteriaCollector.apply(receiver) } // TODO - Deprecate? fun <T> on(leftColumn: BindableColumn<T>): RightColumnCollector<T> = RightColumnCollector { - initialCriterion = ColumnAndConditionCriterion.withColumn(leftColumn) - .withCondition(it) - .build() + assertNull(criteriaCollector.initialCriterion, "ERROR.45") //$NON-NLS-1$ + criteriaCollector.apply { leftColumn.invoke(it) } } // TODO - Deprecate? fun <T> and(leftColumn: BindableColumn<T>): RightColumnCollector<T> = RightColumnCollector { - subCriteria.add( - AndOrCriteriaGroup.Builder() - .withConnector("and") //$NON-NLS-1$ - .withInitialCriterion(ColumnAndConditionCriterion.withColumn(leftColumn).withCondition(it).build()) - .build() - ) + criteriaCollector.and { leftColumn.invoke(it) } } } diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt index e9d070320..88386b2c1 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt @@ -66,12 +66,12 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> : fun join(table: SqlTable, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> - join(table, jc.initialCriterion(), jc.subCriteria) + join(table, jc.initialCriterion(), jc.subCriteria()) } fun join(table: SqlTable, alias: String, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> - join(table, alias, jc.initialCriterion(), jc.subCriteria) + join(table, alias, jc.initialCriterion(), jc.subCriteria()) } fun join( @@ -79,17 +79,17 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> : joinCriteria: JoinReceiver ): Unit = applyToDsl(subQuery, joinCriteria) { sq, jc -> - join(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria) + join(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria()) } fun fullJoin(table: SqlTable, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> - fullJoin(table, jc.initialCriterion(), jc.subCriteria) + fullJoin(table, jc.initialCriterion(), jc.subCriteria()) } fun fullJoin(table: SqlTable, alias: String, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> - fullJoin(table, alias, jc.initialCriterion(), jc.subCriteria) + fullJoin(table, alias, jc.initialCriterion(), jc.subCriteria()) } fun fullJoin( @@ -97,17 +97,17 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> : joinCriteria: JoinReceiver ): Unit = applyToDsl(subQuery, joinCriteria) { sq, jc -> - fullJoin(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria) + fullJoin(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria()) } fun leftJoin(table: SqlTable, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> - leftJoin(table, jc.initialCriterion(), jc.subCriteria) + leftJoin(table, jc.initialCriterion(), jc.subCriteria()) } fun leftJoin(table: SqlTable, alias: String, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> - leftJoin(table, alias, jc.initialCriterion(), jc.subCriteria) + leftJoin(table, alias, jc.initialCriterion(), jc.subCriteria()) } fun leftJoin( @@ -115,17 +115,17 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> : joinCriteria: JoinReceiver ): Unit = applyToDsl(subQuery, joinCriteria) { sq, jc -> - leftJoin(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria) + leftJoin(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria()) } fun rightJoin(table: SqlTable, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> - rightJoin(table, jc.initialCriterion(), jc.subCriteria) + rightJoin(table, jc.initialCriterion(), jc.subCriteria()) } fun rightJoin(table: SqlTable, alias: String, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> - rightJoin(table, alias, jc.initialCriterion(), jc.subCriteria) + rightJoin(table, alias, jc.initialCriterion(), jc.subCriteria()) } fun rightJoin( @@ -133,7 +133,7 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> : joinCriteria: JoinReceiver ): Unit = applyToDsl(subQuery, joinCriteria) { sq, jc -> - rightJoin(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria) + rightJoin(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria()) } private fun applyToDsl(joinCriteria: JoinReceiver, applyJoin: D.(JoinCollector) -> Unit) { diff --git a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties index ef092e651..8600b0437 100644 --- a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties +++ b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties @@ -61,4 +61,5 @@ ERROR.41=You cannot call "then" in a Kotlin case expression more than once ERROR.42=You cannot call `else` in a Kotlin case expression more than once ERROR.43=A Kotlin cast expression must have one, and only one, `as` element ERROR.44={0} conditions must contain at least one value +ERROR.45=You cannot call "on" in a Kotlin join expression more than once INTERNAL.ERROR=Internal Error {0} diff --git a/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt index a99124a12..cc2159c13 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt @@ -815,4 +815,21 @@ class JoinMapperNewSyntaxTest { } }.withMessage(Messages.getString("ERROR.22")) //$NON-NLS-1$ } + + @Test + fun testJoinWithDoubleOnCondition() { + // create second table instance for self-join + val user2 = user.withAlias("other_user") + + assertThatExceptionOfType(KInvalidSQLException::class.java).isThrownBy { + select(user.userId, user.userName, user.parentId) { + from(user, "u1") + join(user2, "u2") { + on { user.userId isEqualTo user2.parentId } + on { user.userId isEqualTo user2.parentId } + } + where { user2.userId isEqualTo 4 } + } + }.withMessage(Messages.getString("ERROR.45")) //$NON-NLS-1$ + } } diff --git a/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperTest.kt index a60bc2105..5754fe631 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperTest.kt @@ -813,6 +813,23 @@ class JoinMapperTest { }.withMessage(Messages.getString("ERROR.22")) //$NON-NLS-1$ } + @Test + fun testJoinWithDoubleOnCondition() { + // create second table instance for self-join + val user2 = user.withAlias("other_user") + + assertThatExceptionOfType(KInvalidSQLException::class.java).isThrownBy { + select(user.userId, user.userName, user.parentId) { + from(user, "u1") + join(user2, "u2") { + on(user.userId) equalTo user2.parentId + on(user.userId) equalTo user2.parentId + } + where { user2.userId isEqualTo 4 } + } + }.withMessage(Messages.getString("ERROR.45")) //$NON-NLS-1$ + } + @Test fun testThatAliasesPropagateToSubQueryConditions() { sqlSessionFactory.openSession().use { session -> From ffce2bc550b19c2592a94a7027af1630cf0ec73d Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Sat, 17 Aug 2024 09:10:24 -0400 Subject: [PATCH 072/260] Improvements to the Paging Implementation --- .../dynamic/sql/select/MultiSelectDSL.java | 33 +++++++------------ .../mybatis/dynamic/sql/select/PagingDSL.java | 1 + .../mybatis/dynamic/sql/select/SelectDSL.java | 33 +++++++------------ 3 files changed, 23 insertions(+), 44 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java index 6b01f3696..42a20e551 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java @@ -65,19 +65,19 @@ public MultiSelectDSL orderBy(Collection<? extends SortSpecification> columns) { @Override public LimitFinisher<MultiSelectModel> limitWhenPresent(Long limit) { this.limit = limit; - return new LF(); + return new LocalLimitFinisher(); } @Override public OffsetFirstFinisher<MultiSelectModel> offsetWhenPresent(Long offset) { this.offset = offset; - return new OFF(); + return new LocalOffsetFirstFinisher(); } @Override public FetchFirstFinisher<MultiSelectModel> fetchFirstWhenPresent(Long fetchFirstRows) { this.fetchFirstRows = fetchFirstRows; - return new FFF(); + return () -> MultiSelectDSL.this; } @NotNull @@ -106,20 +106,7 @@ public MultiSelectDSL configureStatement(Consumer<StatementConfiguration> consum return this; } - class FFF implements FetchFirstFinisher<MultiSelectModel> { - @Override - public Buildable<MultiSelectModel> rowsOnly() { - return MultiSelectDSL.this; - } - } - - class LF implements LimitFinisher<MultiSelectModel> { - @Override - public Buildable<MultiSelectModel> offsetWhenPresent(Long offset) { - MultiSelectDSL.this.offset = offset; - return MultiSelectDSL.this; - } - + abstract class BaseBuildable implements Buildable<MultiSelectModel> { @NotNull @Override public MultiSelectModel build() { @@ -127,17 +114,19 @@ public MultiSelectModel build() { } } - class OFF implements OffsetFirstFinisher<MultiSelectModel> { + class LocalOffsetFirstFinisher extends BaseBuildable implements OffsetFirstFinisher<MultiSelectModel> { @Override public FetchFirstFinisher<MultiSelectModel> fetchFirstWhenPresent(Long fetchFirstRows) { MultiSelectDSL.this.fetchFirstRows = fetchFirstRows; - return new FFF(); + return () -> MultiSelectDSL.this; } + } - @NotNull + class LocalLimitFinisher extends BaseBuildable implements LimitFinisher<MultiSelectModel> { @Override - public MultiSelectModel build() { - return MultiSelectDSL.this.build(); + public Buildable<MultiSelectModel> offsetWhenPresent(Long offset) { + MultiSelectDSL.this.offset = offset; + return MultiSelectDSL.this; } } } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/PagingDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/PagingDSL.java index 89cfafafb..0d86e5e9a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/PagingDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/PagingDSL.java @@ -52,6 +52,7 @@ default FetchFirstFinisher<T> fetchFirst(long fetchFirstRows) { FetchFirstFinisher<T> fetchFirstWhenPresent(Long fetchFirstRows); } + @FunctionalInterface interface FetchFirstFinisher<T> { Buildable<T> rowsOnly(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java index 82e55aefb..4b5ef2077 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java @@ -109,17 +109,17 @@ void orderBy(Collection<? extends SortSpecification> columns) { public LimitFinisher<R> limitWhenPresent(Long limit) { this.limit = limit; - return new LF(); + return new LocalLimitFinisher(); } public OffsetFirstFinisher<R> offsetWhenPresent(Long offset) { this.offset = offset; - return new OFF(); + return new LocalOffsetFirstFinisher(); } public FetchFirstFinisher<R> fetchFirstWhenPresent(Long fetchFirstRows) { this.fetchFirstRows = fetchFirstRows; - return new FFF(); + return () -> SelectDSL.this; } @Override @@ -153,20 +153,7 @@ private Optional<PagingModel> buildPagingModel() { .build(); } - class FFF implements FetchFirstFinisher<R> { - @Override - public Buildable<R> rowsOnly() { - return SelectDSL.this; - } - } - - class LF implements LimitFinisher<R> { - @Override - public Buildable<R> offsetWhenPresent(Long offset) { - SelectDSL.this.offset = offset; - return SelectDSL.this; - } - + abstract class BaseBuildable implements Buildable<R> { @NotNull @Override public R build() { @@ -174,17 +161,19 @@ public R build() { } } - class OFF implements OffsetFirstFinisher<R> { + class LocalOffsetFirstFinisher extends BaseBuildable implements OffsetFirstFinisher<R> { @Override public FetchFirstFinisher<R> fetchFirstWhenPresent(Long fetchFirstRows) { SelectDSL.this.fetchFirstRows = fetchFirstRows; - return new FFF(); + return () -> SelectDSL.this; } + } - @NotNull + class LocalLimitFinisher extends BaseBuildable implements LimitFinisher<R> { @Override - public R build() { - return SelectDSL.this.build(); + public Buildable<R> offsetWhenPresent(Long offset) { + SelectDSL.this.offset = offset; + return SelectDSL.this; } } } From fdda342a0728c4a6918e51bf15cc2f2ddcde7066 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 17 Aug 2024 19:29:52 +0000 Subject: [PATCH 073/260] Update dependency maven to v3.9.9 --- .mvn/wrapper/maven-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index fd5166374..01aa6654c 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -16,5 +16,5 @@ # under the License. wrapperVersion=3.3.2 distributionType=source -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.3.2/maven-wrapper-3.3.2.jar From 3cd872b2db21c05eac25526a62141d98879c2ec3 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 19 Aug 2024 11:02:46 -0400 Subject: [PATCH 074/260] Add deprecation notices --- .../org/mybatis/dynamic/sql/SqlBuilder.java | 36 +++++++++++++------ .../dynamic/sql/util/kotlin/JoinCollector.kt | 8 ++--- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java index 88871f6f0..4468b523a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java @@ -435,6 +435,32 @@ static <T> ColumnAndConditionCriterion<T> on(BindableColumn<T> joinColumn, Visit .build(); } + /** + * Starting in version 2.0.0, this function is a synonym for {@link SqlBuilder#isEqualTo(BasicColumn)}. + * + * @param column the column + * @return an IsEqualToColumn condition + * @param <T> the column type + * @deprecated since 2.0.0. Please replace with isEqualTo(column) + */ + @Deprecated(since = "2.0.0", forRemoval = true) + static <T> IsEqualToColumn<T> equalTo(BindableColumn<T> column) { + return isEqualTo(column); + } + + /** + * Starting in version 2.0.0, this function is a synonym for {@link SqlBuilder#isEqualTo(Object)}. + * + * @param value the value + * @return an IsEqualTo condition + * @param <T> the column type + * @deprecated since 2.0.0. Please replace with isEqualTo(value) + */ + @Deprecated(since = "2.0.0", forRemoval = true) + static <T> IsEqualTo<T> equalTo(T value) { + return isEqualTo(value); + } + // case expressions @SuppressWarnings("java:S100") static <T> SimpleCaseDSL<T> case_(BindableColumn<T> column) { @@ -446,16 +472,6 @@ static SearchedCaseDSL case_() { return SearchedCaseDSL.searchedCase(); } - // TODO - Deprecate? - static <T> IsEqualToColumn<T> equalTo(BindableColumn<T> column) { - return IsEqualToColumn.of(column); - } - - // TODO - Deprecate? - static <T> IsEqualTo<T> equalTo(T value) { - return IsEqualTo.of(value); - } - // aggregate support static CountAll count() { return new CountAll(); diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt index ec63179db..ba68b4a8e 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt @@ -33,20 +33,20 @@ class JoinCollector { criteriaCollector.apply(receiver) } - // TODO - Deprecate? + @Deprecated("Please replace with the \"on\" lambda expression", level = DeprecationLevel.WARNING) fun <T> on(leftColumn: BindableColumn<T>): RightColumnCollector<T> = RightColumnCollector { assertNull(criteriaCollector.initialCriterion, "ERROR.45") //$NON-NLS-1$ criteriaCollector.apply { leftColumn.invoke(it) } } - // TODO - Deprecate? + @Deprecated("Please move the \"and\" expression into an \"on\" lambda", level = DeprecationLevel.WARNING) fun <T> and(leftColumn: BindableColumn<T>): RightColumnCollector<T> = RightColumnCollector { criteriaCollector.and { leftColumn.invoke(it) } } } class RightColumnCollector<T>(private val joinConditionConsumer: (VisitableCondition<T>) -> Unit) { - infix fun equalTo(rightColumn: BindableColumn<T>) = joinConditionConsumer.invoke(SqlBuilder.equalTo(rightColumn)) + infix fun equalTo(rightColumn: BindableColumn<T>) = joinConditionConsumer.invoke(SqlBuilder.isEqualTo(rightColumn)) - infix fun equalTo(value: T) = joinConditionConsumer.invoke(SqlBuilder.equalTo(value)) + infix fun equalTo(value: T) = joinConditionConsumer.invoke(SqlBuilder.isEqualTo(value)) } From f888b831b4a6fb1e8fe4bf1ef8bb2b7d29c493d9 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 19 Aug 2024 15:13:29 -0400 Subject: [PATCH 075/260] New join syntax for Kotlin --- .../sql/select/render/JoinRenderer.java | 20 +- .../dynamic/sql/util/kotlin/JoinCollector.kt | 7 - .../sql/util/kotlin/KotlinBaseBuilders.kt | 88 ++++++++ .../dynamic/sql/util/messages.properties | 1 + .../mybatis3/joins/JoinMapperNewSyntaxTest.kt | 191 +++++++++--------- 5 files changed, 192 insertions(+), 115 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/JoinRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/JoinRenderer.java index 0da029f59..6a437f010 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/JoinRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/JoinRenderer.java @@ -15,8 +15,6 @@ */ package org.mybatis.dynamic.sql.select.render; -import static org.mybatis.dynamic.sql.util.StringUtilities.spaceBefore; - import java.util.Objects; import java.util.stream.Collectors; @@ -26,6 +24,7 @@ import org.mybatis.dynamic.sql.select.join.JoinSpecification; import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.FragmentCollector; +import org.mybatis.dynamic.sql.util.Messages; public class JoinRenderer { private final JoinModel joinModel; @@ -46,22 +45,17 @@ public FragmentAndParameters render() { } private FragmentAndParameters renderJoinSpecification(JoinSpecification joinSpecification) { - FragmentAndParameters renderedTable = joinSpecification.table().accept(tableExpressionRenderer); - FragmentAndParameters renderedJoinSpecification = JoinSpecificationRenderer + FragmentCollector fc = new FragmentCollector(); + fc.add(FragmentAndParameters.fromFragment(joinSpecification.joinType().type())); + fc.add(joinSpecification.table().accept(tableExpressionRenderer)); + fc.add(JoinSpecificationRenderer .withJoinSpecification(joinSpecification) .withRenderingContext(renderingContext) .build() .render() - .orElseThrow(() -> new InvalidSqlException("Join Specifications Must Render")); // TODO - - String fragment = joinSpecification.joinType().type() - + spaceBefore(renderedTable.fragment()) - + spaceBefore(renderedJoinSpecification.fragment()); + .orElseThrow(() -> new InvalidSqlException(Messages.getString("ERROR.46")))); //$NON-NLS-1$ - return FragmentAndParameters.withFragment(fragment) - .withParameters(renderedTable.parameters()) - .withParameters(renderedJoinSpecification.parameters()) - .build(); + return fc.toFragmentAndParameters(Collectors.joining(" ")); //$NON-NLS-1$ } public static Builder withJoinModel(JoinModel joinModel) { diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt index ba68b4a8e..078ea2a34 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt @@ -28,18 +28,11 @@ class JoinCollector { internal fun initialCriterion() = invalidIfNull(criteriaCollector.initialCriterion, "ERROR.22") //$NON-NLS-1$ internal fun subCriteria() = criteriaCollector.subCriteria - fun on (receiver: GroupingCriteriaReceiver) { - assertNull(criteriaCollector.initialCriterion, "ERROR.45") //$NON-NLS-1$ - criteriaCollector.apply(receiver) - } - - @Deprecated("Please replace with the \"on\" lambda expression", level = DeprecationLevel.WARNING) fun <T> on(leftColumn: BindableColumn<T>): RightColumnCollector<T> = RightColumnCollector { assertNull(criteriaCollector.initialCriterion, "ERROR.45") //$NON-NLS-1$ criteriaCollector.apply { leftColumn.invoke(it) } } - @Deprecated("Please move the \"and\" expression into an \"on\" lambda", level = DeprecationLevel.WARNING) fun <T> and(leftColumn: BindableColumn<T>): RightColumnCollector<T> = RightColumnCollector { criteriaCollector.and { leftColumn.invoke(it) } } diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt index 88386b2c1..059792b2c 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt @@ -64,16 +64,19 @@ abstract class KotlinBaseBuilder<D : AbstractWhereStarter<*,*>> { @Suppress("TooManyFunctions") abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> : KotlinBaseBuilder<D>() { + @Deprecated("Please use the new form with the \"on\" keyword outside the lambda") fun join(table: SqlTable, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> join(table, jc.initialCriterion(), jc.subCriteria()) } + @Deprecated("Please use the new form with the \"on\" keyword outside the lambda") fun join(table: SqlTable, alias: String, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> join(table, alias, jc.initialCriterion(), jc.subCriteria()) } + @Deprecated("Please use the new form with the \"on\" keyword outside the lambda") fun join( subQuery: KotlinQualifiedSubQueryBuilder.() -> Unit, joinCriteria: JoinReceiver @@ -82,16 +85,36 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> : join(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria()) } + fun join(table: SqlTable): JoinCriteriaGatherer = + JoinCriteriaGatherer { + getDsl().join(table, it.initialCriterion, it.subCriteria) + } + + fun join(table: SqlTable, alias: String): JoinCriteriaGatherer = + JoinCriteriaGatherer { + getDsl().join(table, alias, it.initialCriterion, it.subCriteria) + } + + fun join( + subQuery: KotlinQualifiedSubQueryBuilder.() -> Unit): JoinCriteriaGatherer = + JoinCriteriaGatherer { + val sq = KotlinQualifiedSubQueryBuilder().apply(subQuery) + getDsl().join(sq, sq.correlationName, it.initialCriterion, it.subCriteria) + } + + @Deprecated("Please use the new form with the \"on\" keyword outside the lambda") fun fullJoin(table: SqlTable, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> fullJoin(table, jc.initialCriterion(), jc.subCriteria()) } + @Deprecated("Please use the new form with the \"on\" keyword outside the lambda") fun fullJoin(table: SqlTable, alias: String, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> fullJoin(table, alias, jc.initialCriterion(), jc.subCriteria()) } + @Deprecated("Please use the new form with the \"on\" keyword outside the lambda") fun fullJoin( subQuery: KotlinQualifiedSubQueryBuilder.() -> Unit, joinCriteria: JoinReceiver @@ -100,16 +123,36 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> : fullJoin(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria()) } + fun fullJoin(table: SqlTable): JoinCriteriaGatherer = + JoinCriteriaGatherer { + getDsl().fullJoin(table, it.initialCriterion, it.subCriteria) + } + + fun fullJoin(table: SqlTable, alias: String): JoinCriteriaGatherer = + JoinCriteriaGatherer { + getDsl().fullJoin(table, alias, it.initialCriterion, it.subCriteria) + } + + fun fullJoin( + subQuery: KotlinQualifiedSubQueryBuilder.() -> Unit): JoinCriteriaGatherer = + JoinCriteriaGatherer { + val sq = KotlinQualifiedSubQueryBuilder().apply(subQuery) + getDsl().fullJoin(sq, sq.correlationName, it.initialCriterion, it.subCriteria) + } + + @Deprecated("Please use the new form with the \"on\" keyword outside the lambda") fun leftJoin(table: SqlTable, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> leftJoin(table, jc.initialCriterion(), jc.subCriteria()) } + @Deprecated("Please use the new form with the \"on\" keyword outside the lambda") fun leftJoin(table: SqlTable, alias: String, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> leftJoin(table, alias, jc.initialCriterion(), jc.subCriteria()) } + @Deprecated("Please use the new form with the \"on\" keyword outside the lambda") fun leftJoin( subQuery: KotlinQualifiedSubQueryBuilder.() -> Unit, joinCriteria: JoinReceiver @@ -118,16 +161,36 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> : leftJoin(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria()) } + fun leftJoin(table: SqlTable): JoinCriteriaGatherer = + JoinCriteriaGatherer { + getDsl().leftJoin(table, it.initialCriterion, it.subCriteria) + } + + fun leftJoin(table: SqlTable, alias: String): JoinCriteriaGatherer = + JoinCriteriaGatherer { + getDsl().leftJoin(table, alias, it.initialCriterion, it.subCriteria) + } + + fun leftJoin( + subQuery: KotlinQualifiedSubQueryBuilder.() -> Unit): JoinCriteriaGatherer = + JoinCriteriaGatherer { + val sq = KotlinQualifiedSubQueryBuilder().apply(subQuery) + getDsl().leftJoin(sq, sq.correlationName, it.initialCriterion, it.subCriteria) + } + + @Deprecated("Please use the new form with the \"on\" keyword outside the lambda") fun rightJoin(table: SqlTable, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> rightJoin(table, jc.initialCriterion(), jc.subCriteria()) } + @Deprecated("Please use the new form with the \"on\" keyword outside the lambda") fun rightJoin(table: SqlTable, alias: String, joinCriteria: JoinReceiver): Unit = applyToDsl(joinCriteria) { jc -> rightJoin(table, alias, jc.initialCriterion(), jc.subCriteria()) } + @Deprecated("Please use the new form with the \"on\" keyword outside the lambda") fun rightJoin( subQuery: KotlinQualifiedSubQueryBuilder.() -> Unit, joinCriteria: JoinReceiver @@ -136,6 +199,23 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> : rightJoin(sq, sq.correlationName, jc.initialCriterion(), jc.subCriteria()) } + fun rightJoin(table: SqlTable): JoinCriteriaGatherer = + JoinCriteriaGatherer { + getDsl().rightJoin(table, it.initialCriterion, it.subCriteria) + } + + fun rightJoin(table: SqlTable, alias: String): JoinCriteriaGatherer = + JoinCriteriaGatherer { + getDsl().rightJoin(table, alias, it.initialCriterion, it.subCriteria) + } + + fun rightJoin( + subQuery: KotlinQualifiedSubQueryBuilder.() -> Unit): JoinCriteriaGatherer = + JoinCriteriaGatherer { + val sq = KotlinQualifiedSubQueryBuilder().apply(subQuery) + getDsl().rightJoin(sq, sq.correlationName, it.initialCriterion, it.subCriteria) + } + private fun applyToDsl(joinCriteria: JoinReceiver, applyJoin: D.(JoinCollector) -> Unit) { getDsl().applyJoin(JoinCollector().apply(joinCriteria)) } @@ -148,3 +228,11 @@ abstract class KotlinBaseJoiningBuilder<D : AbstractQueryExpressionDSL<*, *>> : getDsl().applyJoin(KotlinQualifiedSubQueryBuilder().apply(subQuery), JoinCollector().apply(joinCriteria)) } } + +class JoinCriteriaGatherer(private val consumer: (GroupingCriteriaCollector) -> Unit) { + infix fun on (joinCriteria: GroupingCriteriaReceiver): Unit = + with(GroupingCriteriaCollector().apply(joinCriteria)) { + assertTrue(initialCriterion != null || subCriteria.isNotEmpty(), "ERROR.22") //$NON-NLS-1$ + consumer.invoke(this) + } +} diff --git a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties index 8600b0437..05ecfcfe8 100644 --- a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties +++ b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties @@ -62,4 +62,5 @@ ERROR.42=You cannot call `else` in a Kotlin case expression more than once ERROR.43=A Kotlin cast expression must have one, and only one, `as` element ERROR.44={0} conditions must contain at least one value ERROR.45=You cannot call "on" in a Kotlin join expression more than once +ERROR.46=At least one join criterion must render INTERNAL.ERROR=Internal Error {0} diff --git a/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt index cc2159c13..1b69ba5ec 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt @@ -57,8 +57,8 @@ class JoinMapperNewSyntaxTest { orderDetail.lineNumber, orderDetail.description, orderDetail.quantity ) { from(orderMaster, "om") - join(orderDetail, "od") { - on { orderMaster.orderId isEqualTo orderDetail.orderId } + join(orderDetail, "od") on { + orderMaster.orderId isEqualTo orderDetail.orderId } } @@ -96,11 +96,9 @@ class JoinMapperNewSyntaxTest { orderDetail.lineNumber, orderDetail.description, orderDetail.quantity ) { from(orderMaster, "om") - join(orderDetail, "od") { - on { - orderMaster.orderId isEqualTo orderDetail.orderId - and { orderMaster.orderId isEqualTo 1 } - } + join(orderDetail, "od") on { + orderMaster.orderId isEqualTo orderDetail.orderId + and { orderMaster.orderId isEqualTo 1 } } } @@ -133,11 +131,9 @@ class JoinMapperNewSyntaxTest { orderDetail.lineNumber, orderDetail.description, orderDetail.quantity ) { from(orderMaster, "om") - join(orderDetail, "od") { - on { - orderMaster.orderId isEqualTo orderDetail.orderId - and { orderMaster.orderId isEqualTo constant<Int>("1") } - } + join(orderDetail, "od") on { + orderMaster.orderId isEqualTo orderDetail.orderId + and { orderMaster.orderId isEqualTo constant<Int>("1") } } } @@ -168,11 +164,9 @@ class JoinMapperNewSyntaxTest { orderDetail.description, orderDetail.quantity ) { from(orderMaster, "om") - join(orderDetail, "od") { - on { - orderMaster.orderId isEqualTo orderDetail.orderId - and { orderMaster.orderId isEqualTo orderDetail.orderId } - } + join(orderDetail, "od") on { + orderMaster.orderId isEqualTo orderDetail.orderId + and { orderMaster.orderId isEqualTo orderDetail.orderId } } } @@ -189,11 +183,9 @@ class JoinMapperNewSyntaxTest { orderDetail.description, orderDetail.quantity ) { from(orderMaster, "om") - join(orderDetail, "od") { - on { - orderMaster.orderId isEqualTo orderDetail.orderId - and { orderMaster.orderId isEqualTo orderDetail.orderId } - } + join(orderDetail, "od") on { + orderMaster.orderId isEqualTo orderDetail.orderId + and { orderMaster.orderId isEqualTo orderDetail.orderId } } where { orderMaster.orderId isEqualTo 1 } } @@ -214,11 +206,11 @@ class JoinMapperNewSyntaxTest { itemMaster.description, orderLine.quantity ) { from(orderMaster, "om") - join(orderLine, "ol") { - on { orderMaster.orderId isEqualTo orderLine.orderId } + join(orderLine, "ol") on { + orderMaster.orderId isEqualTo orderLine.orderId } - join(itemMaster, "im") { - on { orderLine.itemId isEqualTo itemMaster.itemId } + join(itemMaster, "im") on { + orderLine.itemId isEqualTo itemMaster.itemId } where { orderMaster.orderId isEqualTo 2 } } @@ -250,11 +242,11 @@ class JoinMapperNewSyntaxTest { orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description ) { from(orderMaster, "om") - join(orderLine, "ol") { - on { orderMaster.orderId isEqualTo orderLine.orderId } + join(orderLine, "ol") on { + orderMaster.orderId isEqualTo orderLine.orderId } - fullJoin(itemMaster, "im") { - on { orderLine.itemId isEqualTo itemMaster.itemId } + fullJoin(itemMaster, "im") on { + orderLine.itemId isEqualTo itemMaster.itemId } orderBy(orderLine.orderId, itemMaster.itemId) } @@ -318,26 +310,21 @@ class JoinMapperNewSyntaxTest { } + "om" } - join( - subQuery = { - select(orderLine.allColumns()) { - from(orderLine) - } - + "ol" - }, - joinCriteria = { - on { "om"(orderMaster.orderId) isEqualTo "ol"(orderLine.orderId) } + join { + select(orderLine.allColumns()) { + from(orderLine) } - ) - fullJoin( - { - select(itemMaster.allColumns()) { - from(itemMaster) - } - + "im" + + "ol" + } on { + "om"(orderMaster.orderId) isEqualTo "ol"(orderLine.orderId) + } + fullJoin { + select(itemMaster.allColumns()) { + from(itemMaster) } - ) { - on { "ol"(orderLine.itemId) isEqualTo "im"(itemMaster.itemId) } + +"im" + } on { + "ol"(orderLine.itemId) isEqualTo "im"(itemMaster.itemId) } orderBy(orderLine.orderId, itemMaster.itemId) } @@ -395,11 +382,11 @@ class JoinMapperNewSyntaxTest { orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description ) { from(orderMaster, "om") - join(orderLine, "ol") { - on { orderMaster.orderId isEqualTo orderLine.orderId } + join(orderLine, "ol") on { + orderMaster.orderId isEqualTo orderLine.orderId } - fullJoin(itemMaster) { - on { orderLine.itemId isEqualTo itemMaster.itemId } + fullJoin(itemMaster) on { + orderLine.itemId isEqualTo itemMaster.itemId } orderBy(orderLine.orderId, itemMaster.itemId) } @@ -443,11 +430,11 @@ class JoinMapperNewSyntaxTest { orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description ) { from(orderMaster, "om") - join(orderLine, "ol") { - on { orderMaster.orderId isEqualTo orderLine.orderId } + join(orderLine, "ol") on { + orderMaster.orderId isEqualTo orderLine.orderId } - leftJoin(itemMaster, "im") { - on { orderLine.itemId isEqualTo itemMaster.itemId } + leftJoin(itemMaster, "im") on { + orderLine.itemId isEqualTo itemMaster.itemId } orderBy(orderLine.orderId, itemMaster.itemId) } @@ -487,8 +474,8 @@ class JoinMapperNewSyntaxTest { itemMaster.description ) { from(orderMaster, "om") - join(orderLine, "ol") { - on { orderMaster.orderId isEqualTo orderLine.orderId } + join(orderLine, "ol") on { + orderMaster.orderId isEqualTo orderLine.orderId } leftJoin( { @@ -497,8 +484,8 @@ class JoinMapperNewSyntaxTest { } + "im" } - ) { - on { orderLine.itemId isEqualTo "im"(itemMaster.itemId) } + ) on { + orderLine.itemId isEqualTo "im"(itemMaster.itemId) } orderBy(orderLine.orderId, itemMaster.itemId) } @@ -537,11 +524,11 @@ class JoinMapperNewSyntaxTest { orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description ) { from(orderMaster, "om") - join(orderLine, "ol") { - on { orderMaster.orderId isEqualTo orderLine.orderId } + join(orderLine, "ol") on { + orderMaster.orderId isEqualTo orderLine.orderId } - leftJoin(itemMaster) { - on { orderLine.itemId isEqualTo itemMaster.itemId } + leftJoin(itemMaster) on { + orderLine.itemId isEqualTo itemMaster.itemId } orderBy(orderLine.orderId, itemMaster.itemId) } @@ -580,11 +567,11 @@ class JoinMapperNewSyntaxTest { orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description ) { from(orderMaster, "om") - join(orderLine, "ol") { - on { orderMaster.orderId isEqualTo orderLine.orderId } + join(orderLine, "ol") on { + orderMaster.orderId isEqualTo orderLine.orderId } - rightJoin(itemMaster, "im") { - on { orderLine.itemId isEqualTo itemMaster.itemId } + rightJoin(itemMaster, "im") on { + orderLine.itemId isEqualTo itemMaster.itemId } orderBy(orderLine.orderId, itemMaster.itemId) } @@ -624,8 +611,8 @@ class JoinMapperNewSyntaxTest { "im"(itemMaster.itemId), itemMaster.description ) { from(orderMaster, "om") - join(orderLine, "ol") { - on { orderMaster.orderId isEqualTo orderLine.orderId } + join(orderLine, "ol") on { + orderMaster.orderId isEqualTo orderLine.orderId } rightJoin( { @@ -634,8 +621,8 @@ class JoinMapperNewSyntaxTest { } + "im" } - ) { - on { orderLine.itemId isEqualTo "im"(itemMaster.itemId) } + ) on { + orderLine.itemId isEqualTo "im"(itemMaster.itemId) } orderBy(orderLine.orderId, itemMaster.itemId) } @@ -674,11 +661,11 @@ class JoinMapperNewSyntaxTest { orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description ) { from(orderMaster, "om") - join(orderLine, "ol") { - on { orderMaster.orderId isEqualTo orderLine.orderId } + join(orderLine, "ol") on { + orderMaster.orderId isEqualTo orderLine.orderId } - rightJoin(itemMaster) { - on { orderLine.itemId isEqualTo itemMaster.itemId } + rightJoin(itemMaster) on { + orderLine.itemId isEqualTo itemMaster.itemId } orderBy(orderLine.orderId, itemMaster.itemId) } @@ -719,8 +706,8 @@ class JoinMapperNewSyntaxTest { // get Bamm Bamm's parent - should be Barney val selectStatement = select(user.userId, user.userName, user.parentId) { from(user, "u1") - join(user2, "u2") { - on { user.userId isEqualTo user2.parentId } + join(user2, "u2") on { + user.userId isEqualTo user2.parentId } where { user2.userId isEqualTo 4 } } @@ -750,8 +737,8 @@ class JoinMapperNewSyntaxTest { // get Bamm Bamm's parent - should be Barney val selectStatement = select(user.userId, user.userName, user.parentId) { from(user) - join(user2) { - on { user.userId isEqualTo user2.parentId } + join(user2) on { + user.userId isEqualTo user2.parentId } where { user2.userId isEqualTo 4 } } @@ -782,8 +769,8 @@ class JoinMapperNewSyntaxTest { // get Bamm Bamm's parent - should be Barney val selectStatement = select(user.userId, user.userName, user.parentId) { from(user, "u1") - join(user2, "u2") { - on { user.userId isEqualTo user2.parentId } + join(user2, "u2") on { + user.userId isEqualTo user2.parentId } where { user2.userId isEqualTo 4 } } @@ -803,33 +790,47 @@ class JoinMapperNewSyntaxTest { } @Test - fun testJoinWithNoOnCondition() { - // create second table instance for self-join - val user2 = user.withAlias("other_user") + fun testSelfWithNewAliasAndOverrideOddUsage() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(JoinMapper::class.java) - assertThatExceptionOfType(KInvalidSQLException::class.java).isThrownBy { - select(user.userId, user.userName, user.parentId) { + // create second table instance for self-join + val user2 = user.withAlias("other_user") + + // get Bamm Bamm's parent - should be Barney + val selectStatement = select(user.userId, user.userName, user.parentId) { from(user, "u1") - join(user2, "u2") { } + join(user2, "u2") on { + and { user.userId isEqualTo user2.parentId } + } where { user2.userId isEqualTo 4 } } - }.withMessage(Messages.getString("ERROR.22")) //$NON-NLS-1$ + + val expectedStatement = "select u1.user_id, u1.user_name, u1.parent_id" + + " from User u1 join User u2 on u1.user_id = u2.parent_id" + + " where u2.user_id = #{parameters.p1,jdbcType=INTEGER}" + assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) + val rows = mapper.selectManyMappedRows(selectStatement) + assertThat(rows).hasSize(1) + + assertThat(rows[0]).containsExactly( + entry("USER_ID", 2), + entry("USER_NAME", "Barney"), + ) + } } @Test - fun testJoinWithDoubleOnCondition() { + fun testJoinWithNoOnCondition() { // create second table instance for self-join val user2 = user.withAlias("other_user") assertThatExceptionOfType(KInvalidSQLException::class.java).isThrownBy { select(user.userId, user.userName, user.parentId) { from(user, "u1") - join(user2, "u2") { - on { user.userId isEqualTo user2.parentId } - on { user.userId isEqualTo user2.parentId } - } + join(user2, "u2") on { } where { user2.userId isEqualTo 4 } } - }.withMessage(Messages.getString("ERROR.45")) //$NON-NLS-1$ + }.withMessage(Messages.getString("ERROR.22")) //$NON-NLS-1$ } } From 4984924f2462e677a998320f21f17bffe0d8dd9b Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 19 Aug 2024 15:51:10 -0400 Subject: [PATCH 076/260] Docs --- CHANGELOG.md | 4 +- src/site/markdown/docs/kotlinOverview.md | 9 +- src/site/markdown/docs/migratingV1toV2.md | 69 +++++++++ src/site/markdown/docs/select.md | 168 ++++++++++++---------- src/site/site.xml | 1 + 5 files changed, 168 insertions(+), 83 deletions(-) create mode 100644 src/site/markdown/docs/migratingV1toV2.md diff --git a/CHANGELOG.md b/CHANGELOG.md index b4c7526c2..2d46635fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,9 @@ Other important changes: With this change, the exception thrown is more predictable and the error is caught before sending the SQL to the database. - All the paging methods (limit, offset, fetchFirst) now have "WhenPresent" variations that will drop the phrase from - rendering if a null value is passed in + rendering if a null value is passed in +- The JOIN syntax is updated and now allows full boolean expressions like a WHERE clause. The prior JOIN syntax + is deprecated and will be removed in a future release. ## Release 1.5.2 - June 3, 2024 diff --git a/src/site/markdown/docs/kotlinOverview.md b/src/site/markdown/docs/kotlinOverview.md index 5b646a7b0..78dba6a78 100644 --- a/src/site/markdown/docs/kotlinOverview.md +++ b/src/site/markdown/docs/kotlinOverview.md @@ -417,9 +417,9 @@ val selectStatement = select(orderMaster.orderId, orderMaster.orderDate, orderDe orderDetail.description, orderDetail.quantity ) { from(orderMaster, "om") - join(orderDetail, "od") { - on(orderMaster.orderId) equalTo orderDetail.orderId - and(orderMaster.orderId) equalTo orderDetail.orderId + join(orderDetail, "od") on { + orderMaster.orderId isEqualTo orderDetail.orderId + and { orderMaster.orderId isEqualTo orderDetail.orderId } } where { orderMaster.orderId isEqualTo 1 } or { @@ -433,8 +433,7 @@ val selectStatement = select(orderMaster.orderId, orderMaster.orderDate, orderDe In a select statement you must specify a table in a `from` clause. Everything else is optional. -Multiple join clauses can be specified if you need to join additional tables. In a join clause, you must -specify an `on` condition, and you may specify additional `and` conditions as necessary. Full, left, right, inner, +Multiple join clauses can be specified if you need to join additional tables. Full, left, right, inner, and outer joins are supported. Where clauses can be of arbitrary complexity and support all SQL operators including exists operators, subqueries, etc. diff --git a/src/site/markdown/docs/migratingV1toV2.md b/src/site/markdown/docs/migratingV1toV2.md new file mode 100644 index 000000000..8d51e68f9 --- /dev/null +++ b/src/site/markdown/docs/migratingV1toV2.md @@ -0,0 +1,69 @@ +# V1 to V2 Migration Guide + +Version 2 of MyBatis Dynamic SQL introduced many new features. This page will document how to migrate code +from prior releases to version 2. + +## Java Join Syntax + +Version2 offers a fully flexible join specification and reuses the capabilities of where clauses. Of course, +not all capabilities are supported in databases, but you should now be able to code any type of join specification. + +The changes in the Java DSL are mostly internal and should not impact most users. The `equalTo` methods has been +deprecated in favor of `isEqualTo`, but all other changes should be hidden. + +V1 Join Specification Example: +```java +SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDetail.lineNumber, orderDetail.quantity) + .from(orderMaster, "om") + .join(orderDetail, "od", on(orderMaster.orderId, equalTo(orderDetail.orderId))) + .build() + .render(RenderingStrategies.MYBATIS3); +``` + +V2 Join Specification Example: +```java +SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDetail.lineNumber, orderDetail.quantity) + .from(orderMaster, "om") + .join(orderDetail, "od", on(orderMaster.orderId, isEqualTo(orderDetail.orderId))) + .build() + .render(RenderingStrategies.MYBATIS3); +``` + +## Kotlin Join Syntax + +Like the Java DSL, the V2 Kotlin DSL offers a fully flexible join specification and reuses the capabilities of where +clauses. Of course, not all capabilities are supported in databases, but you should now be able to code any type of +join specification. + +The changes in the Kotlin DSL allow a more natural expressions of a join specification. The main difference is that +the "on" keyword should be moved outside the join specification lambda (it is now an infix function). Inside the lambda, +the conditions should be rewritten to match the syntax of a where clause. + +V1 Join Specification Example: +```kotlin +val selectStatement = select( + orderMaster.orderId, orderMaster.orderDate, + orderDetail.lineNumber, orderDetail.description, orderDetail.quantity +) { + from(orderMaster, "om") + join(orderDetail, "od") { + on(orderMaster.orderId) equalTo orderDetail.orderId + and(orderMaster.orderId) equalTo constant("1") + } +} +``` + +V2 Join Specification Example: +```kotlin +val selectStatement = select( + orderMaster.orderId, orderMaster.orderDate, + orderDetail.lineNumber, orderDetail.description, orderDetail.quantity +) { + from(orderMaster, "om") + join(orderDetail, "od") on { + orderMaster.orderId isEqualTo orderDetail.orderId + and { orderMaster.orderId isEqualTo constant("1") } + } +} + +``` diff --git a/src/site/markdown/docs/select.md b/src/site/markdown/docs/select.md index 923c30c42..f73ef17dd 100644 --- a/src/site/markdown/docs/select.md +++ b/src/site/markdown/docs/select.md @@ -10,7 +10,7 @@ In general, the following are supported: 2. Tables can be aliased per select statement 3. Columns can be aliased per select statement 4. Some support for aggregates (avg, min, max, sum) -5. Equijoins of type INNER, LEFT OUTER, RIGHT OUTER, FULL OUTER +5. Joins of type INNER, LEFT OUTER, RIGHT OUTER, FULL OUTER 6. Subqueries in where clauses. For example, `where foo in (select foo from foos where id < 36)` 7. Select from another select. For example `select count(*) from (select foo from foos where id < 36)` 8. Multi-Selects. For example `(select * from foo order by id limit 3) union (select * from foo order by id desc limit 3)` @@ -21,47 +21,50 @@ At this time, the library does not support the following: 2. INTERSECT, EXCEPT, etc. The user guide page for WHERE Clauses shows examples of many types of SELECT statements with different complexities of -the WHERE clause including support for sub-queries. We will just show a single example here, including an ORDER BY clause: +the WHERE clause including support for sub-queries. We will just show a single example here, including an ORDER BY +clause: ```java - SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) - .from(animalData) - .where(id, isIn(1, 5, 7)) - .and(bodyWeight, isBetween(1.0).and(3.0)) - .orderBy(id.descending(), bodyWeight) - .build() - .render(RenderingStrategies.MYBATIS3); - - List<AnimalData> animals = mapper.selectMany(selectStatement); +SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) + .from(animalData) + .where(id, isIn(1, 5, 7)) + .and(bodyWeight, isBetween(1.0).and(3.0)) + .orderBy(id.descending(), bodyWeight) + .build() + .render(RenderingStrategies.MYBATIS3); + +List<AnimalData> animals = mapper.selectMany(selectStatement); ``` The WHERE and ORDER BY clauses are optional. ## Joins -The library supports the generation of equijoin statements - joins defined by column matching. For example: +The library supports the generation of join statements. For example: ```java - SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) - .from(orderMaster, "om") - .join(orderDetail, "od").on(orderMaster.orderId, equalTo(orderDetail.orderId)) - .build() - .render(RenderingStrategies.MYBATIS3); +SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) + .from(orderMaster, "om") + .join(orderDetail, "od").on(orderMaster.orderId, isEqualTo(orderDetail.orderId)) + .build() + .render(RenderingStrategies.MYBATIS3); ``` -Notice that you can give an alias to a table if desired. If you don't specify an alias, the full table name will be used in the generated SQL. +Notice that you can give an alias to a table if desired. If you don't specify an alias, the full table name will be +used in the generated SQL. Multiple tables can be joined in a single statement. For example: ```java - SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) - .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, equalTo(orderLine.orderId)) - .join(itemMaster, "im").on(orderLine.itemId, equalTo(itemMaster.itemId)) - .where(orderMaster.orderId, isEqualTo(2)) - .build() - .render(RenderingStrategies.MYBATIS3); +SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) + .from(orderMaster, "om") + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .join(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .where(orderMaster.orderId, isEqualTo(2)) + .build() + .render(RenderingStrategies.MYBATIS3); ``` -Join queries will likely require you to define a MyBatis result mapping in XML. This is the only instance where XML is required. This is due to the limitations of the MyBatis annotations when mapping collections. +Join queries will likely require you to define a MyBatis result mapping in XML. This is the only instance where XML is +required. This is due to the limitations of the MyBatis annotations when mapping collections. The library supports four join types: @@ -74,14 +77,14 @@ The library supports four join types: The library supports the generation of UNION and UNION ALL queries. For example: ```java - SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) - .from(animalData) - .union() - .selectDistinct(id, animalName, bodyWeight, brainWeight) - .from(animalData) - .orderBy(id) - .build() - .render(RenderingStrategies.MYBATIS3); +SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) + .from(animalData) + .union() + .selectDistinct(id, animalName, bodyWeight, brainWeight) + .from(animalData) + .orderBy(id) + .build() + .render(RenderingStrategies.MYBATIS3); ``` Any number of SELECT statements can be added to a UNION query. Only one ORDER BY phrase is allowed. @@ -96,16 +99,16 @@ Multi-select queries are a special case of union select statements. The differen paging clauses can be applied to the merged queries. For example: ```java - SelectStatementProvider selectStatement = multiSelect( - select(id, animalName, bodyWeight, brainWeight) - .from(animalData) - .orderBy(id) - .limit(2) +SelectStatementProvider selectStatement = multiSelect( + select(id, animalName, bodyWeight, brainWeight) + .from(animalData) + .orderBy(id) + .limit(2) ).union( - selectDistinct(id, animalName, bodyWeight, brainWeight) - .from(animalData) - .orderBy(id.descending()) - .limit(3) + selectDistinct(id, animalName, bodyWeight, brainWeight) + .from(animalData) + .orderBy(id.descending()) + .limit(3) ) .build() .render(RenderingStrategies.MYBATIS3); @@ -114,7 +117,8 @@ paging clauses can be applied to the merged queries. For example: ## MyBatis Mapper for Select Statements The SelectStatementProvider object can be used as a parameter to a MyBatis mapper method directly. If you -are using an annotated mapper, the select method should look like this (note that we recommend coding a "selectMany" and a "selectOne" method with a shared result mapping): +are using an annotated mapper, the select method should look like this (note that we recommend coding a "selectMany" +and a "selectOne" method with a shared result mapping): ```java import org.apache.ibatis.annotations.Result; @@ -143,7 +147,9 @@ import org.mybatis.dynamic.sql.util.SqlProviderAdapter; ## XML Mapper for Join Statements -If you are coding a join, it is likely you will need to code an XML mapper to define the result map. This is due to a MyBatis limitation - the annotations cannot define a collection mapping. If you have to do this, the Java code looks like this: +If you are coding a join, it is likely you will need to code an XML mapper to define the result map. This is due to a +MyBatis limitation - the annotations cannot define a collection mapping. If you have to do this, the Java code looks +like this: ```java @SelectProvider(type=SqlProviderAdapter.class, method="select") @@ -171,7 +177,8 @@ And the corresponding XML looks like this: Notice that the resultMap is the only element in the XML mapper. This is our recommended practice. ## XML Mapper for Select Statements -We do not recommend using an XML mapper for select statements, but if you want to do so the SelectStatementProvider object can be used as a parameter to a MyBatis mapper method directly. +We do not recommend using an XML mapper for select statements, but if you want to do so the SelectStatementProvider +object can be used as a parameter to a MyBatis mapper method directly. If you are using an XML mapper, the select method should look like this in the Java interface: @@ -205,30 +212,33 @@ Order by phrases can be difficult to calculate when there are aliased columns, a This library has taken a relatively simple approach: 1. When specifying an SqlColumn in an ORDER BY phrase the library will either write the column alias or the column -name into the ORDER BY phrase. For the ORDER BY phrase, the table alias (if there is one) will be ignored. Use this pattern -when the ORDER BY column is a member of the select list. For example `orderBy(foo)`. If the column has an alias, then -it is easist to use the "arbitrary string" method with the column alias as shown below. -1. It is also possible to explicitly specify a table alias for a column in an ORDER BY phrase. Use this pattern when -there is a join, and the ORDER BY column is in two or more tables, and the ORDER BY column is not in the select -list. For example `orderBy(sortColumn("t1", foo))`. -1. If none of the above use cases meet your needs, then you can specify an arbitrary String to write into the rendered ORDER BY -phrase (see below for an example). + name into the ORDER BY phrase. For the ORDER BY phrase, the table alias (if there is one) will be ignored. Use this + pattern when the ORDER BY column is a member of the select list. For example `orderBy(foo)`. If the column has an + alias, then it is easiest to use the "arbitrary string" method with the column alias as shown below. +2. It is also possible to explicitly specify a table alias for a column in an ORDER BY phrase. Use this pattern when + there is a join, and the ORDER BY column is in two or more tables, and the ORDER BY column is not in the select + list. For example `orderBy(sortColumn("t1", foo))`. +3. If none of the above use cases meet your needs, then you can specify an arbitrary String to write into the rendered + ORDER BY phrase (see below for an example). In our testing, this caused an issue in only one case. When there is an outer join and the select list contains both the left and right join column. In that case, the workaround is to supply a column alias for both columns. -When using a column function (lower, upper, etc.), then it is customary to give the calculated column an alias so you will have a predictable result set. In cases like this there will not be a column to use for an alias. The library supports arbitrary values in an ORDER BY expression like this: +When using a column function (lower, upper, etc.), then it is customary to give the calculated column an alias so you +will have a predictable result set. In cases like this there will not be a column to use for an alias. The library +supports arbitrary values in an ORDER BY expression like this: ```java - SelectStatementProvider selectStatement = select(substring(gender, 1, 1).as("ShortGender"), avg(age).as("AverageAge")) - .from(person, "a") - .groupBy(substring(gender, 1, 1)) - .orderBy(sortColumn("ShortGender").descending()) - .build() - .render(RenderingStrategies.MYBATIS3); +SelectStatementProvider selectStatement = select(substring(gender, 1, 1).as("ShortGender"), avg(age).as("AverageAge")) + .from(person, "a") + .groupBy(substring(gender, 1, 1)) + .orderBy(sortColumn("ShortGender").descending()) + .build() + .render(RenderingStrategies.MYBATIS3); ``` -In this example the `substring` function is used in both the select list and the GROUP BY expression. In the ORDER BY expression, we use the `sortColumn` function to duplicate the alias given to the column in the select list. +In this example the `substring` function is used in both the select list and the GROUP BY expression. In the ORDER BY +expression, we use the `sortColumn` function to duplicate the alias given to the column in the select list. ## Limit and Offset Support Since version 1.1.1 the select statement supports limit and offset for paging (or slicing) queries. You can specify: @@ -237,18 +247,22 @@ Since version 1.1.1 the select statement supports limit and offset for paging (o - Offset only - Both limit and offset -It is important to note that the select renderer writes limit and offset clauses into the generated select statement as is. The library does not attempt to normalize those values for databases that don't support limit and offset directly. Therefore, it is very important for users to understand whether or not the target database supports limit and offset. If the target database does not support limit and offset, then it is likely that using this support will create SQL that has runtime errors. +It is important to note that the select renderer writes limit and offset clauses into the generated select statement as +is. The library does not attempt to normalize those values for databases that don't support limit and offset directly. +Therefore, it is very important for users to understand whether the target database supports limit and offset. +If the target database does not support limit and offset, then it is likely that using this support will create SQL +that has runtime errors. An example follows: ```java - SelectStatementProvider selectStatement = select(animalData.allColumns()) - .from(animalData) - .orderBy(id) - .limit(3) - .offset(22) - .build() - .render(RenderingStrategies.MYBATIS3); +SelectStatementProvider selectStatement = select(animalData.allColumns()) + .from(animalData) + .orderBy(id) + .limit(3) + .offset(22) + .build() + .render(RenderingStrategies.MYBATIS3); ``` ## Fetch First Support @@ -263,11 +277,11 @@ Fetch first is an SQL standard and is supported by most databases. An example follows: ```java - SelectStatementProvider selectStatement = select(animalData.allColumns()) - .from(animalData) - .orderBy(id) - .offset(22) - .fetchFirst(3).rowsOnly() - .build() - .render(RenderingStrategies.MYBATIS3); +SelectStatementProvider selectStatement = select(animalData.allColumns()) + .from(animalData) + .orderBy(id) + .offset(22) + .fetchFirst(3).rowsOnly() + .build() + .render(RenderingStrategies.MYBATIS3); ``` diff --git a/src/site/site.xml b/src/site/site.xml index e22bf264d..2a02c4a79 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -36,6 +36,7 @@ <menu name="User's Guide"> <item href="docs/introduction.html" name="Introduction" /> <item href="docs/CHANGELOG.html" name="Change Log" /> + <item href="docs/migratingV1toV2.html" name="Migrating from V1 to V2" /> <item href="docs/quickStart.html" name="Quick Start" /> <item href="docs/exceptions.html" name="Exceptions thrown by the Library" /> <item href="docs/configuration.html" name="Configuration of the Library" /> From f31473cba252f659bc0c1beabf4e6f0b95111160 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 19 Aug 2024 17:13:38 -0400 Subject: [PATCH 077/260] Docs --- src/site/markdown/docs/migratingV1toV2.md | 50 +++++++---------------- 1 file changed, 15 insertions(+), 35 deletions(-) diff --git a/src/site/markdown/docs/migratingV1toV2.md b/src/site/markdown/docs/migratingV1toV2.md index 8d51e68f9..f24fdaafc 100644 --- a/src/site/markdown/docs/migratingV1toV2.md +++ b/src/site/markdown/docs/migratingV1toV2.md @@ -1,45 +1,21 @@ # V1 to V2 Migration Guide -Version 2 of MyBatis Dynamic SQL introduced many new features. This page will document how to migrate code -from prior releases to version 2. +Version 2 of MyBatis Dynamic SQL introduced many new features. On this page we will provide examples for the more +significant changes - changes that are more substantial than following deprecation messages. -## Java Join Syntax - -Version2 offers a fully flexible join specification and reuses the capabilities of where clauses. Of course, -not all capabilities are supported in databases, but you should now be able to code any type of join specification. +## Kotlin Join Syntax +The Java DSL for joins was changed to allow much more flexible joins. Of course, not all capabilities are supported in +all databases, but you should now be able to code most joins specification that are supported by your database. The changes in the Java DSL are mostly internal and should not impact most users. The `equalTo` methods has been deprecated in favor of `isEqualTo`, but all other changes should be hidden. -V1 Join Specification Example: -```java -SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDetail.lineNumber, orderDetail.quantity) - .from(orderMaster, "om") - .join(orderDetail, "od", on(orderMaster.orderId, equalTo(orderDetail.orderId))) - .build() - .render(RenderingStrategies.MYBATIS3); -``` +Like the Java DSL, the V2 Kotlin DSL offers a fully flexible join specification and allows for much more flexible join +specifications. The changes in the Kotlin DSL allow a more natural expressions of a join specification. The main +difference is that the "on" keyword should be moved outside the join specification lambda (it is now an infix function). +Inside the lambda, the conditions should be rewritten to match the syntax of a where clause. -V2 Join Specification Example: -```java -SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDetail.lineNumber, orderDetail.quantity) - .from(orderMaster, "om") - .join(orderDetail, "od", on(orderMaster.orderId, isEqualTo(orderDetail.orderId))) - .build() - .render(RenderingStrategies.MYBATIS3); -``` - -## Kotlin Join Syntax - -Like the Java DSL, the V2 Kotlin DSL offers a fully flexible join specification and reuses the capabilities of where -clauses. Of course, not all capabilities are supported in databases, but you should now be able to code any type of -join specification. - -The changes in the Kotlin DSL allow a more natural expressions of a join specification. The main difference is that -the "on" keyword should be moved outside the join specification lambda (it is now an infix function). Inside the lambda, -the conditions should be rewritten to match the syntax of a where clause. - -V1 Join Specification Example: +V1 (Deprecated) Join Specification Example: ```kotlin val selectStatement = select( orderMaster.orderId, orderMaster.orderDate, @@ -65,5 +41,9 @@ val selectStatement = select( and { orderMaster.orderId isEqualTo constant("1") } } } - ``` + +Notice that the "on" keyword has been moved outside the lambda, and the conditions are coded with the same syntax used +by WHERE, HAVING, and CASE expressions. + +The prior syntax is deprecated and will be removed in a future release. From 0f1ad9c33f2f64033eb61f00f2ff1da42536948e Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 19 Aug 2024 17:25:46 -0400 Subject: [PATCH 078/260] Checkstyle --- src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java | 4 ++-- .../java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java | 2 +- .../org/mybatis/dynamic/sql/select/QueryExpressionDSL.java | 3 ++- src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java | 2 +- src/site/markdown/docs/migratingV1toV2.md | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java index 4468b523a..2cf6ac277 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java @@ -439,8 +439,8 @@ static <T> ColumnAndConditionCriterion<T> on(BindableColumn<T> joinColumn, Visit * Starting in version 2.0.0, this function is a synonym for {@link SqlBuilder#isEqualTo(BasicColumn)}. * * @param column the column - * @return an IsEqualToColumn condition * @param <T> the column type + * @return an IsEqualToColumn condition * @deprecated since 2.0.0. Please replace with isEqualTo(column) */ @Deprecated(since = "2.0.0", forRemoval = true) @@ -452,8 +452,8 @@ static <T> IsEqualToColumn<T> equalTo(BindableColumn<T> column) { * Starting in version 2.0.0, this function is a synonym for {@link SqlBuilder#isEqualTo(Object)}. * * @param value the value - * @return an IsEqualTo condition * @param <T> the column type + * @return an IsEqualTo condition * @deprecated since 2.0.0. Please replace with isEqualTo(value) */ @Deprecated(since = "2.0.0", forRemoval = true) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java index 42a20e551..0c244481c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java @@ -77,7 +77,7 @@ public OffsetFirstFinisher<MultiSelectModel> offsetWhenPresent(Long offset) { @Override public FetchFirstFinisher<MultiSelectModel> fetchFirstWhenPresent(Long fetchFirstRows) { this.fetchFirstRows = fetchFirstRows; - return () -> MultiSelectDSL.this; + return () -> this; } @NotNull diff --git a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java index 034e9b593..c4e2b5d9a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java @@ -359,7 +359,8 @@ public <T> JoinSpecificationFinisher on(BindableColumn<T> joinColumn, VisitableC public class JoinSpecificationFinisher extends AbstractBooleanExpressionDSL<JoinSpecificationFinisher> - implements AbstractWhereStarter<QueryExpressionWhereBuilder, JoinSpecificationFinisher>, Buildable<R>, PagingDSL<R> { + implements AbstractWhereStarter<QueryExpressionWhereBuilder, JoinSpecificationFinisher>, Buildable<R>, + PagingDSL<R> { private final TableExpression table; private final JoinType joinType; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java index 4b5ef2077..525e3282d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java @@ -119,7 +119,7 @@ public OffsetFirstFinisher<R> offsetWhenPresent(Long offset) { public FetchFirstFinisher<R> fetchFirstWhenPresent(Long fetchFirstRows) { this.fetchFirstRows = fetchFirstRows; - return () -> SelectDSL.this; + return () -> this; } @Override diff --git a/src/site/markdown/docs/migratingV1toV2.md b/src/site/markdown/docs/migratingV1toV2.md index f24fdaafc..12b6adc37 100644 --- a/src/site/markdown/docs/migratingV1toV2.md +++ b/src/site/markdown/docs/migratingV1toV2.md @@ -11,7 +11,7 @@ The changes in the Java DSL are mostly internal and should not impact most users deprecated in favor of `isEqualTo`, but all other changes should be hidden. Like the Java DSL, the V2 Kotlin DSL offers a fully flexible join specification and allows for much more flexible join -specifications. The changes in the Kotlin DSL allow a more natural expressions of a join specification. The main +specifications. The changes in the Kotlin DSL allow a more natural expressions of a join specification. The main difference is that the "on" keyword should be moved outside the join specification lambda (it is now an infix function). Inside the lambda, the conditions should be rewritten to match the syntax of a where clause. From 9c0d7488a7c6419fe9a321dbc8d90e15004cfe5f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 12:04:04 +0000 Subject: [PATCH 079/260] Update kotlin monorepo to v2.0.20 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1cef97f04..5def2d3ee 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,7 @@ <module.name>org.mybatis.dynamic.sql</module.name> - <kotlin.version>2.0.10</kotlin.version> + <kotlin.version>2.0.20</kotlin.version> <kotlin.compiler.jvmTarget>17</kotlin.compiler.jvmTarget> <kotlin.compiler.languageVersion>2.0</kotlin.compiler.languageVersion> <kotlin.compiler.apiVersion>2.0</kotlin.compiler.apiVersion> From 13e16ecd59cb4c3de0b0544aa0f3427fa28bc0ce Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 22 Aug 2024 20:44:42 +0000 Subject: [PATCH 080/260] Update dependency org.postgresql:postgresql to v42.7.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5def2d3ee..cd05834f0 100644 --- a/pom.xml +++ b/pom.xml @@ -181,7 +181,7 @@ <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> - <version>42.7.3</version> + <version>42.7.4</version> <scope>test</scope> </dependency> <dependency> From b4415921d93d9e7f25c55fb83e5761b908132683 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 7 Sep 2024 13:13:59 +0000 Subject: [PATCH 081/260] Update dependency ch.qos.logback:logback-classic to v1.5.8 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cd05834f0..2a7cbd9bb 100644 --- a/pom.xml +++ b/pom.xml @@ -163,7 +163,7 @@ <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> - <version>1.5.7</version> + <version>1.5.8</version> <scope>test</scope> </dependency> <dependency> From 5865325a020900db5af3fe442dfc112c4200ed10 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Sep 2024 14:05:35 +0000 Subject: [PATCH 082/260] Update dependency org.springframework:spring-jdbc to v6.1.13 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2a7cbd9bb..8555c856f 100644 --- a/pom.xml +++ b/pom.xml @@ -94,7 +94,7 @@ <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> - <version>6.1.12</version> + <version>6.1.13</version> <scope>provided</scope> <optional>true</optional> </dependency> From 1bfc8e9d02c0b0b516ff75e9ea59d27347b91281 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 25 Sep 2024 10:52:10 +0000 Subject: [PATCH 083/260] Update junit5 monorepo to v5.11.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8555c856f..991746894 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ <properties> <java.version>17</java.version> <java.release.version>17</java.release.version> - <junit.jupiter.version>5.11.0</junit.jupiter.version> + <junit.jupiter.version>5.11.1</junit.jupiter.version> <spring.batch.version>5.1.2</spring.batch.version> <checkstyle.config>checkstyle-override.xml</checkstyle.config> From 187cfc2098713fa708ff9f512f175421798c27d7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 01:34:38 +0000 Subject: [PATCH 084/260] Update testcontainers-java monorepo to v1.20.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 991746894..9b2d89a54 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ <sonar.tests>src/test/java,src/test/kotlin</sonar.tests> <kotlin.code.style>official</kotlin.code.style> - <test.containers.version>1.20.1</test.containers.version> + <test.containers.version>1.20.2</test.containers.version> <osgi.export>org.mybatis.dynamic.sql.*;version=${project.version};-noimport:=true</osgi.export> <!-- Reproducible Builds --> From 392f63850098ab2e0234dcbee2a3f1a228e82ef5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Oct 2024 14:10:49 +0000 Subject: [PATCH 085/260] Update junit5 monorepo to v5.11.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9b2d89a54..048c066c3 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ <properties> <java.version>17</java.version> <java.release.version>17</java.release.version> - <junit.jupiter.version>5.11.1</junit.jupiter.version> + <junit.jupiter.version>5.11.2</junit.jupiter.version> <spring.batch.version>5.1.2</spring.batch.version> <checkstyle.config>checkstyle-override.xml</checkstyle.config> From 1bc43186e61257f3cf59013aa810603c7645a6e3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 8 Oct 2024 15:25:33 +0000 Subject: [PATCH 086/260] Update dependency ch.qos.logback:logback-classic to v1.5.9 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 048c066c3..e2ffb86d8 100644 --- a/pom.xml +++ b/pom.xml @@ -163,7 +163,7 @@ <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> - <version>1.5.8</version> + <version>1.5.9</version> <scope>test</scope> </dependency> <dependency> From d7632a7db2d7b9768c9c4d7a65ba91d0cb4c7cc0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 10 Oct 2024 09:59:09 +0000 Subject: [PATCH 087/260] Update kotlin monorepo to v2.0.21 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e2ffb86d8..d68c74ab0 100644 --- a/pom.xml +++ b/pom.xml @@ -67,7 +67,7 @@ <module.name>org.mybatis.dynamic.sql</module.name> - <kotlin.version>2.0.20</kotlin.version> + <kotlin.version>2.0.21</kotlin.version> <kotlin.compiler.jvmTarget>17</kotlin.compiler.jvmTarget> <kotlin.compiler.languageVersion>2.0</kotlin.compiler.languageVersion> <kotlin.compiler.apiVersion>2.0</kotlin.compiler.apiVersion> From f604fd859a80150c0fb7615b4c2a23ab4bf7b0a3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 12 Oct 2024 10:32:43 +0000 Subject: [PATCH 088/260] Update dependency ch.qos.logback:logback-classic to v1.5.10 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d68c74ab0..301e22449 100644 --- a/pom.xml +++ b/pom.xml @@ -163,7 +163,7 @@ <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> - <version>1.5.9</version> + <version>1.5.10</version> <scope>test</scope> </dependency> <dependency> From 528dfe627eae11add14e1520903976746c42300f Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Sun, 13 Oct 2024 16:10:27 -0400 Subject: [PATCH 089/260] Refactor Spring Batch support for more flexibility The prior support was limited to limit and offset queries. --- .../dynamic/sql/render/RenderingContext.java | 12 ++++ .../dynamic/sql/render/RenderingStrategy.java | 12 ++++ .../render/FetchFirstPagingModelRenderer.java | 24 ++++---- .../LimitAndOffsetPagingModelRenderer.java | 18 +++--- .../SpringBatchCursorReaderSelectModel.java | 32 ---------- ...tchPagingItemReaderRenderingStrategy.java} | 27 ++++++--- .../SpringBatchPagingReaderSelectModel.java | 59 ------------------- .../SpringBatchProviderAdapter.java | 6 +- .../util/springbatch/SpringBatchUtility.java | 49 +++++++-------- .../CursorReaderBatchConfiguration.java | 6 +- .../PagingReaderBatchConfiguration.java | 7 ++- 11 files changed, 94 insertions(+), 158 deletions(-) delete mode 100644 src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchCursorReaderSelectModel.java rename src/main/java/org/mybatis/dynamic/sql/util/springbatch/{SpringBatchReaderRenderingStrategy.java => SpringBatchPagingItemReaderRenderingStrategy.java} (54%) delete mode 100644 src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingReaderSelectModel.java diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java b/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java index bc953f847..6eb15615c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java @@ -66,6 +66,18 @@ private <T> String renderedPlaceHolder(String mapKey, BindableColumn<T> column) .getFormattedJdbcPlaceholder(column, calculatedParameterName, mapKey); } + public RenderedParameterInfo calculateLimitParameterInfo() { + String mapKey = renderingStrategy.formatParameterMapKeyForLimit(sequence); + return new RenderedParameterInfo(mapKey, + renderingStrategy.getFormattedJdbcPlaceholderForLimitOrOffset(calculatedParameterName, mapKey)); + } + + public RenderedParameterInfo calculateOffsetParameterInfo() { + String mapKey = renderingStrategy.formatParameterMapKeyForOffset(sequence); + return new RenderedParameterInfo(mapKey, + renderingStrategy.getFormattedJdbcPlaceholderForLimitOrOffset(calculatedParameterName, mapKey)); + } + public RenderedParameterInfo calculateParameterInfo() { String mapKey = nextMapKey(); return new RenderedParameterInfo(mapKey, renderedPlaceHolder(mapKey)); diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java b/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java index 70b369c73..5924f356c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java @@ -40,6 +40,14 @@ public String formatParameterMapKey(AtomicInteger sequence) { return "p" + sequence.getAndIncrement(); //$NON-NLS-1$ } + public String formatParameterMapKeyForLimit(AtomicInteger sequence) { + return formatParameterMapKey(sequence); + } + + public String formatParameterMapKeyForOffset(AtomicInteger sequence) { + return formatParameterMapKey(sequence); + } + /** * This method generates a binding for a parameter to a placeholder in a generated SQL statement. * @@ -78,6 +86,10 @@ public String formatParameterMapKey(AtomicInteger sequence) { */ public abstract String getFormattedJdbcPlaceholder(String prefix, String parameterName); + public String getFormattedJdbcPlaceholderForLimitOrOffset(String prefix, String parameterName) { + return getFormattedJdbcPlaceholder(prefix, parameterName); + } + /** * This method generates a binding for a parameter to a placeholder in a row based insert statement. * diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/FetchFirstPagingModelRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/FetchFirstPagingModelRenderer.java index fcd62264b..82b61cdf7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/FetchFirstPagingModelRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/FetchFirstPagingModelRenderer.java @@ -51,30 +51,30 @@ private FragmentAndParameters renderFetchFirstRowsOnly() { } private FragmentAndParameters renderFetchFirstRowsOnly(Long fetchFirstRows) { - RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo(); + RenderedParameterInfo limitParameterInfo = renderingContext.calculateLimitParameterInfo(); return FragmentAndParameters - .withFragment("fetch first " + parameterInfo.renderedPlaceHolder() //$NON-NLS-1$ + .withFragment("fetch first " + limitParameterInfo.renderedPlaceHolder() //$NON-NLS-1$ + " rows only") //$NON-NLS-1$ - .withParameter(parameterInfo.parameterMapKey(), fetchFirstRows) + .withParameter(limitParameterInfo.parameterMapKey(), fetchFirstRows) .build(); } private FragmentAndParameters renderOffsetOnly(Long offset) { - RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo(); - return FragmentAndParameters.withFragment("offset " + parameterInfo.renderedPlaceHolder() //$NON-NLS-1$ + RenderedParameterInfo offsetParameterInfo = renderingContext.calculateOffsetParameterInfo(); + return FragmentAndParameters.withFragment("offset " + offsetParameterInfo.renderedPlaceHolder() //$NON-NLS-1$ + " rows") //$NON-NLS-1$ - .withParameter(parameterInfo.parameterMapKey(), offset) + .withParameter(offsetParameterInfo.parameterMapKey(), offset) .build(); } private FragmentAndParameters renderOffsetAndFetchFirstRows(Long offset, Long fetchFirstRows) { - RenderedParameterInfo parameterInfo1 = renderingContext.calculateParameterInfo(); - RenderedParameterInfo parameterInfo2 = renderingContext.calculateParameterInfo(); - return FragmentAndParameters.withFragment("offset " + parameterInfo1.renderedPlaceHolder() //$NON-NLS-1$ - + " rows fetch first " + parameterInfo2.renderedPlaceHolder() //$NON-NLS-1$ + RenderedParameterInfo offsetParameterInfo = renderingContext.calculateOffsetParameterInfo(); + RenderedParameterInfo limitParameterInfo = renderingContext.calculateParameterInfo(); + return FragmentAndParameters.withFragment("offset " + offsetParameterInfo.renderedPlaceHolder() //$NON-NLS-1$ + + " rows fetch first " + limitParameterInfo.renderedPlaceHolder() //$NON-NLS-1$ + " rows only") //$NON-NLS-1$ - .withParameter(parameterInfo1.parameterMapKey(), offset) - .withParameter(parameterInfo2.parameterMapKey(), fetchFirstRows) + .withParameter(offsetParameterInfo.parameterMapKey(), offset) + .withParameter(limitParameterInfo.parameterMapKey(), fetchFirstRows) .build(); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/LimitAndOffsetPagingModelRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/LimitAndOffsetPagingModelRenderer.java index 008c5a1af..609f4816a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/LimitAndOffsetPagingModelRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/LimitAndOffsetPagingModelRenderer.java @@ -40,19 +40,19 @@ public FragmentAndParameters render() { } private FragmentAndParameters renderLimitOnly() { - RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo(); - return FragmentAndParameters.withFragment("limit " + parameterInfo.renderedPlaceHolder()) //$NON-NLS-1$ - .withParameter(parameterInfo.parameterMapKey(), limit) + RenderedParameterInfo limitParameterInfo = renderingContext.calculateLimitParameterInfo(); + return FragmentAndParameters.withFragment("limit " + limitParameterInfo.renderedPlaceHolder()) //$NON-NLS-1$ + .withParameter(limitParameterInfo.parameterMapKey(), limit) .build(); } private FragmentAndParameters renderLimitAndOffset(Long offset) { - RenderedParameterInfo parameterInfo1 = renderingContext.calculateParameterInfo(); - RenderedParameterInfo parameterInfo2 = renderingContext.calculateParameterInfo(); - return FragmentAndParameters.withFragment("limit " + parameterInfo1.renderedPlaceHolder() //$NON-NLS-1$ - + " offset " + parameterInfo2.renderedPlaceHolder()) //$NON-NLS-1$ - .withParameter(parameterInfo1.parameterMapKey(), limit) - .withParameter(parameterInfo2.parameterMapKey(), offset) + RenderedParameterInfo limitParameterInfo = renderingContext.calculateLimitParameterInfo(); + RenderedParameterInfo offsetParameterInfo = renderingContext.calculateOffsetParameterInfo(); + return FragmentAndParameters.withFragment("limit " + limitParameterInfo.renderedPlaceHolder() //$NON-NLS-1$ + + " offset " + offsetParameterInfo.renderedPlaceHolder()) //$NON-NLS-1$ + .withParameter(limitParameterInfo.parameterMapKey(), limit) + .withParameter(offsetParameterInfo.parameterMapKey(), offset) .build(); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchCursorReaderSelectModel.java b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchCursorReaderSelectModel.java deleted file mode 100644 index 5486b31de..000000000 --- a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchCursorReaderSelectModel.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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.util.springbatch; - -import org.mybatis.dynamic.sql.select.SelectModel; -import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; - -public class SpringBatchCursorReaderSelectModel { - - private final SelectModel selectModel; - - public SpringBatchCursorReaderSelectModel(SelectModel selectModel) { - this.selectModel = selectModel; - } - - public SelectStatementProvider render() { - return selectModel.render(SpringBatchUtility.SPRING_BATCH_READER_RENDERING_STRATEGY); - } -} diff --git a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchReaderRenderingStrategy.java b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java similarity index 54% rename from src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchReaderRenderingStrategy.java rename to src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java index 48b1b9b8c..566a78bcd 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchReaderRenderingStrategy.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java @@ -15,20 +15,31 @@ */ package org.mybatis.dynamic.sql.util.springbatch; -import org.mybatis.dynamic.sql.BindableColumn; +import java.util.concurrent.atomic.AtomicInteger; + import org.mybatis.dynamic.sql.render.MyBatis3RenderingStrategy; /** - * This rendering strategy should be used for MyBatis3 statements using one of the - * Spring batch readers supplied by mybatis-spring integration (http://www.mybatis.org/spring/). - * Those readers are MyBatisPagingItemReader and MyBatisCursorItemReader. + * This rendering strategy should be used for MyBatis3 statements using the + * MyBatisPagingItemReader supplied by mybatis-spring integration (http://www.mybatis.org/spring/). * */ -public class SpringBatchReaderRenderingStrategy extends MyBatis3RenderingStrategy { +public class SpringBatchPagingItemReaderRenderingStrategy extends MyBatis3RenderingStrategy { + + @Override + public String getFormattedJdbcPlaceholderForLimitOrOffset(String prefix, String parameterName) { + return "#{" //$NON-NLS-1$ + + parameterName + + "}"; //$NON-NLS-1$ + } + + @Override + public String formatParameterMapKeyForLimit(AtomicInteger sequence) { + return "_pagesize"; //$NON-NLS-1$ + } @Override - public String getFormattedJdbcPlaceholder(BindableColumn<?> column, String prefix, String parameterName) { - String newPrefix = SpringBatchUtility.PARAMETER_KEY + "." + prefix; //$NON-NLS-1$ - return super.getFormattedJdbcPlaceholder(column, newPrefix, parameterName); + public String formatParameterMapKeyForOffset(AtomicInteger sequence) { + return "_skiprows"; //$NON-NLS-1$ } } diff --git a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingReaderSelectModel.java b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingReaderSelectModel.java deleted file mode 100644 index 648d71218..000000000 --- a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingReaderSelectModel.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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.util.springbatch; - -import java.util.HashMap; -import java.util.Map; - -import org.mybatis.dynamic.sql.select.SelectModel; -import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; - -public class SpringBatchPagingReaderSelectModel { - - private final SelectModel selectModel; - - public SpringBatchPagingReaderSelectModel(SelectModel selectModel) { - this.selectModel = selectModel; - } - - public SelectStatementProvider render() { - SelectStatementProvider selectStatement = - selectModel.render(SpringBatchUtility.SPRING_BATCH_READER_RENDERING_STRATEGY); - return new LimitAndOffsetDecorator(selectStatement); - } - - public static class LimitAndOffsetDecorator implements SelectStatementProvider { - private final Map<String, Object> parameters = new HashMap<>(); - private final String selectStatement; - - public LimitAndOffsetDecorator(SelectStatementProvider delegate) { - parameters.putAll(delegate.getParameters()); - - selectStatement = delegate.getSelectStatement() - + " LIMIT #{_pagesize} OFFSET #{_skiprows}"; //$NON-NLS-1$ - } - - @Override - public Map<String, Object> getParameters() { - return parameters; - } - - @Override - public String getSelectStatement() { - return selectStatement; - } - } -} diff --git a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchProviderAdapter.java b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchProviderAdapter.java index f212a0d04..ce75697cd 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchProviderAdapter.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchProviderAdapter.java @@ -17,13 +17,9 @@ import java.util.Map; -import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; - public class SpringBatchProviderAdapter { public String select(Map<String, Object> parameterValues) { - SelectStatementProvider selectStatement = - (SelectStatementProvider) parameterValues.get(SpringBatchUtility.PARAMETER_KEY); - return selectStatement.getSelectStatement(); + return (String) parameterValues.get(SpringBatchUtility.PARAMETER_KEY); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchUtility.java b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchUtility.java index 63b64429a..1155da806 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchUtility.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchUtility.java @@ -18,48 +18,39 @@ import java.util.HashMap; import java.util.Map; -import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.render.RenderingStrategy; -import org.mybatis.dynamic.sql.select.QueryExpressionDSL; -import org.mybatis.dynamic.sql.select.SelectDSL; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; public class SpringBatchUtility { private SpringBatchUtility() {} - public static final String PARAMETER_KEY = "mybatis3_dsql_query"; //$NON-NLS-1$ - - public static final RenderingStrategy SPRING_BATCH_READER_RENDERING_STRATEGY = - new SpringBatchReaderRenderingStrategy(); - - public static Map<String, Object> toParameterValues(SelectStatementProvider selectStatement) { - Map<String, Object> parameterValues = new HashMap<>(); - parameterValues.put(PARAMETER_KEY, selectStatement); - return parameterValues; - } + static final String PARAMETER_KEY = "mybatis3_dsql_query"; //$NON-NLS-1$ /** - * Select builder that renders in a manner appropriate for the MyBatisPagingItemReader. - * - * <p><b>Important</b> rendered SQL will contain LIMIT and OFFSET clauses in the SELECT statement. If your database - * (Oracle) does not support LIMIT and OFFSET, the queries will fail. + * Constant for use in a query intended for use with the MyBatisPagingItemReader. + * This value will not be used in the query at runtime because MyBatis Spring integration + * will supply a value for _skiprows. * - * @param selectList a column list for the SELECT statement - * @return FromGatherer used to continue a SELECT statement + * <p>See <a href="https://mybatis.org/spring/batch.html">https://mybatis.org/spring/batch.html</a> for details. */ - public static QueryExpressionDSL.FromGatherer<SpringBatchPagingReaderSelectModel> selectForPaging( - BasicColumn... selectList) { - return SelectDSL.select(SpringBatchPagingReaderSelectModel::new, selectList); - } + public static final long MYBATIS_SPRING_BATCH_SKIPROWS = -437L; /** - * Select builder that renders in a manner appropriate for the MyBatisCursorItemReader. + * Constant for use in a query intended for use with the MyBatisPagingItemReader. + * This value will not be used in the query at runtime because MyBatis Spring integration + * will supply a value for _pagesize. * - * @param selectList a column list for the SELECT statement - * @return FromGatherer used to continue a SELECT statement + * <p>See <a href="https://mybatis.org/spring/batch.html">https://mybatis.org/spring/batch.html</a> for details. */ - public static QueryExpressionDSL.FromGatherer<SpringBatchCursorReaderSelectModel> selectForCursor( - BasicColumn... selectList) { - return SelectDSL.select(SpringBatchCursorReaderSelectModel::new, selectList); + public static final long MYBATIS_SPRING_BATCH_PAGESIZE = -439L; + + public static final RenderingStrategy SPRING_BATCH_PAGING_ITEM_READER_RENDERING_STRATEGY = + new SpringBatchPagingItemReaderRenderingStrategy(); + + public static Map<String, Object> toParameterValues(SelectStatementProvider selectStatement) { + Map<String, Object> parameterValues = new HashMap<>(); + parameterValues.put(PARAMETER_KEY, selectStatement.getSelectStatement()); + parameterValues.put("parameters", selectStatement.getParameters()); //$NON-NLS-1$ + return parameterValues; } } diff --git a/src/test/java/examples/springbatch/cursor/CursorReaderBatchConfiguration.java b/src/test/java/examples/springbatch/cursor/CursorReaderBatchConfiguration.java index 823f1c631..838fe9d41 100644 --- a/src/test/java/examples/springbatch/cursor/CursorReaderBatchConfiguration.java +++ b/src/test/java/examples/springbatch/cursor/CursorReaderBatchConfiguration.java @@ -18,10 +18,12 @@ import static examples.springbatch.mapper.PersonDynamicSqlSupport.lastName; import static examples.springbatch.mapper.PersonDynamicSqlSupport.person; import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo; +import static org.mybatis.dynamic.sql.SqlBuilder.select; import javax.sql.DataSource; import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.dynamic.sql.render.RenderingStrategies; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider; import org.mybatis.dynamic.sql.util.springbatch.SpringBatchUtility; @@ -89,11 +91,11 @@ public PlatformTransactionManager transactionManager(DataSource dataSource) { @Bean public MyBatisCursorItemReader<PersonRecord> reader(SqlSessionFactory sqlSessionFactory) { - SelectStatementProvider selectStatement = SpringBatchUtility.selectForCursor(person.allColumns()) + SelectStatementProvider selectStatement = select(person.allColumns()) .from(person) .where(lastName, isEqualTo("flintstone")) .build() - .render(); + .render(RenderingStrategies.MYBATIS3); MyBatisCursorItemReader<PersonRecord> reader = new MyBatisCursorItemReader<>(); reader.setQueryId(PersonMapper.class.getName() + ".selectMany"); diff --git a/src/test/java/examples/springbatch/paging/PagingReaderBatchConfiguration.java b/src/test/java/examples/springbatch/paging/PagingReaderBatchConfiguration.java index 41353ab35..2fa74c862 100644 --- a/src/test/java/examples/springbatch/paging/PagingReaderBatchConfiguration.java +++ b/src/test/java/examples/springbatch/paging/PagingReaderBatchConfiguration.java @@ -17,6 +17,7 @@ import static examples.springbatch.mapper.PersonDynamicSqlSupport.*; import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo; +import static org.mybatis.dynamic.sql.SqlBuilder.select; import javax.sql.DataSource; @@ -88,12 +89,14 @@ public PlatformTransactionManager transactionManager(DataSource dataSource) { @Bean public MyBatisPagingItemReader<PersonRecord> reader(SqlSessionFactory sqlSessionFactory) { - SelectStatementProvider selectStatement = SpringBatchUtility.selectForPaging(person.allColumns()) + SelectStatementProvider selectStatement = select(person.allColumns()) .from(person) .where(forPagingTest, isEqualTo(true)) .orderBy(id) + .limit(SpringBatchUtility.MYBATIS_SPRING_BATCH_PAGESIZE) + .offset(SpringBatchUtility.MYBATIS_SPRING_BATCH_SKIPROWS) .build() - .render(); + .render(SpringBatchUtility.SPRING_BATCH_PAGING_ITEM_READER_RENDERING_STRATEGY); MyBatisPagingItemReader<PersonRecord> reader = new MyBatisPagingItemReader<>(); reader.setQueryId(PersonMapper.class.getName() + ".selectMany"); From 8214313b936c759f2b009c2dfaed6e623bd011ff Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Sun, 13 Oct 2024 16:26:49 -0400 Subject: [PATCH 090/260] Fix documentation link --- .../SpringBatchPagingItemReaderRenderingStrategy.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java index 566a78bcd..d45d56c0e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java @@ -21,8 +21,8 @@ /** * This rendering strategy should be used for MyBatis3 statements using the - * MyBatisPagingItemReader supplied by mybatis-spring integration (http://www.mybatis.org/spring/). - * + * MyBatisPagingItemReader supplied by mybatis-spring integration + * (<a href="http://www.mybatis.org/spring/">http://www.mybatis.org/spring/</a>). */ public class SpringBatchPagingItemReaderRenderingStrategy extends MyBatis3RenderingStrategy { From e6859feac052a6093e8bf9feea905882ec9173dc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Oct 2024 11:50:41 +0000 Subject: [PATCH 091/260] Update dependency ch.qos.logback:logback-classic to v1.5.11 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 301e22449..e29318619 100644 --- a/pom.xml +++ b/pom.xml @@ -163,7 +163,7 @@ <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> - <version>1.5.10</version> + <version>1.5.11</version> <scope>test</scope> </dependency> <dependency> From 86104fb8320de830b0b698e742d2d245d281e727 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 15 Oct 2024 09:55:51 -0400 Subject: [PATCH 092/260] Update test container versions --- src/test/java/config/TestContainersConfiguration.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/config/TestContainersConfiguration.java b/src/test/java/config/TestContainersConfiguration.java index ed2c95c96..fc6607dbb 100644 --- a/src/test/java/config/TestContainersConfiguration.java +++ b/src/test/java/config/TestContainersConfiguration.java @@ -21,6 +21,6 @@ * Utility interface to hold Docker image tags for the test containers we use */ public interface TestContainersConfiguration { - DockerImageName POSTGRES_LATEST = DockerImageName.parse("postgres:16.3"); - DockerImageName MARIADB_LATEST = DockerImageName.parse("mariadb:11.4.2"); + DockerImageName POSTGRES_LATEST = DockerImageName.parse("postgres:17.0"); + DockerImageName MARIADB_LATEST = DockerImageName.parse("mariadb:11.5.2"); } From e41a1129e66a78e692204436d86d538847628ffa Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 15 Oct 2024 14:38:12 -0400 Subject: [PATCH 093/260] Improve Javadocs --- .../sql/util/springbatch/SpringBatchUtility.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchUtility.java b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchUtility.java index 1155da806..01cae8964 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchUtility.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchUtility.java @@ -31,6 +31,9 @@ private SpringBatchUtility() {} * This value will not be used in the query at runtime because MyBatis Spring integration * will supply a value for _skiprows. * + * <p>This value can be used as a parameter for the "offset" method in a query to make the intention + * clear that the actual runtime value will be supplied by MyBatis Spring integration. + * * <p>See <a href="https://mybatis.org/spring/batch.html">https://mybatis.org/spring/batch.html</a> for details. */ public static final long MYBATIS_SPRING_BATCH_SKIPROWS = -437L; @@ -40,6 +43,9 @@ private SpringBatchUtility() {} * This value will not be used in the query at runtime because MyBatis Spring integration * will supply a value for _pagesize. * + * <p>This value can be used as a parameter for the "limit" or "fetchFirst" method in a query to make the intention + * clear that the actual runtime value will be supplied by MyBatis Spring integration. + * * <p>See <a href="https://mybatis.org/spring/batch.html">https://mybatis.org/spring/batch.html</a> for details. */ public static final long MYBATIS_SPRING_BATCH_PAGESIZE = -439L; @@ -48,9 +54,9 @@ private SpringBatchUtility() {} new SpringBatchPagingItemReaderRenderingStrategy(); public static Map<String, Object> toParameterValues(SelectStatementProvider selectStatement) { - Map<String, Object> parameterValues = new HashMap<>(); + var parameterValues = new HashMap<String, Object>(); parameterValues.put(PARAMETER_KEY, selectStatement.getSelectStatement()); - parameterValues.put("parameters", selectStatement.getParameters()); //$NON-NLS-1$ + parameterValues.put(RenderingStrategy.DEFAULT_PARAMETER_PREFIX, selectStatement.getParameters()); return parameterValues; } } From e262018aecbca866561f7c78faf9dc9f07ed328a Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 16 Oct 2024 13:33:55 -0400 Subject: [PATCH 094/260] Improve Javadocs --- .../dynamic/sql/render/RenderingStrategy.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java b/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java index 5924f356c..afc588a7a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java @@ -36,14 +36,38 @@ public abstract class RenderingStrategy { public static final String DEFAULT_PARAMETER_PREFIX = "parameters"; //$NON-NLS-1$ + /** + * Return a unique key that can be used to place a parameter value in the parameter map + * + * @param sequence a sequence for calculating a unique value + * @return a key used to place the parameter value in the parameter map + */ public String formatParameterMapKey(AtomicInteger sequence) { return "p" + sequence.getAndIncrement(); //$NON-NLS-1$ } + /** + * Return a parameter map key intended as a parameter for a limit or fetch first query. + * + * <p>By default, this parameter is treated the same as any other. This method is a hook to support + * MyBatis Spring Batch. + * + * @param sequence a sequence for calculating a unique value + * @return a key used to place the parameter value in the parameter map + */ public String formatParameterMapKeyForLimit(AtomicInteger sequence) { return formatParameterMapKey(sequence); } + /** + * Return a parameter map key intended as a parameter for a query offset. + * + * <p>By default, this parameter is treated the same as any other. This method is a hook to support + * MyBatis Spring Batch. + * + * @param sequence a sequence for calculating a unique value + * @return a key used to place the parameter value in the parameter map + */ public String formatParameterMapKeyForOffset(AtomicInteger sequence) { return formatParameterMapKey(sequence); } @@ -86,6 +110,19 @@ public String formatParameterMapKeyForOffset(AtomicInteger sequence) { */ public abstract String getFormattedJdbcPlaceholder(String prefix, String parameterName); + /** + * This method generates a binding for a parameter to a placeholder in a generated SQL statement. + * + * <p>This method is used to generate bindings for limit, offset, and fetch first parameters. By default, these + * parameters are treated the same as any other. This method supports MyBatis Spring Batch integration where the + * parameter keys have predefined values and need special handling. + * + * @param prefix parameter prefix used for locating the parameters in a SQL provider object. Typically, will be + * {@link RenderingStrategy#DEFAULT_PARAMETER_PREFIX}. This is ignored for Spring. + * @param parameterName name of the parameter. Typically generated by calling + * {@link RenderingStrategy#formatParameterMapKey(AtomicInteger)} + * @return the generated binding + */ public String getFormattedJdbcPlaceholderForLimitOrOffset(String prefix, String parameterName) { return getFormattedJdbcPlaceholder(prefix, parameterName); } From 4e8bf745f2fe257537b60305e304975a52889fcd Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 16 Oct 2024 13:34:18 -0400 Subject: [PATCH 095/260] Use new limit method for delete and update statements --- .../org/mybatis/dynamic/sql/delete/render/DeleteRenderer.java | 2 +- .../org/mybatis/dynamic/sql/update/render/UpdateRenderer.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 8a9c945d4..fa4cd0d28 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 @@ -84,7 +84,7 @@ private Optional<FragmentAndParameters> calculateLimitClause() { } private FragmentAndParameters renderLimitClause(Long limit) { - RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo(); + RenderedParameterInfo parameterInfo = renderingContext.calculateLimitParameterInfo(); return FragmentAndParameters.withFragment("limit " + parameterInfo.renderedPlaceHolder()) //$NON-NLS-1$ .withParameter(parameterInfo.parameterMapKey(), limit) 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 f11662c02..352c1de7a 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 @@ -109,7 +109,7 @@ private Optional<FragmentAndParameters> calculateLimitClause() { } private FragmentAndParameters renderLimitClause(Long limit) { - RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo(); + RenderedParameterInfo parameterInfo = renderingContext.calculateLimitParameterInfo(); return FragmentAndParameters.withFragment("limit " + parameterInfo.renderedPlaceHolder()) //$NON-NLS-1$ .withParameter(parameterInfo.parameterMapKey(), limit) From 4bb5fdc6b7dd33fad46f9a14e1e918dfdeefc293 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 17 Oct 2024 10:26:02 +0000 Subject: [PATCH 096/260] Update dependency org.springframework:spring-jdbc to v6.1.14 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e29318619..20c63a9ec 100644 --- a/pom.xml +++ b/pom.xml @@ -94,7 +94,7 @@ <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> - <version>6.1.13</version> + <version>6.1.14</version> <scope>provided</scope> <optional>true</optional> </dependency> From ce2943fa45c0d90ff7e63f14fde0a288d52f2a56 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 15:41:07 +0000 Subject: [PATCH 097/260] Update junit5 monorepo to v5.11.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 20c63a9ec..6312edf6d 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ <properties> <java.version>17</java.version> <java.release.version>17</java.release.version> - <junit.jupiter.version>5.11.2</junit.jupiter.version> + <junit.jupiter.version>5.11.3</junit.jupiter.version> <spring.batch.version>5.1.2</spring.batch.version> <checkstyle.config>checkstyle-override.xml</checkstyle.config> From dbd94e8ee9a8092cb015ac6483d46afeabb9e78c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 01:54:29 +0000 Subject: [PATCH 098/260] Update testcontainers-java monorepo to v1.20.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6312edf6d..b49e7f205 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,7 @@ <sonar.tests>src/test/java,src/test/kotlin</sonar.tests> <kotlin.code.style>official</kotlin.code.style> - <test.containers.version>1.20.2</test.containers.version> + <test.containers.version>1.20.3</test.containers.version> <osgi.export>org.mybatis.dynamic.sql.*;version=${project.version};-noimport:=true</osgi.export> <!-- Reproducible Builds --> From 3ade4fe06c7626799a10cf97ae7b42ed5c53f819 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 23 Oct 2024 16:37:32 -0400 Subject: [PATCH 099/260] Documentation --- CHANGELOG.md | 4 + src/site/markdown/docs/springBatch.md | 180 ++++++++++++++++---------- 2 files changed, 116 insertions(+), 68 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d46635fb..9a61b8b89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ worked to make these changes as minimal as possible. **Potentially Breaking Changes:** +- If you use this library with MyBatis' Spring Batch integration, you will need to make changes as we have + refactored that support to be more flexible. Please see the + [Spring Batch](https://mybatis.org/mybatis-dynamic-sql/docs/springBatch.html) documentation page to see the new usage + details. - If you have created any custom implementations of `SortSpecification`, you will need to update those implementations due to a new rendering strategy for ORDER BY phrases. The old methods `isDescending` and `orderByName` are removed in favor of a new method `renderForOrderBy` diff --git a/src/site/markdown/docs/springBatch.md b/src/site/markdown/docs/springBatch.md index 4b1855a97..1c5bfda66 100644 --- a/src/site/markdown/docs/springBatch.md +++ b/src/site/markdown/docs/springBatch.md @@ -1,100 +1,144 @@ # Spring Batch Support This library provides some utilities to make it easier to interact with the MyBatis Spring Batch support. -## The Problem +MyBatis Spring provides support for interacting with Spring Batch (see +[http://www.mybatis.org/spring/batch.html](http://www.mybatis.org/spring/batch.html)). This support consists of +specialized implementations of Spring Batch's `ItemReader` and `ItemWriter` interfaces that have support for MyBatis +mappers. -MyBatis Spring support provides utility classes for interacting with Spring Batch (see [http://www.mybatis.org/spring/batch.html](http://www.mybatis.org/spring/batch.html)). These classes are specialized implementations of Spring Batch's `ItemReader` and `ItemWriter` interfaces that have support for MyBatis mappers. +The `ItemWriter` implementation works with SQL generated by MyBatis Dynamic SQL with no modification needed. -The `ItemWriter` implementations work with SQL generated by MyBatis Dynamic SQL with no modification needed. +The `ItemReader` implementations need special care. Those classes assume that all query parameters will be placed in a +Map (as per usual when using multiple parameters in a query). MyBatis Dynamic SQL, by default, builds a parameter +object that is intended to be the only parameter for a query. The library contains utilities for overcoming this +difficulty. -The `ItemReader` implementations need special care. Those classes assume that all query parameters will be placed in a Map (as per usual when using multiple parameters in a query). MyBatis Dynamic SQL, by default, builds a parameter object that should be the only parameter in a query and will not work when placed in a Map of parameters. +## Using MyBatisCursorItemReader -## The Solution +The `MyBatisCursorItemReader` class works with built-in support for cursor based queries in MyBatis. Queries of this +type will read row by row and MyBatis will convert each result row to a result object without having to read the entire +result set into memory. The normal rendering for MyBatis will work for queries using this reader, but special care +must be taken to prepare the parameter values for use with this reader. See the following example: -The solution involves these steps: - -1. The SQL must be rendered such that the parameter markers are aware of the enclosing parameter Map in the `ItemReader` -1. The `SelectStatementProvider` must be placed in the `ItemReader` parameter Map with a known key. -1. The `@SelectProvider` must be configured to be aware of the enclosing parameter Map - -MyBatis Dynamic SQL provides utilities for each of these requirements. Each utility uses a shared Map key for consistency. - -## Spring Batch Item Readers - -MyBatis Spring support supplies two implementations of the `ItemReader` interface: - -1. `org.mybatis.spring.batch.MyBatisCursorItemReader` - for queries that can be efficiently processed through a single select statement and a cursor -1. `org.mybatis.spring.batch.MyBatisPagingItemReader` - for queries that should be processed as a series of paged selects. Note that MyBatis does not provide any native support for paged queries - it is up to the user to write SQL for paging. The `MyBatisPagingItemWriter` simply makes properties available that specify which page should be read currently. - -MyBatis Dynamic SQL supplies specialized select statements that will render properly for the different implementations of `ItemReader`: - -1. `SpringBatchUtility.selectForCursor(...)` will create a select statement that is appropriate for the `MyBatisCursorItemReader` - a single select statement that will be read with a cursor -1. `SpringBatchUtility.selectForPaging(...)` will create a select statement that is appropriate for the `MyBatisPagingItemReader` - a select statement that will be called multiple times - one for each page as configured on the batch job. - -**Very Important:** The paging implementation will only work for databases that support limit and offset in select statements. Fortunately, most databases do support this - with the notable exception of Oracle. - - -### Rendering for Cursor +```java +@Bean +public MyBatisCursorItemReader<PersonRecord> reader(SqlSessionFactory sqlSessionFactory) { + SelectStatementProvider selectStatement = select(person.allColumns()) + .from(person) + .where(lastName, isEqualTo("flintstone")) + .build() + .render(RenderingStrategies.MYBATIS3); + + MyBatisCursorItemReader<PersonRecord> reader = new MyBatisCursorItemReader<>(); + reader.setQueryId(PersonMapper.class.getName() + ".selectMany"); + reader.setSqlSessionFactory(sqlSessionFactory); + reader.setParameterValues(SpringBatchUtility.toParameterValues(selectStatement)); + return reader; +} +``` -Queries intended for the `MyBatisCursorItemReader` should be rendered as follows: +Note the use of `SpringBatchUtility.toParameterValues(...)`. This utility will set up the parameter Map correctly for the +rendered statement, and for use with a library supplied `@selectProvider`. See the following for an example of the mapper +method used for the query coded above: ```java - SelectStatementProvider selectStatement = SpringBatchUtility.selectForCursor(person.allColumns()) - .from(person) - .where(lastName, isEqualTo("flintstone")) - .build() - .render(); // renders for MyBatisCursorItemReader +@Mapper +public interface PersonMapper { + + @SelectProvider(type=SpringBatchProviderAdapter.class, method="select") + @Results({ + @Result(column="id", property="id", id=true), + @Result(column="first_name", property="firstName"), + @Result(column="last_name", property="lastName") + }) + List<PersonRecord> selectMany(Map<String, Object> parameterValues); +} ``` -### Rendering for Paging +Note the use of the `SpringBatchProviderAdapter` - that adapter knows how to retrieve the rendered queries from the +parameter map initialed in the method above. -Queries intended for the `MyBatisPagingItemReader` should be rendered as follows: +### Migrating from 1.x Support for MyBatisCursorItemReader + +In version 1.x, the library supplied a special utility for creating a select statement as follows: ```java - SelectStatementProvider selectStatement = SpringBatchUtility.selectForPaging(person.allColumns()) - .from(person) - .where(lastName, isEqualTo("flintstone")) - .build() - .render(); // renders for MyBatisPagingItemReader +SelectStatementProvider selectStatement = SpringBatchUtility.selectForCursor(person.allColumns()) + .from(person) + .where(lastName, isEqualTo("flintstone")) + .build() + .render(); ``` -## Creating the Parameter Map +That utility method was limited in capability. The new method allows the full capabilities of the library. To migrate, +follow these steps: -The `SpringBatchUtility` provides a method to create the parameter values Map needed by the MyBatis Spring `ItemReader` implementations. It can be used as follows: +1. Replace `SpringBatchUtility.selectForCursor(...)` with `SqlBuilder.select(...)` +2. Replace `render()` with `render(RenderingStrategies.MYBATIS3)` -For cursor based queries... +## Using MyBatisPagingItemReader -```java - MyBatisCursorItemReader<Person> reader = new MyBatisCursorItemReader<>(); - reader.setQueryId(PersonMapper.class.getName() + ".selectMany"); - reader.setSqlSessionFactory(sqlSessionFactory); - reader.setParameterValues(SpringBatchUtility.toParameterValues(selectStatement)); // create parameter map -``` -For paging based queries... +The `MyBatisPagingItemReader` class works with paging queries - queries that read rows in pages and process page by page +rather than row by row. The normal rendering for MyBatis will work NOT for queries using this reader because MyBatis +Spring support supplies specially named parameters for page size, offset, etc. So the query must be rendered properly +to respond to these parameter values that are supplied at runtime. As with the other reader, special care +must also be taken to prepare the parameter values for use with this reader. See the following example: ```java - MyBatisPagingItemReader<Person> reader = new MyBatisPagingItemReader<>(); - reader.setQueryId(PersonMapper.class.getName() + ".selectMany"); - reader.setSqlSessionFactory(sqlSessionFactory); - reader.setPageSize(7); - reader.setParameterValues(SpringBatchUtility.toParameterValues(selectStatement)); // create parameter map +@Bean +public MyBatisPagingItemReader<PersonRecord> reader(SqlSessionFactory sqlSessionFactory) { + SelectStatementProvider selectStatement = select(person.allColumns()) + .from(person) + .where(forPagingTest, isEqualTo(true)) + .orderBy(id) + .limit(SpringBatchUtility.MYBATIS_SPRING_BATCH_PAGESIZE) + .offset(SpringBatchUtility.MYBATIS_SPRING_BATCH_SKIPROWS) + .build() + .render(SpringBatchUtility.SPRING_BATCH_PAGING_ITEM_READER_RENDERING_STRATEGY); + + MyBatisPagingItemReader<PersonRecord> reader = new MyBatisPagingItemReader<>(); + reader.setQueryId(PersonMapper.class.getName() + ".selectMany"); + reader.setSqlSessionFactory(sqlSessionFactory); + reader.setParameterValues(SpringBatchUtility.toParameterValues(selectStatement)); + reader.setPageSize(7); + return reader; +} ``` +Notice the following important items: +1. The `limit` and `offset` methods in the query are used to set up paging support in the query. With MyBatis Spring + batch support, the integration library will supply values for those parameters at runtime. Any values you code in the + select statement will be ignored - only the values supplied by the library will be used. We supply two constants + to make this clearer: `MYBATIS_SPRING_BATCH_PAGESIZE` and `MYBATIS_SPRING_BATCH_SKIPROWS`. You can use these values + to make the code clearer, but again the values will be ignored at runtime. +2. The query must be rendered with the `SPRING_BATCH_PAGING_ITEM_READER_RENDERING_STRATEGY` rendering strategy. This + rendering strategy will render the query so that it will respond properly to the runtime values supplied for page size + and skip rows. -## Specialized @SelectProvider Adapter +### Migrating from 1.x Support for MyBatisPagingItemReader -MyBatis mapper methods should be configured to use the specialized `@SelectProvider` adapter as follows: +In version 1.x, the library supplied a special utility for creating a select statement as follows: ```java - @SelectProvider(type=SpringBatchProviderAdapter.class, method="select") // use the Spring batch adapter - @Results({ - @Result(column="id", property="id", id=true), - @Result(column="first_name", property="firstName"), - @Result(column="last_name", property="lastName") - }) - List<Person> selectMany(Map<String, Object> parameterValues); +SelectStatementProvider selectStatement = SpringBatchUtility.selectForPaging(person.allColumns()) + .from(person) + .where(forPagingTest, isEqualTo(true)) + .orderBy(id) + .build() + .render(); ``` -## Complete Example +That utility method was very limited in capability. It only supported limit and offset based queries - which are not +supported in all databases. The new method allows the full capabilities of the library. To migrate, +follow these steps: + +1. Replace `SpringBatchUtility.selectForPaging(...)` with `SqlBuilder.select(...)` +2. Add `limit()`, `fetchFirst()`, and `offset()` method calls as appropriate for your query and database +3. Replace `render()` with `render(RenderingStrategies.SPRING_BATCH_PAGING_ITEM_READER_RENDERING_STRATEGY)` + + +## Complete Examples -The unit tests for MyBatis Dynamic SQL include a complete example of using MyBatis Spring Batch support using the MyBatis supplied reader as well as both types of MyBatis supplied writers. You can see the full example here: [https://github.com/mybatis/mybatis-dynamic-sql/tree/master/src/test/java/examples/springbatch](https://github.com/mybatis/mybatis-dynamic-sql/tree/master/src/test/java/examples/springbatch) +The unit tests for MyBatis Dynamic SQL include a complete example of using MyBatis Spring Batch support using the +MyBatis supplied reader as well as both types of MyBatis supplied writers. You can see the full example +here: [https://github.com/mybatis/mybatis-dynamic-sql/tree/master/src/test/java/examples/springbatch](https://github.com/mybatis/mybatis-dynamic-sql/tree/master/src/test/java/examples/springbatch) From d4005a757e49d554d95692b73e841bf9f6145ec6 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 23 Oct 2024 17:51:58 -0400 Subject: [PATCH 100/260] Coverage --- pom.xml | 2 + .../dynamic/sql/render/RenderingContext.java | 19 +++--- .../dynamic/sql/render/RenderingStrategy.java | 19 +++++- .../render/FetchFirstPagingModelRenderer.java | 12 ++-- ...atchPagingItemReaderRenderingStrategy.java | 2 +- src/site/markdown/docs/springBatch.md | 2 +- .../examples/simple/MyBatisMapToRowTest.java | 1 - .../springbatch/SpringBatchRenderingTest.java | 65 +++++++++++++++++++ 8 files changed, 99 insertions(+), 23 deletions(-) create mode 100644 src/test/java/examples/springbatch/SpringBatchRenderingTest.java diff --git a/pom.xml b/pom.xml index 991746894..772950c2b 100644 --- a/pom.xml +++ b/pom.xml @@ -58,6 +58,8 @@ <properties> <java.version>17</java.version> <java.release.version>17</java.release.version> + <java.test.version>17</java.test.version> + <java.test.release.version>17</java.test.release.version> <junit.jupiter.version>5.11.1</junit.jupiter.version> <spring.batch.version>5.1.2</spring.batch.version> diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java b/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java index 6eb15615c..553ecd090 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java @@ -57,30 +57,27 @@ private String nextMapKey() { return renderingStrategy.formatParameterMapKey(sequence); } - private String renderedPlaceHolder(String mapKey) { - return renderingStrategy.getFormattedJdbcPlaceholder(calculatedParameterName, mapKey); - } - private <T> String renderedPlaceHolder(String mapKey, BindableColumn<T> column) { return column.renderingStrategy().orElse(renderingStrategy) .getFormattedJdbcPlaceholder(column, calculatedParameterName, mapKey); } + public RenderedParameterInfo calculateFetchFirstRowsParameterInfo() { + String mapKey = renderingStrategy.formatParameterMapKeyForFetchFirstRows(sequence); + return new RenderedParameterInfo(mapKey, + renderingStrategy.getFormattedJdbcPlaceholderForPagingParameters(calculatedParameterName, mapKey)); + } + public RenderedParameterInfo calculateLimitParameterInfo() { String mapKey = renderingStrategy.formatParameterMapKeyForLimit(sequence); return new RenderedParameterInfo(mapKey, - renderingStrategy.getFormattedJdbcPlaceholderForLimitOrOffset(calculatedParameterName, mapKey)); + renderingStrategy.getFormattedJdbcPlaceholderForPagingParameters(calculatedParameterName, mapKey)); } public RenderedParameterInfo calculateOffsetParameterInfo() { String mapKey = renderingStrategy.formatParameterMapKeyForOffset(sequence); return new RenderedParameterInfo(mapKey, - renderingStrategy.getFormattedJdbcPlaceholderForLimitOrOffset(calculatedParameterName, mapKey)); - } - - public RenderedParameterInfo calculateParameterInfo() { - String mapKey = nextMapKey(); - return new RenderedParameterInfo(mapKey, renderedPlaceHolder(mapKey)); + renderingStrategy.getFormattedJdbcPlaceholderForPagingParameters(calculatedParameterName, mapKey)); } public <T> RenderedParameterInfo calculateParameterInfo(BindableColumn<T> column) { diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java b/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java index afc588a7a..969a5e094 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java @@ -37,7 +37,7 @@ public abstract class RenderingStrategy { public static final String DEFAULT_PARAMETER_PREFIX = "parameters"; //$NON-NLS-1$ /** - * Return a unique key that can be used to place a parameter value in the parameter map + * Generate a unique key that can be used to place a parameter value in the parameter map * * @param sequence a sequence for calculating a unique value * @return a key used to place the parameter value in the parameter map @@ -47,7 +47,20 @@ public String formatParameterMapKey(AtomicInteger sequence) { } /** - * Return a parameter map key intended as a parameter for a limit or fetch first query. + * Return a parameter map key intended as a parameter for a fetch first query. + * + * <p>By default, this parameter is treated the same as any other. This method is a hook to support + * MyBatis Spring Batch. + * + * @param sequence a sequence for calculating a unique value + * @return a key used to place the parameter value in the parameter map + */ + public String formatParameterMapKeyForFetchFirstRows(AtomicInteger sequence) { + return formatParameterMapKeyForLimit(sequence); + } + + /** + * Return a parameter map key intended as a parameter for a limit query. * * <p>By default, this parameter is treated the same as any other. This method is a hook to support * MyBatis Spring Batch. @@ -123,7 +136,7 @@ public String formatParameterMapKeyForOffset(AtomicInteger sequence) { * {@link RenderingStrategy#formatParameterMapKey(AtomicInteger)} * @return the generated binding */ - public String getFormattedJdbcPlaceholderForLimitOrOffset(String prefix, String parameterName) { + public String getFormattedJdbcPlaceholderForPagingParameters(String prefix, String parameterName) { return getFormattedJdbcPlaceholder(prefix, parameterName); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/FetchFirstPagingModelRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/FetchFirstPagingModelRenderer.java index 82b61cdf7..0ad493620 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/FetchFirstPagingModelRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/FetchFirstPagingModelRenderer.java @@ -51,11 +51,11 @@ private FragmentAndParameters renderFetchFirstRowsOnly() { } private FragmentAndParameters renderFetchFirstRowsOnly(Long fetchFirstRows) { - RenderedParameterInfo limitParameterInfo = renderingContext.calculateLimitParameterInfo(); + RenderedParameterInfo fetchFirstParameterInfo = renderingContext.calculateFetchFirstRowsParameterInfo(); return FragmentAndParameters - .withFragment("fetch first " + limitParameterInfo.renderedPlaceHolder() //$NON-NLS-1$ + .withFragment("fetch first " + fetchFirstParameterInfo.renderedPlaceHolder() //$NON-NLS-1$ + " rows only") //$NON-NLS-1$ - .withParameter(limitParameterInfo.parameterMapKey(), fetchFirstRows) + .withParameter(fetchFirstParameterInfo.parameterMapKey(), fetchFirstRows) .build(); } @@ -69,12 +69,12 @@ private FragmentAndParameters renderOffsetOnly(Long offset) { private FragmentAndParameters renderOffsetAndFetchFirstRows(Long offset, Long fetchFirstRows) { RenderedParameterInfo offsetParameterInfo = renderingContext.calculateOffsetParameterInfo(); - RenderedParameterInfo limitParameterInfo = renderingContext.calculateParameterInfo(); + RenderedParameterInfo fetchFirstParameterInfo = renderingContext.calculateFetchFirstRowsParameterInfo(); return FragmentAndParameters.withFragment("offset " + offsetParameterInfo.renderedPlaceHolder() //$NON-NLS-1$ - + " rows fetch first " + limitParameterInfo.renderedPlaceHolder() //$NON-NLS-1$ + + " rows fetch first " + fetchFirstParameterInfo.renderedPlaceHolder() //$NON-NLS-1$ + " rows only") //$NON-NLS-1$ .withParameter(offsetParameterInfo.parameterMapKey(), offset) - .withParameter(limitParameterInfo.parameterMapKey(), fetchFirstRows) + .withParameter(fetchFirstParameterInfo.parameterMapKey(), fetchFirstRows) .build(); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java index d45d56c0e..791e89bfc 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java @@ -27,7 +27,7 @@ public class SpringBatchPagingItemReaderRenderingStrategy extends MyBatis3RenderingStrategy { @Override - public String getFormattedJdbcPlaceholderForLimitOrOffset(String prefix, String parameterName) { + public String getFormattedJdbcPlaceholderForPagingParameters(String prefix, String parameterName) { return "#{" //$NON-NLS-1$ + parameterName + "}"; //$NON-NLS-1$ diff --git a/src/site/markdown/docs/springBatch.md b/src/site/markdown/docs/springBatch.md index 1c5bfda66..11ec90d6d 100644 --- a/src/site/markdown/docs/springBatch.md +++ b/src/site/markdown/docs/springBatch.md @@ -85,7 +85,7 @@ to respond to these parameter values that are supplied at runtime. As with the o must also be taken to prepare the parameter values for use with this reader. See the following example: ```java -@Bean +@Bean public MyBatisPagingItemReader<PersonRecord> reader(SqlSessionFactory sqlSessionFactory) { SelectStatementProvider selectStatement = select(person.allColumns()) .from(person) diff --git a/src/test/java/examples/simple/MyBatisMapToRowTest.java b/src/test/java/examples/simple/MyBatisMapToRowTest.java index 2b6f714b2..a542d36f6 100644 --- a/src/test/java/examples/simple/MyBatisMapToRowTest.java +++ b/src/test/java/examples/simple/MyBatisMapToRowTest.java @@ -28,7 +28,6 @@ import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DriverManager; -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.IntStream; diff --git a/src/test/java/examples/springbatch/SpringBatchRenderingTest.java b/src/test/java/examples/springbatch/SpringBatchRenderingTest.java new file mode 100644 index 000000000..48873b375 --- /dev/null +++ b/src/test/java/examples/springbatch/SpringBatchRenderingTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2016-2024 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 + * + * https://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.springbatch; + +import static examples.springbatch.mapper.PersonDynamicSqlSupport.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mybatis.dynamic.sql.SqlBuilder.isLike; +import static org.mybatis.dynamic.sql.SqlBuilder.select; + +import org.junit.jupiter.api.Test; +import org.mybatis.dynamic.sql.util.springbatch.SpringBatchUtility; + +class SpringBatchRenderingTest { + + @Test + void renderLimit() { + var selectStatement = select(person.allColumns()) + .from(person) + .where(firstName, isLike("%f%")) + .limit(SpringBatchUtility.MYBATIS_SPRING_BATCH_PAGESIZE) + .offset(SpringBatchUtility.MYBATIS_SPRING_BATCH_SKIPROWS) + .build() + .render(SpringBatchUtility.SPRING_BATCH_PAGING_ITEM_READER_RENDERING_STRATEGY); + + assertThat(selectStatement.getSelectStatement()) + .isEqualTo(""" + select * \ + from person \ + where first_name like #{parameters.p1,jdbcType=VARCHAR} \ + limit #{_pagesize} \ + offset #{_skiprows}"""); + } + + @Test + void renderFetchFirst() { + var selectStatement = select(person.allColumns()) + .from(person) + .where(firstName, isLike("%f%")) + .offset(SpringBatchUtility.MYBATIS_SPRING_BATCH_SKIPROWS) + .fetchFirst(SpringBatchUtility.MYBATIS_SPRING_BATCH_PAGESIZE).rowsOnly() + .build() + .render(SpringBatchUtility.SPRING_BATCH_PAGING_ITEM_READER_RENDERING_STRATEGY); + + assertThat(selectStatement.getSelectStatement()) + .isEqualTo(""" + select * \ + from person \ + where first_name like #{parameters.p1,jdbcType=VARCHAR} \ + offset #{_skiprows} rows \ + fetch first #{_pagesize} rows only"""); + } +} From adc2931b74bc9d67c6f25d058b0b8c4a24eb3803 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 24 Oct 2024 11:08:54 -0400 Subject: [PATCH 101/260] Better pattern for fetch first --- .../org/mybatis/dynamic/sql/render/RenderingStrategy.java | 2 +- .../SpringBatchPagingItemReaderRenderingStrategy.java | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java b/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java index 969a5e094..fb10ea99b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java @@ -56,7 +56,7 @@ public String formatParameterMapKey(AtomicInteger sequence) { * @return a key used to place the parameter value in the parameter map */ public String formatParameterMapKeyForFetchFirstRows(AtomicInteger sequence) { - return formatParameterMapKeyForLimit(sequence); + return formatParameterMapKey(sequence); } /** diff --git a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java index 791e89bfc..c87c4a03e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java @@ -33,6 +33,11 @@ public String getFormattedJdbcPlaceholderForPagingParameters(String prefix, Stri + "}"; //$NON-NLS-1$ } + @Override + public String formatParameterMapKeyForFetchFirstRows(AtomicInteger sequence) { + return "_pagesize"; //$NON-NLS-1$ + } + @Override public String formatParameterMapKeyForLimit(AtomicInteger sequence) { return "_pagesize"; //$NON-NLS-1$ From cfb47bce398b6592851be7b0cb4a2568a72c2e30 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 24 Oct 2024 11:31:47 -0400 Subject: [PATCH 102/260] Doc updates --- .../dynamic/sql/render/RenderingStrategy.java | 2 +- src/site/markdown/docs/springBatch.md | 30 +++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java b/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java index fb10ea99b..6beb7bc24 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java @@ -37,7 +37,7 @@ public abstract class RenderingStrategy { public static final String DEFAULT_PARAMETER_PREFIX = "parameters"; //$NON-NLS-1$ /** - * Generate a unique key that can be used to place a parameter value in the parameter map + * Generate a unique key that can be used to place a parameter value in the parameter map. * * @param sequence a sequence for calculating a unique value * @return a key used to place the parameter value in the parameter map diff --git a/src/site/markdown/docs/springBatch.md b/src/site/markdown/docs/springBatch.md index 11ec90d6d..aca011c39 100644 --- a/src/site/markdown/docs/springBatch.md +++ b/src/site/markdown/docs/springBatch.md @@ -70,8 +70,8 @@ SelectStatementProvider selectStatement = SpringBatchUtility.selectForCursor(pe .render(); ``` -That utility method was limited in capability. The new method allows the full capabilities of the library. To migrate, -follow these steps: +That utility method was limited in capability and has been removed. The new method described above allows the full +capabilities of the library. To migrate, follow these steps: 1. Replace `SpringBatchUtility.selectForCursor(...)` with `SqlBuilder.select(...)` 2. Replace `render()` with `render(RenderingStrategies.MYBATIS3)` @@ -114,6 +114,26 @@ Notice the following important items: 2. The query must be rendered with the `SPRING_BATCH_PAGING_ITEM_READER_RENDERING_STRATEGY` rendering strategy. This rendering strategy will render the query so that it will respond properly to the runtime values supplied for page size and skip rows. +3. Note the use of `SpringBatchUtility.toParameterValues(...)`. This utility will set up the parameter Map correctly for + the rendered statement, and for use with a library supplied `@selectProvider`. See the following for an example of + the mapper method used for the query coded above: + +```java +@Mapper +public interface PersonMapper { + + @SelectProvider(type=SpringBatchProviderAdapter.class, method="select") + @Results({ + @Result(column="id", property="id", id=true), + @Result(column="first_name", property="firstName"), + @Result(column="last_name", property="lastName") + }) + List<PersonRecord> selectMany(Map<String, Object> parameterValues); +} +``` + +Note the use of the `SpringBatchProviderAdapter` - that adapter knows how to retrieve the rendered queries from the +parameter map initialed in the method above. ### Migrating from 1.x Support for MyBatisPagingItemReader @@ -128,9 +148,9 @@ SelectStatementProvider selectStatement = SpringBatchUtility.selectForPaging(pe .render(); ``` -That utility method was very limited in capability. It only supported limit and offset based queries - which are not -supported in all databases. The new method allows the full capabilities of the library. To migrate, -follow these steps: +That utility method was very limited in capability and has been removed. The prior method only supported limit and +offset based queries - which are not supported in all databases. The new method described above allows the full +capabilities of the library to be used. To migrate, follow these steps: 1. Replace `SpringBatchUtility.selectForPaging(...)` with `SqlBuilder.select(...)` 2. Add `limit()`, `fetchFirst()`, and `offset()` method calls as appropriate for your query and database From 7e0c665d8ff25f50e15c2bbd039c6c06738d1b17 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 24 Oct 2024 16:51:48 -0400 Subject: [PATCH 103/260] Remove many deprecated method calls --- .../examples/emptywhere/EmptyWhereTest.java | 4 +- .../java/examples/groupby/GroupByTest.java | 10 +- .../java/examples/joins/JoinMapperTest.java | 112 +- .../java/examples/joins/JoinSubQueryTest.java | 29 +- .../joins/NewSyntaxJoinMapperTest.java | 1270 ----------------- .../simple/PersonWithAddressMapper.java | 6 +- .../examples/spring/PersonTemplateTest.java | 12 +- .../java/issues/gh100/FromJoinWhereTest.java | 264 ++-- .../gh100/Issue100StartAfterJoinTest.java | 14 +- src/test/java/issues/gh100/Issue100Test.java | 20 +- .../PersonWithAddressMapperExtensions.kt | 12 +- .../mybatis3/general/GeneralKotlinTest.kt | 12 +- ...perTest.kt => DeprecatedJoinMapperTest.kt} | 284 +--- ...CanonicalSpringKotlinTemplateDirectTest.kt | 4 +- .../canonical/CanonicalSpringKotlinTest.kt | 4 +- 15 files changed, 257 insertions(+), 1800 deletions(-) delete mode 100644 src/test/java/examples/joins/NewSyntaxJoinMapperTest.java rename src/test/kotlin/examples/kotlin/mybatis3/joins/{JoinMapperTest.kt => DeprecatedJoinMapperTest.kt} (66%) diff --git a/src/test/java/examples/emptywhere/EmptyWhereTest.java b/src/test/java/examples/emptywhere/EmptyWhereTest.java index 8b3fdc546..eca321cd9 100644 --- a/src/test/java/examples/emptywhere/EmptyWhereTest.java +++ b/src/test/java/examples/emptywhere/EmptyWhereTest.java @@ -170,7 +170,7 @@ void testJoinThreeConditions() { String lName = "Flintstone"; QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder = select(id, firstName, PersonDynamicSqlSupport.lastName, orderDate) - .from(person).join(order).on(person.id, equalTo(order.personId)) + .from(person).join(order).on(person.id, isEqualTo(order.personId)) .where(id, isEqualTo(3)); builder.and(firstName, isEqualTo(fName).filter(Objects::nonNull)); @@ -192,7 +192,7 @@ void testJoinThreeConditions() { @MethodSource("joinWhereVariations") void testJoinVariations(Variation variation) { QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder = select(id, firstName, PersonDynamicSqlSupport.lastName, orderDate) - .from(person).join(order).on(person.id, equalTo(order.personId)) + .from(person).join(order).on(person.id, isEqualTo(order.personId)) .where(); builder.and(firstName, isEqualTo(variation.firstName).filter(Objects::nonNull)); diff --git a/src/test/java/examples/groupby/GroupByTest.java b/src/test/java/examples/groupby/GroupByTest.java index 0a5ce6645..793fe2429 100644 --- a/src/test/java/examples/groupby/GroupByTest.java +++ b/src/test/java/examples/groupby/GroupByTest.java @@ -126,7 +126,7 @@ void testGroupByAfterJoin() { CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); SelectStatementProvider selectStatement = select(lastName, streetAddress, count().as("count")) - .from(person, "p").join(address, "a").on(person.addressId, equalTo(address.id)) + .from(person, "p").join(address, "a").on(person.addressId, isEqualTo(address.id)) .groupBy(lastName, streetAddress) .build() .render(RenderingStrategies.MYBATIS3); @@ -156,10 +156,10 @@ void testUnionAfterJoin() { CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); SelectStatementProvider selectStatement = select(lastName, firstName, streetAddress) - .from(person, "p").join(address, "a").on(person.addressId, equalTo(address.id)) + .from(person, "p").join(address, "a").on(person.addressId, isEqualTo(address.id)) .union() .select(person2.lastName, person2.firstName, streetAddress) - .from(person2, "p").join(address, "a").on(person2.addressId, equalTo(address.id)) + .from(person2, "p").join(address, "a").on(person2.addressId, isEqualTo(address.id)) .orderBy(lastName, firstName) .build() .render(RenderingStrategies.MYBATIS3); @@ -192,10 +192,10 @@ void testUnionAllAfterJoin() { CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); SelectStatementProvider selectStatement = select(lastName, firstName, streetAddress) - .from(person, "p").join(address, "a").on(person.addressId, equalTo(address.id)) + .from(person, "p").join(address, "a").on(person.addressId, isEqualTo(address.id)) .unionAll() .select(person2.lastName, person2.firstName, streetAddress) - .from(person2, "p").join(address, "a").on(person2.addressId, equalTo(address.id)) + .from(person2, "p").join(address, "a").on(person2.addressId, isEqualTo(address.id)) .orderBy(lastName, firstName) .build() .render(RenderingStrategies.MYBATIS3); diff --git a/src/test/java/examples/joins/JoinMapperTest.java b/src/test/java/examples/joins/JoinMapperTest.java index 50c8e30f5..1b22697e1 100644 --- a/src/test/java/examples/joins/JoinMapperTest.java +++ b/src/test/java/examples/joins/JoinMapperTest.java @@ -83,7 +83,7 @@ void testSingleTableJoin1() { SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) .from(orderMaster, "om") - .join(orderDetail, "od").on(orderMaster.orderId, equalTo(orderDetail.orderId)) + .join(orderDetail, "od").on(orderMaster.orderId, isEqualTo(orderDetail.orderId)) .build() .render(RenderingStrategies.MYBATIS3); @@ -117,7 +117,7 @@ void testSingleTableJoin2() { SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) .from(orderMaster, "om") - .join(orderDetail, "od", on(orderMaster.orderId, equalTo(orderDetail.orderId))) + .join(orderDetail, "od", on(orderMaster.orderId, isEqualTo(orderDetail.orderId))) .build() .render(RenderingStrategies.MYBATIS3); @@ -149,7 +149,7 @@ void testCompoundJoin1() { // this is a nonsensical join, but it does test the "and" capability SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) .from(orderMaster, "om") - .join(orderDetail, "od").on(orderMaster.orderId, equalTo(orderDetail.orderId), and(orderMaster.orderId, equalTo(orderDetail.orderId))) + .join(orderDetail, "od").on(orderMaster.orderId, isEqualTo(orderDetail.orderId), and(orderMaster.orderId, isEqualTo(orderDetail.orderId))) .build() .render(RenderingStrategies.MYBATIS3); @@ -163,9 +163,9 @@ void testCompoundJoin2() { // this is a nonsensical join, but it does test the "and" capability SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) .from(orderMaster, "om") - .join(orderDetail, "od").on(orderMaster.orderId, equalTo(orderDetail.orderId)) + .join(orderDetail, "od").on(orderMaster.orderId, isEqualTo(orderDetail.orderId)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) - .and(orderMaster.orderId, equalTo(orderDetail.orderId)) + .and(orderMaster.orderId, isEqualTo(orderDetail.orderId)) .build() .render(RenderingStrategies.MYBATIS3); @@ -179,7 +179,7 @@ void testCompoundJoin3() { // this is a nonsensical join, but it does test the "and" capability SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) .from(orderMaster, "om") - .join(orderDetail, "od", on(orderMaster.orderId, equalTo(orderDetail.orderId)), and(orderMaster.orderId, equalTo(orderDetail.orderId))) + .join(orderDetail, "od", on(orderMaster.orderId, isEqualTo(orderDetail.orderId)), and(orderMaster.orderId, isEqualTo(orderDetail.orderId))) .build() .render(RenderingStrategies.MYBATIS3); @@ -193,7 +193,7 @@ void testCompoundJoin4() { // this is a nonsensical join, but it does test the "and" capability SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) .from(orderMaster, "om") - .leftJoin(orderDetail, "od", on(orderMaster.orderId, equalTo(orderDetail.orderId)), and(orderMaster.orderId, equalTo(orderDetail.orderId))) + .leftJoin(orderDetail, "od", on(orderMaster.orderId, isEqualTo(orderDetail.orderId)), and(orderMaster.orderId, isEqualTo(orderDetail.orderId))) .build() .render(RenderingStrategies.MYBATIS3); @@ -207,7 +207,7 @@ void testCompoundJoin5() { // this is a nonsensical join, but it does test the "and" capability SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) .from(orderMaster, "om") - .rightJoin(orderDetail, "od", on(orderMaster.orderId, equalTo(orderDetail.orderId)), and(orderMaster.orderId, equalTo(orderDetail.orderId))) + .rightJoin(orderDetail, "od", on(orderMaster.orderId, isEqualTo(orderDetail.orderId)), and(orderMaster.orderId, isEqualTo(orderDetail.orderId))) .build() .render(RenderingStrategies.MYBATIS3); @@ -221,7 +221,7 @@ void testCompoundJoin6() { // this is a nonsensical join, but it does test the "and" capability SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) .from(orderMaster, "om") - .fullJoin(orderDetail, "od", on(orderMaster.orderId, equalTo(orderDetail.orderId)), and(orderMaster.orderId, equalTo(orderDetail.orderId))) + .fullJoin(orderDetail, "od", on(orderMaster.orderId, isEqualTo(orderDetail.orderId)), and(orderMaster.orderId, isEqualTo(orderDetail.orderId))) .build() .render(RenderingStrategies.MYBATIS3); @@ -237,8 +237,8 @@ void testMultipleTableJoinWithWhereClause() { SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, equalTo(orderLine.orderId)) - .join(itemMaster, "im").on(orderLine.itemId, equalTo(itemMaster.itemId)) + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .join(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .where(orderMaster.orderId, isEqualTo(2)) .build() .render(RenderingStrategies.MYBATIS3); @@ -268,8 +268,8 @@ void testMultipleTableJoinWithApplyWhere() { SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, equalTo(orderLine.orderId)) - .join(itemMaster, "im").on(orderLine.itemId, equalTo(itemMaster.itemId)) + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .join(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .applyWhere(where(orderMaster.orderId, isEqualTo(2)).toWhereApplier()) .build() .render(RenderingStrategies.MYBATIS3); @@ -299,8 +299,8 @@ void testMultipleTableJoinWithComplexWhereClause() { SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, equalTo(orderLine.orderId)) - .join(itemMaster, "im").on(orderLine.itemId, equalTo(itemMaster.itemId)) + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .join(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .where(orderMaster.orderId, isEqualTo(2), and(orderLine.lineNumber, isEqualTo(2))) .build() .render(RenderingStrategies.MYBATIS3); @@ -328,8 +328,8 @@ void testMultipleTableJoinWithOrderBy() { SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, equalTo(orderLine.orderId)) - .join(itemMaster, "im").on(orderLine.itemId, equalTo(itemMaster.itemId)) + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .join(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .orderBy(orderMaster.orderId) .build() .render(RenderingStrategies.MYBATIS3); @@ -365,8 +365,8 @@ void testMultipleTableJoinNoAliasWithOrderBy() { SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) .from(orderMaster) - .join(orderLine).on(orderMaster.orderId, equalTo(orderLine.orderId)) - .join(itemMaster).on(orderLine.itemId, equalTo(itemMaster.itemId)) + .join(orderLine).on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .join(itemMaster).on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .where(orderMaster.orderId, isEqualTo(2)) .orderBy(orderMaster.orderId) .build() @@ -398,7 +398,7 @@ void testRightJoin() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(orderLine, "ol") - .rightJoin(itemMaster, "im").on(orderLine.itemId, equalTo(itemMaster.itemId)) + .rightJoin(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .orderBy(itemMaster.itemId) .build() .render(RenderingStrategies.MYBATIS3); @@ -432,8 +432,8 @@ void testRightJoin2() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, equalTo(orderLine.orderId)) - .rightJoin(itemMaster, "im").on(orderLine.itemId, equalTo(itemMaster.itemId)) + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .rightJoin(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .orderBy(orderLine.orderId, itemMaster.itemId) .build() .render(RenderingStrategies.MYBATIS3); @@ -468,8 +468,8 @@ void testRightJoin3() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(orderMaster, "om") - .join(orderLine, "ol", on(orderMaster.orderId, equalTo(orderLine.orderId))) - .rightJoin(itemMaster, "im", on(orderLine.itemId, equalTo(itemMaster.itemId))) + .join(orderLine, "ol", on(orderMaster.orderId, isEqualTo(orderLine.orderId))) + .rightJoin(itemMaster, "im", on(orderLine.itemId, isEqualTo(itemMaster.itemId))) .orderBy(orderLine.orderId, itemMaster.itemId) .build() .render(RenderingStrategies.MYBATIS3); @@ -504,8 +504,8 @@ void testRightJoinNoAliases() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(orderMaster) - .join(orderLine).on(orderMaster.orderId, equalTo(orderLine.orderId)) - .rightJoin(itemMaster).on(orderLine.itemId, equalTo(itemMaster.itemId)) + .join(orderLine).on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .rightJoin(itemMaster).on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .orderBy(orderLine.orderId, itemMaster.itemId) .build() .render(RenderingStrategies.MYBATIS3); @@ -540,7 +540,7 @@ void testLeftJoin() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(itemMaster, "im") - .leftJoin(orderLine, "ol").on(orderLine.itemId, equalTo(itemMaster.itemId)) + .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .orderBy(itemMaster.itemId) .build() .render(RenderingStrategies.MYBATIS3); @@ -574,8 +574,8 @@ void testLeftJoin2() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, equalTo(orderLine.orderId)) - .leftJoin(itemMaster, "im").on(orderLine.itemId, equalTo(itemMaster.itemId)) + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .leftJoin(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .orderBy(orderLine.orderId, itemMaster.itemId) .build() .render(RenderingStrategies.MYBATIS3); @@ -610,8 +610,8 @@ void testLeftJoin3() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(orderMaster, "om") - .join(orderLine, "ol", on(orderMaster.orderId, equalTo(orderLine.orderId))) - .leftJoin(itemMaster, "im", on(orderLine.itemId, equalTo(itemMaster.itemId))) + .join(orderLine, "ol", on(orderMaster.orderId, isEqualTo(orderLine.orderId))) + .leftJoin(itemMaster, "im", on(orderLine.itemId, isEqualTo(itemMaster.itemId))) .orderBy(orderLine.orderId, itemMaster.itemId) .build() .render(RenderingStrategies.MYBATIS3); @@ -646,8 +646,8 @@ void testLeftJoinNoAliases() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(orderMaster) - .join(orderLine).on(orderMaster.orderId, equalTo(orderLine.orderId)) - .leftJoin(itemMaster).on(orderLine.itemId, equalTo(itemMaster.itemId)) + .join(orderLine).on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .leftJoin(itemMaster).on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .orderBy(orderLine.orderId, itemMaster.itemId) .build() .render(RenderingStrategies.MYBATIS3); @@ -682,7 +682,7 @@ void testFullJoin() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, orderLine.itemId.as("ol_itemid"), itemMaster.itemId.as("im_itemid"), itemMaster.description) .from(itemMaster, "im") - .fullJoin(orderLine, "ol").on(itemMaster.itemId, equalTo(orderLine.itemId)) + .fullJoin(orderLine, "ol").on(itemMaster.itemId, isEqualTo(orderLine.itemId)) .orderBy(orderLine.orderId, sortColumn("im_itemid")) .build() .render(RenderingStrategies.MYBATIS3); @@ -723,8 +723,8 @@ void testFullJoin2() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, equalTo(orderLine.orderId)) - .fullJoin(itemMaster, "im").on(orderLine.itemId, equalTo(itemMaster.itemId)) + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .fullJoin(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .orderBy(orderLine.orderId, itemMaster.itemId) .build() .render(RenderingStrategies.MYBATIS3); @@ -765,8 +765,8 @@ void testFullJoin3() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(orderMaster, "om") - .join(orderLine, "ol", on(orderMaster.orderId, equalTo(orderLine.orderId))) - .fullJoin(itemMaster, "im", on(orderLine.itemId, equalTo(itemMaster.itemId))) + .join(orderLine, "ol", on(orderMaster.orderId, isEqualTo(orderLine.orderId))) + .fullJoin(itemMaster, "im", on(orderLine.itemId, isEqualTo(itemMaster.itemId))) .orderBy(orderLine.orderId, itemMaster.itemId) .build() .render(RenderingStrategies.MYBATIS3); @@ -807,8 +807,8 @@ void testFullJoin4() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.description) .from(orderMaster, "om") - .join(orderLine, "ol", on(orderMaster.orderId, equalTo(orderLine.orderId))) - .fullJoin(itemMaster, "im", on(orderLine.itemId, equalTo(itemMaster.itemId))) + .join(orderLine, "ol", on(orderMaster.orderId, isEqualTo(orderLine.orderId))) + .fullJoin(itemMaster, "im", on(orderLine.itemId, isEqualTo(itemMaster.itemId))) .orderBy(orderLine.orderId, sortColumn("im", itemMaster.itemId)) .build() .render(RenderingStrategies.MYBATIS3); @@ -846,8 +846,8 @@ void testFullJoin5() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.description) .from(orderMaster, "om") - .join(orderLine, "ol", on(orderMaster.orderId, equalTo(orderLine.orderId))) - .fullJoin(itemMaster, "im", on(orderLine.itemId, equalTo(itemMaster.itemId))) + .join(orderLine, "ol", on(orderMaster.orderId, isEqualTo(orderLine.orderId))) + .fullJoin(itemMaster, "im", on(orderLine.itemId, isEqualTo(itemMaster.itemId))) .orderBy(orderLine.orderId, sortColumn("im", itemMaster.itemId).descending()) .build() .render(RenderingStrategies.MYBATIS3); @@ -885,8 +885,8 @@ void testFullJoinNoAliases() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(orderMaster) - .join(orderLine).on(orderMaster.orderId, equalTo(orderLine.orderId)) - .fullJoin(itemMaster).on(orderLine.itemId, equalTo(itemMaster.itemId)) + .join(orderLine).on(orderMaster.orderId, isEqualTo(orderLine.orderId)) + .fullJoin(itemMaster).on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .orderBy(orderLine.orderId, itemMaster.itemId) .build() .render(RenderingStrategies.MYBATIS3); @@ -931,7 +931,7 @@ void testSelf() { // get Bamm Bamm's parent - should be Barney SelectStatementProvider selectStatement = select(user.userId, user.userName, user.parentId) .from(user, "u1") - .join(user2, "u2").on(user.userId, equalTo(user2.parentId)) + .join(user2, "u2").on(user.userId, isEqualTo(user2.parentId)) .where(user2.userId, isEqualTo(4)) .build() .render(RenderingStrategies.MYBATIS3); @@ -971,7 +971,7 @@ void testSelfWithNewAlias() { // get Bamm Bamm's parent - should be Barney SelectStatementProvider selectStatement = select(user.userId, user.userName, user.parentId) .from(user) - .join(user2).on(user.userId, equalTo(user2.parentId)) + .join(user2).on(user.userId, isEqualTo(user2.parentId)) .where(user2.userId, isEqualTo(4)) .build() .render(RenderingStrategies.MYBATIS3); @@ -1002,7 +1002,7 @@ void testSelfWithNewAliasAndOverride() { // get Bamm Bamm's parent - should be Barney SelectStatementProvider selectStatement = select(user.userId, user.userName, user.parentId) .from(user, "u1") - .join(user2, "u2").on(user.userId, equalTo(user2.parentId)) + .join(user2, "u2").on(user.userId, isEqualTo(user2.parentId)) .where(user2.userId, isEqualTo(4)) .build() .render(RenderingStrategies.MYBATIS3); @@ -1029,7 +1029,7 @@ void testLimitAndOffsetAfterJoin() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(itemMaster, "im") - .leftJoin(orderLine, "ol").on(orderLine.itemId, equalTo(itemMaster.itemId)) + .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .limit(2) .offset(1) .build() @@ -1064,7 +1064,7 @@ void testLimitOnlyAfterJoin() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(itemMaster, "im") - .leftJoin(orderLine, "ol").on(orderLine.itemId, equalTo(itemMaster.itemId)) + .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .limit(2) .build() .render(RenderingStrategies.MYBATIS3); @@ -1098,7 +1098,7 @@ void testOffsetOnlyAfterJoin() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(itemMaster, "im") - .leftJoin(orderLine, "ol").on(orderLine.itemId, equalTo(itemMaster.itemId)) + .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .offset(2) .build() .render(RenderingStrategies.MYBATIS3); @@ -1132,7 +1132,7 @@ void testOffsetAndFetchFirstAfterJoin() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(itemMaster, "im") - .leftJoin(orderLine, "ol").on(orderLine.itemId, equalTo(itemMaster.itemId)) + .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .offset(1) .fetchFirst(2).rowsOnly() .build() @@ -1167,7 +1167,7 @@ void testFetchFirstOnlyAfterJoin() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(itemMaster, "im") - .leftJoin(orderLine, "ol").on(orderLine.itemId, equalTo(itemMaster.itemId)) + .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) .fetchFirst(2).rowsOnly() .build() .render(RenderingStrategies.MYBATIS3); @@ -1201,8 +1201,8 @@ void testJoinWithParameterValue() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(itemMaster, "im") - .join(orderLine, "ol").on(orderLine.itemId, equalTo(itemMaster.itemId)) - .and(orderLine.orderId, equalTo(1)) + .join(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .and(orderLine.orderId, isEqualTo(1)) .build() .render(RenderingStrategies.MYBATIS3); @@ -1235,8 +1235,8 @@ void testJoinWithConstant() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) .from(itemMaster, "im") - .join(orderLine, "ol").on(orderLine.itemId, equalTo(itemMaster.itemId)) - .and(orderLine.orderId, equalTo(constant("1"))) + .join(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) + .and(orderLine.orderId, isEqualTo(constant("1"))) .build() .render(RenderingStrategies.MYBATIS3); diff --git a/src/test/java/examples/joins/JoinSubQueryTest.java b/src/test/java/examples/joins/JoinSubQueryTest.java index 588844828..1bda4983e 100644 --- a/src/test/java/examples/joins/JoinSubQueryTest.java +++ b/src/test/java/examples/joins/JoinSubQueryTest.java @@ -20,7 +20,6 @@ import static examples.joins.OrderLineDynamicSQLSupport.orderLine; import static examples.joins.OrderMasterDynamicSQLSupport.orderMaster; import static org.assertj.core.api.Assertions.assertThat; -import static org.mybatis.dynamic.sql.SqlBuilder.equalTo; import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo; import static org.mybatis.dynamic.sql.SqlBuilder.select; import static org.mybatis.dynamic.sql.SqlBuilder.sortColumn; @@ -82,7 +81,7 @@ void testSingleTableJoin1() { .from(orderMaster, "om") .join(select(orderDetail.orderId, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) .from(orderDetail), - "od").on(orderMaster.orderId, equalTo(orderDetail.orderId.qualifiedWith("od"))) + "od").on(orderMaster.orderId, isEqualTo(orderDetail.orderId.qualifiedWith("od"))) .build() .render(RenderingStrategies.MYBATIS3); @@ -121,11 +120,11 @@ void testMultipleTableJoinWithWhereClause() { .join(select(orderLine.orderId, orderLine.itemId, orderLine.quantity, orderLine.lineNumber) .from(orderLine), "ol") - .on(orderMaster.orderId, equalTo(orderLine.orderId.qualifiedWith("ol"))) + .on(orderMaster.orderId, isEqualTo(orderLine.orderId.qualifiedWith("ol"))) .join(select(itemMaster.itemId, itemMaster.description) .from(itemMaster), "im") - .on(orderLine.itemId.qualifiedWith("ol"), equalTo(itemMaster.itemId.qualifiedWith("im"))) + .on(orderLine.itemId.qualifiedWith("ol"), isEqualTo(itemMaster.itemId.qualifiedWith("im"))) .where(orderMaster.orderId, isEqualTo(2)) .build() .render(RenderingStrategies.MYBATIS3); @@ -158,9 +157,9 @@ void testMultipleTableJoinWithSelectStar() { SelectStatementProvider selectStatement = select(orderMaster.orderId, orderMaster.orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) .from(orderMaster, "om") .join(select(orderLine.allColumns()).from(orderLine), "ol") - .on(orderMaster.orderId, equalTo(orderLine.orderId.qualifiedWith("ol"))) + .on(orderMaster.orderId, isEqualTo(orderLine.orderId.qualifiedWith("ol"))) .join(select(itemMaster.allColumns()).from(itemMaster), "im") - .on(orderLine.itemId.qualifiedWith("ol"), equalTo(itemMaster.itemId.qualifiedWith("im"))) + .on(orderLine.itemId.qualifiedWith("ol"), isEqualTo(itemMaster.itemId.qualifiedWith("im"))) .where(orderMaster.orderId, isEqualTo(2)) .orderBy(orderMaster.orderId) .build() @@ -197,7 +196,7 @@ void testRightJoin() { itemMaster.itemId.qualifiedWith("im"), itemMaster.description) .from(orderLine, "ol") .rightJoin(select(itemMaster.allColumns()).from(itemMaster), "im") - .on(orderLine.itemId, equalTo(itemMaster.itemId.qualifiedWith("im"))) + .on(orderLine.itemId, isEqualTo(itemMaster.itemId.qualifiedWith("im"))) .orderBy(itemMaster.itemId) .build() .render(RenderingStrategies.MYBATIS3); @@ -232,9 +231,9 @@ void testRightJoin2() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId.qualifiedWith(("im")), itemMaster.description) .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, equalTo(orderLine.orderId)) + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) .rightJoin(select(itemMaster.allColumns()).from(itemMaster), "im") - .on(orderLine.itemId, equalTo(itemMaster.itemId.qualifiedWith("im"))) + .on(orderLine.itemId, isEqualTo(itemMaster.itemId.qualifiedWith("im"))) .orderBy(orderLine.orderId, itemMaster.itemId) .build() .render(RenderingStrategies.MYBATIS3); @@ -271,7 +270,7 @@ void testLeftJoin() { itemMaster.itemId.qualifiedWith("im"), itemMaster.description) .from(itemMaster, "im") .leftJoin(select(orderLine.allColumns()).from(orderLine), "ol") - .on(orderLine.itemId.qualifiedWith("ol"), equalTo(itemMaster.itemId)) + .on(orderLine.itemId.qualifiedWith("ol"), isEqualTo(itemMaster.itemId)) .orderBy(itemMaster.itemId) .build() .render(RenderingStrategies.MYBATIS3); @@ -307,9 +306,9 @@ void testLeftJoin2() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId.qualifiedWith("im"), itemMaster.description) .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, equalTo(orderLine.orderId)) + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) .leftJoin(select(itemMaster.allColumns()).from(itemMaster), "im") - .on(orderLine.itemId, equalTo(itemMaster.itemId.qualifiedWith("im"))) + .on(orderLine.itemId, isEqualTo(itemMaster.itemId.qualifiedWith("im"))) .orderBy(orderLine.orderId, itemMaster.itemId) .build() .render(RenderingStrategies.MYBATIS3); @@ -346,7 +345,7 @@ void testFullJoin() { orderLine.itemId.as("ol_itemid").qualifiedWith("ol"), itemMaster.itemId.as("im_itemid"), itemMaster.description) .from(itemMaster, "im") .fullJoin(select(orderLine.allColumns()).from(orderLine), "ol") - .on(itemMaster.itemId, equalTo(orderLine.itemId.qualifiedWith("ol"))) + .on(itemMaster.itemId, isEqualTo(orderLine.itemId.qualifiedWith("ol"))) .orderBy(orderLine.orderId, sortColumn("im_itemid")) .build() .render(RenderingStrategies.MYBATIS3); @@ -389,9 +388,9 @@ void testFullJoin2() { SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId.qualifiedWith("im"), itemMaster.description) .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, equalTo(orderLine.orderId)) + .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) .fullJoin(select(itemMaster.allColumns()).from(itemMaster), "im") - .on(orderLine.itemId, equalTo(itemMaster.itemId.qualifiedWith("im"))) + .on(orderLine.itemId, isEqualTo(itemMaster.itemId.qualifiedWith("im"))) .orderBy(orderLine.orderId, itemMaster.itemId) .build() .render(RenderingStrategies.MYBATIS3); diff --git a/src/test/java/examples/joins/NewSyntaxJoinMapperTest.java b/src/test/java/examples/joins/NewSyntaxJoinMapperTest.java deleted file mode 100644 index ae8f5d0f0..000000000 --- a/src/test/java/examples/joins/NewSyntaxJoinMapperTest.java +++ /dev/null @@ -1,1270 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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.joins; - -import org.apache.ibatis.datasource.unpooled.UnpooledDataSource; -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; -import org.mybatis.dynamic.sql.exception.DuplicateTableAliasException; -import org.mybatis.dynamic.sql.render.RenderingStrategies; -import org.mybatis.dynamic.sql.select.QueryExpressionDSL; -import org.mybatis.dynamic.sql.select.SelectModel; -import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; -import org.mybatis.dynamic.sql.util.Messages; -import org.mybatis.dynamic.sql.util.mybatis3.CommonSelectMapper; - -import java.io.InputStream; -import java.io.InputStreamReader; -import java.sql.Connection; -import java.sql.DriverManager; -import java.util.List; -import java.util.Map; - -import static examples.joins.ItemMasterDynamicSQLSupport.itemMaster; -import static examples.joins.OrderDetailDynamicSQLSupport.orderDetail; -import static examples.joins.OrderLineDynamicSQLSupport.orderLine; -import static examples.joins.OrderMasterDynamicSQLSupport.orderDate; -import static examples.joins.OrderMasterDynamicSQLSupport.orderMaster; -import static examples.joins.UserDynamicSQLSupport.user; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.mybatis.dynamic.sql.SqlBuilder.and; -import static org.mybatis.dynamic.sql.SqlBuilder.constant; -import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo; -import static org.mybatis.dynamic.sql.SqlBuilder.on; -import static org.mybatis.dynamic.sql.SqlBuilder.select; -import static org.mybatis.dynamic.sql.SqlBuilder.sortColumn; -import static org.mybatis.dynamic.sql.SqlBuilder.where; - -class NewSyntaxJoinMapperTest { - - private static final String JDBC_URL = "jdbc:hsqldb:mem:aname"; - private static final String JDBC_DRIVER = "org.hsqldb.jdbcDriver"; - - private SqlSessionFactory sqlSessionFactory; - - @BeforeEach - void setup() throws Exception { - Class.forName(JDBC_DRIVER); - InputStream is = getClass().getResourceAsStream("/examples/joins/CreateJoinDB.sql"); - assert is != null; - 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(JoinMapper.class); - config.addMapper(CommonSelectMapper.class); - sqlSessionFactory = new SqlSessionFactoryBuilder().build(config); - } - - @Test - void testSingleTableJoin1() { - try (SqlSession session = sqlSessionFactory.openSession()) { - JoinMapper mapper = session.getMapper(JoinMapper.class); - - SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) - .from(orderMaster, "om") - .join(orderDetail, "od").on(orderMaster.orderId, isEqualTo(orderDetail.orderId)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" - + " from OrderMaster om join OrderDetail od on om.order_id = od.order_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<OrderMaster> rows = mapper.selectMany(selectStatement); - - assertThat(rows).hasSize(2); - OrderMaster orderMaster = rows.get(0); - assertThat(orderMaster.getId()).isEqualTo(1); - assertThat(orderMaster.getDetails()).hasSize(2); - OrderDetail orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); - orderDetail = orderMaster.getDetails().get(1); - assertThat(orderDetail.getLineNumber()).isEqualTo(2); - - orderMaster = rows.get(1); - assertThat(orderMaster.getId()).isEqualTo(2); - assertThat(orderMaster.getDetails()).hasSize(1); - orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); - } - } - - @Test - void testSingleTableJoin2() { - try (SqlSession session = sqlSessionFactory.openSession()) { - JoinMapper mapper = session.getMapper(JoinMapper.class); - - SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) - .from(orderMaster, "om") - .join(orderDetail, "od", on(orderMaster.orderId, isEqualTo(orderDetail.orderId))) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" - + " from OrderMaster om join OrderDetail od on om.order_id = od.order_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<OrderMaster> rows = mapper.selectMany(selectStatement); - - assertThat(rows).hasSize(2); - OrderMaster orderMaster = rows.get(0); - assertThat(orderMaster.getId()).isEqualTo(1); - assertThat(orderMaster.getDetails()).hasSize(2); - OrderDetail orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); - orderDetail = orderMaster.getDetails().get(1); - assertThat(orderDetail.getLineNumber()).isEqualTo(2); - - orderMaster = rows.get(1); - assertThat(orderMaster.getId()).isEqualTo(2); - assertThat(orderMaster.getDetails()).hasSize(1); - orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); - } - } - - @Test - void testCompoundJoin1() { - // this is a nonsensical join, but it does test the "and" capability - SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) - .from(orderMaster, "om") - .join(orderDetail, "od").on(orderMaster.orderId, isEqualTo(orderDetail.orderId), and(orderMaster.orderId, isEqualTo(orderDetail.orderId))) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" - + " from OrderMaster om join OrderDetail od on om.order_id = od.order_id and om.order_id = od.order_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - } - - @Test - void testCompoundJoin2() { - // this is a nonsensical join, but it does test the "and" capability - SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) - .from(orderMaster, "om") - .join(orderDetail, "od").on(orderMaster.orderId, isEqualTo(orderDetail.orderId)) - .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) - .and(orderMaster.orderId, isEqualTo(orderDetail.orderId)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" - + " from OrderMaster om join OrderDetail od on om.order_id = od.order_id and om.order_id = od.order_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - } - - @Test - void testCompoundJoin3() { - // this is a nonsensical join, but it does test the "and" capability - SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) - .from(orderMaster, "om") - .join(orderDetail, "od", on(orderMaster.orderId, isEqualTo(orderDetail.orderId)), and(orderMaster.orderId, isEqualTo(orderDetail.orderId))) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" - + " from OrderMaster om join OrderDetail od on om.order_id = od.order_id and om.order_id = od.order_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - } - - @Test - void testCompoundJoin4() { - // this is a nonsensical join, but it does test the "and" capability - SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) - .from(orderMaster, "om") - .leftJoin(orderDetail, "od", on(orderMaster.orderId, isEqualTo(orderDetail.orderId)), and(orderMaster.orderId, isEqualTo(orderDetail.orderId))) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" - + " from OrderMaster om left join OrderDetail od on om.order_id = od.order_id and om.order_id = od.order_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - } - - @Test - void testCompoundJoin5() { - // this is a nonsensical join, but it does test the "and" capability - SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) - .from(orderMaster, "om") - .rightJoin(orderDetail, "od", on(orderMaster.orderId, isEqualTo(orderDetail.orderId)), and(orderMaster.orderId, isEqualTo(orderDetail.orderId))) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" - + " from OrderMaster om right join OrderDetail od on om.order_id = od.order_id and om.order_id = od.order_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - } - - @Test - void testCompoundJoin6() { - // this is a nonsensical join, but it does test the "and" capability - SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity) - .from(orderMaster, "om") - .fullJoin(orderDetail, "od", on(orderMaster.orderId, isEqualTo(orderDetail.orderId)), and(orderMaster.orderId, isEqualTo(orderDetail.orderId))) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" - + " from OrderMaster om full join OrderDetail od on om.order_id = od.order_id and om.order_id = od.order_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - } - - @Test - void testMultipleTableJoinWithWhereClause() { - try (SqlSession session = sqlSessionFactory.openSession()) { - JoinMapper mapper = session.getMapper(JoinMapper.class); - - SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) - .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) - .join(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .where(orderMaster.orderId, isEqualTo(2)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select om.order_id, om.order_date, ol.line_number, im.description, ol.quantity" - + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id join ItemMaster im on ol.item_id = im.item_id" - + " where om.order_id = #{parameters.p1,jdbcType=INTEGER}"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<OrderMaster> rows = mapper.selectMany(selectStatement); - - assertThat(rows).hasSize(1); - OrderMaster orderMaster = rows.get(0); - assertThat(orderMaster.getId()).isEqualTo(2); - assertThat(orderMaster.getDetails()).hasSize(2); - OrderDetail orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); - orderDetail = orderMaster.getDetails().get(1); - assertThat(orderDetail.getLineNumber()).isEqualTo(2); - } - } - - @Test - void testMultipleTableJoinWithApplyWhere() { - try (SqlSession session = sqlSessionFactory.openSession()) { - JoinMapper mapper = session.getMapper(JoinMapper.class); - - SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) - .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) - .join(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .applyWhere(where(orderMaster.orderId, isEqualTo(2)).toWhereApplier()) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select om.order_id, om.order_date, ol.line_number, im.description, ol.quantity" - + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id join ItemMaster im on ol.item_id = im.item_id" - + " where om.order_id = #{parameters.p1,jdbcType=INTEGER}"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<OrderMaster> rows = mapper.selectMany(selectStatement); - - assertThat(rows).hasSize(1); - OrderMaster orderMaster = rows.get(0); - assertThat(orderMaster.getId()).isEqualTo(2); - assertThat(orderMaster.getDetails()).hasSize(2); - OrderDetail orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); - orderDetail = orderMaster.getDetails().get(1); - assertThat(orderDetail.getLineNumber()).isEqualTo(2); - } - } - - @Test - void testMultipleTableJoinWithComplexWhereClause() { - try (SqlSession session = sqlSessionFactory.openSession()) { - JoinMapper mapper = session.getMapper(JoinMapper.class); - - SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) - .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) - .join(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .where(orderMaster.orderId, isEqualTo(2), and(orderLine.lineNumber, isEqualTo(2))) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select om.order_id, om.order_date, ol.line_number, im.description, ol.quantity" - + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id join ItemMaster im on ol.item_id = im.item_id" - + " where om.order_id = #{parameters.p1,jdbcType=INTEGER} and ol.line_number = #{parameters.p2,jdbcType=INTEGER}"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<OrderMaster> rows = mapper.selectMany(selectStatement); - - assertThat(rows).hasSize(1); - OrderMaster orderMaster = rows.get(0); - assertThat(orderMaster.getId()).isEqualTo(2); - assertThat(orderMaster.getDetails()).hasSize(1); - OrderDetail orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(2); - } - } - - @Test - void testMultipleTableJoinWithOrderBy() { - try (SqlSession session = sqlSessionFactory.openSession()) { - JoinMapper mapper = session.getMapper(JoinMapper.class); - - SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) - .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) - .join(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .orderBy(orderMaster.orderId) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select om.order_id, om.order_date, ol.line_number, im.description, ol.quantity" - + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id join ItemMaster im on ol.item_id = im.item_id" - + " order by order_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<OrderMaster> rows = mapper.selectMany(selectStatement); - - assertThat(rows).hasSize(2); - OrderMaster orderMaster = rows.get(0); - assertThat(orderMaster.getId()).isEqualTo(1); - assertThat(orderMaster.getDetails()).hasSize(1); - OrderDetail orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); - - orderMaster = rows.get(1); - assertThat(orderMaster.getId()).isEqualTo(2); - assertThat(orderMaster.getDetails()).hasSize(2); - orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); - orderDetail = orderMaster.getDetails().get(1); - assertThat(orderDetail.getLineNumber()).isEqualTo(2); - } - } - - @Test - void testMultipleTableJoinNoAliasWithOrderBy() { - try (SqlSession session = sqlSessionFactory.openSession()) { - JoinMapper mapper = session.getMapper(JoinMapper.class); - - SelectStatementProvider selectStatement = select(orderMaster.orderId, orderDate, orderLine.lineNumber, itemMaster.description, orderLine.quantity) - .from(orderMaster) - .join(orderLine).on(orderMaster.orderId, isEqualTo(orderLine.orderId)) - .join(itemMaster).on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .where(orderMaster.orderId, isEqualTo(2)) - .orderBy(orderMaster.orderId) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select OrderMaster.order_id, OrderMaster.order_date, OrderLine.line_number, ItemMaster.description, OrderLine.quantity" - + " from OrderMaster join OrderLine on OrderMaster.order_id = OrderLine.order_id join ItemMaster on OrderLine.item_id = ItemMaster.item_id" - + " where OrderMaster.order_id = #{parameters.p1,jdbcType=INTEGER}" - + " order by order_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<OrderMaster> rows = mapper.selectMany(selectStatement); - - assertThat(rows).hasSize(1); - OrderMaster orderMaster = rows.get(0); - assertThat(orderMaster.getId()).isEqualTo(2); - assertThat(orderMaster.getDetails()).hasSize(2); - OrderDetail orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); - orderDetail = orderMaster.getDetails().get(1); - assertThat(orderDetail.getLineNumber()).isEqualTo(2); - } - } - - @Test - void testRightJoin() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(orderLine, "ol") - .rightJoin(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .orderBy(itemMaster.itemId) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" - + " from OrderLine ol right join ItemMaster im on ol.item_id = im.item_id" - + " order by item_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(5); - Map<String, Object> row = rows.get(2); - assertThat(row).containsEntry("ORDER_ID", 1); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "First Base Glove"); - assertThat(row).containsEntry("ITEM_ID", 33); - - row = rows.get(4); - assertThat(row).doesNotContainKey("ORDER_ID"); - assertThat(row).doesNotContainKey("QUANTITY"); - assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); - assertThat(row).containsEntry("ITEM_ID", 55); - } - } - - @Test - void testRightJoin2() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) - .rightJoin(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .orderBy(orderLine.orderId, itemMaster.itemId) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" - + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" - + " right join ItemMaster im on ol.item_id = im.item_id" - + " order by order_id, item_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(5); - Map<String, Object> row = rows.get(0); - assertThat(row).doesNotContainKey("ORDER_ID"); - assertThat(row).doesNotContainKey("QUANTITY"); - assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); - assertThat(row).containsEntry("ITEM_ID", 55); - - row = rows.get(4); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); - assertThat(row).containsEntry("ITEM_ID", 44); - } - } - - @Test - void testRightJoin3() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(orderMaster, "om") - .join(orderLine, "ol", on(orderMaster.orderId, isEqualTo(orderLine.orderId))) - .rightJoin(itemMaster, "im", on(orderLine.itemId, isEqualTo(itemMaster.itemId))) - .orderBy(orderLine.orderId, itemMaster.itemId) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" - + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" - + " right join ItemMaster im on ol.item_id = im.item_id" - + " order by order_id, item_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(5); - Map<String, Object> row = rows.get(0); - assertThat(row).doesNotContainKey("ORDER_ID"); - assertThat(row).doesNotContainKey("QUANTITY"); - assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); - assertThat(row).containsEntry("ITEM_ID", 55); - - row = rows.get(4); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); - assertThat(row).containsEntry("ITEM_ID", 44); - } - } - - @Test - void testRightJoinNoAliases() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(orderMaster) - .join(orderLine).on(orderMaster.orderId, isEqualTo(orderLine.orderId)) - .rightJoin(itemMaster).on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .orderBy(orderLine.orderId, itemMaster.itemId) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select OrderLine.order_id, OrderLine.quantity, ItemMaster.item_id, ItemMaster.description" - + " from OrderMaster join OrderLine on OrderMaster.order_id = OrderLine.order_id" - + " right join ItemMaster on OrderLine.item_id = ItemMaster.item_id" - + " order by order_id, item_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(5); - Map<String, Object> row = rows.get(0); - assertThat(row).doesNotContainKey("ORDER_ID"); - assertThat(row).doesNotContainKey("QUANTITY"); - assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); - assertThat(row).containsEntry("ITEM_ID", 55); - - row = rows.get(4); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); - assertThat(row).containsEntry("ITEM_ID", 44); - } - } - - @Test - void testLeftJoin() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(itemMaster, "im") - .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .orderBy(itemMaster.itemId) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" - + " from ItemMaster im left join OrderLine ol on ol.item_id = im.item_id" - + " order by item_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(5); - Map<String, Object> row = rows.get(2); - assertThat(row).containsEntry("ORDER_ID", 1); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "First Base Glove"); - assertThat(row).containsEntry("ITEM_ID", 33); - - row = rows.get(4); - assertThat(row).doesNotContainKey("ORDER_ID"); - assertThat(row).doesNotContainKey("QUANTITY"); - assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); - assertThat(row).containsEntry("ITEM_ID", 55); - } - } - - @Test - void testLeftJoin2() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) - .leftJoin(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .orderBy(orderLine.orderId, itemMaster.itemId) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" - + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" - + " left join ItemMaster im on ol.item_id = im.item_id" - + " order by order_id, item_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(5); - Map<String, Object> row = rows.get(2); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 6); - assertThat(row).doesNotContainKey("DESCRIPTION"); - assertThat(row).doesNotContainKey("ITEM_ID"); - - row = rows.get(4); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); - assertThat(row).containsEntry("ITEM_ID", 44); - } - } - - @Test - void testLeftJoin3() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(orderMaster, "om") - .join(orderLine, "ol", on(orderMaster.orderId, isEqualTo(orderLine.orderId))) - .leftJoin(itemMaster, "im", on(orderLine.itemId, isEqualTo(itemMaster.itemId))) - .orderBy(orderLine.orderId, itemMaster.itemId) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" - + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" - + " left join ItemMaster im on ol.item_id = im.item_id" - + " order by order_id, item_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(5); - Map<String, Object> row = rows.get(2); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 6); - assertThat(row).doesNotContainKey("DESCRIPTION"); - assertThat(row).doesNotContainKey("ITEM_ID"); - - row = rows.get(4); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); - assertThat(row).containsEntry("ITEM_ID", 44); - } - } - - @Test - void testLeftJoinNoAliases() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(orderMaster) - .join(orderLine).on(orderMaster.orderId, isEqualTo(orderLine.orderId)) - .leftJoin(itemMaster).on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .orderBy(orderLine.orderId, itemMaster.itemId) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select OrderLine.order_id, OrderLine.quantity, ItemMaster.item_id, ItemMaster.description" - + " from OrderMaster join OrderLine on OrderMaster.order_id = OrderLine.order_id" - + " left join ItemMaster on OrderLine.item_id = ItemMaster.item_id" - + " order by order_id, item_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(5); - Map<String, Object> row = rows.get(2); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 6); - assertThat(row).doesNotContainKey("DESCRIPTION"); - assertThat(row).doesNotContainKey("ITEM_ID"); - - row = rows.get(4); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); - assertThat(row).containsEntry("ITEM_ID", 44); - } - } - - @Test - void testFullJoin() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, orderLine.itemId.as("ol_itemid"), itemMaster.itemId.as("im_itemid"), itemMaster.description) - .from(itemMaster, "im") - .fullJoin(orderLine, "ol").on(itemMaster.itemId, isEqualTo(orderLine.itemId)) - .orderBy(orderLine.orderId, sortColumn("im_itemid")) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, ol.item_id as ol_itemid, im.item_id as im_itemid, im.description" - + " from ItemMaster im full join OrderLine ol on im.item_id = ol.item_id" - + " order by order_id, im_itemid"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(6); - Map<String, Object> row = rows.get(0); - assertThat(row).doesNotContainKey("ORDER_ID"); - assertThat(row).doesNotContainKey("QUANTITY"); - assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); - assertThat(row).containsEntry("IM_ITEMID", 55); - - row = rows.get(2); - assertThat(row).containsEntry("ORDER_ID", 1); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "First Base Glove"); - assertThat(row).containsEntry("IM_ITEMID", 33); - - row = rows.get(3); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 6); - assertThat(row).containsEntry("OL_ITEMID", 66); - assertThat(row).doesNotContainKey("DESCRIPTION"); - assertThat(row).doesNotContainKey("IM_ITEMID"); - } - } - - @Test - void testFullJoin2() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(orderMaster, "om") - .join(orderLine, "ol").on(orderMaster.orderId, isEqualTo(orderLine.orderId)) - .fullJoin(itemMaster, "im").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .orderBy(orderLine.orderId, itemMaster.itemId) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" - + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" - + " full join ItemMaster im on ol.item_id = im.item_id" - + " order by order_id, item_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(6); - Map<String, Object> row = rows.get(0); - assertThat(row).doesNotContainKey("ORDER_ID"); - assertThat(row).doesNotContainKey("QUANTITY"); - assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); - assertThat(row).containsEntry("ITEM_ID", 55); - - row = rows.get(3); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 6); - assertThat(row).doesNotContainKey("DESCRIPTION"); - assertThat(row).doesNotContainKey("ITEM_ID"); - - row = rows.get(5); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); - assertThat(row).containsEntry("ITEM_ID", 44); - } - } - - @Test - void testFullJoin3() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(orderMaster, "om") - .join(orderLine, "ol", on(orderMaster.orderId, isEqualTo(orderLine.orderId))) - .fullJoin(itemMaster, "im", on(orderLine.itemId, isEqualTo(itemMaster.itemId))) - .orderBy(orderLine.orderId, itemMaster.itemId) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" - + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" - + " full join ItemMaster im on ol.item_id = im.item_id" - + " order by order_id, item_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(6); - Map<String, Object> row = rows.get(0); - assertThat(row).doesNotContainKey("ORDER_ID"); - assertThat(row).doesNotContainKey("QUANTITY"); - assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); - assertThat(row).containsEntry("ITEM_ID", 55); - - row = rows.get(3); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 6); - assertThat(row).doesNotContainKey("DESCRIPTION"); - assertThat(row).doesNotContainKey("ITEM_ID"); - - row = rows.get(5); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); - assertThat(row).containsEntry("ITEM_ID", 44); - } - } - - @Test - void testFullJoin4() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.description) - .from(orderMaster, "om") - .join(orderLine, "ol", on(orderMaster.orderId, isEqualTo(orderLine.orderId))) - .fullJoin(itemMaster, "im", on(orderLine.itemId, isEqualTo(itemMaster.itemId))) - .orderBy(orderLine.orderId, sortColumn("im", itemMaster.itemId)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, im.description" - + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" - + " full join ItemMaster im on ol.item_id = im.item_id" - + " order by order_id, im.item_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(6); - Map<String, Object> row = rows.get(0); - assertThat(row).doesNotContainKey("ORDER_ID"); - assertThat(row).doesNotContainKey("QUANTITY"); - assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); - - row = rows.get(3); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 6); - assertThat(row).doesNotContainKey("DESCRIPTION"); - - row = rows.get(5); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); - } - } - - @Test - void testFullJoin5() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.description) - .from(orderMaster, "om") - .join(orderLine, "ol", on(orderMaster.orderId, isEqualTo(orderLine.orderId))) - .fullJoin(itemMaster, "im", on(orderLine.itemId, isEqualTo(itemMaster.itemId))) - .orderBy(orderLine.orderId, sortColumn("im", itemMaster.itemId).descending()) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, im.description" - + " from OrderMaster om join OrderLine ol on om.order_id = ol.order_id" - + " full join ItemMaster im on ol.item_id = im.item_id" - + " order by order_id, im.item_id DESC"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(6); - Map<String, Object> row = rows.get(0); - assertThat(row).doesNotContainKey("ORDER_ID"); - assertThat(row).doesNotContainKey("QUANTITY"); - assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); - - row = rows.get(3); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 6); - assertThat(row).doesNotContainKey("DESCRIPTION"); - - row = rows.get(5); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Helmet"); - } - } - - @Test - void testFullJoinNoAliases() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(orderMaster) - .join(orderLine).on(orderMaster.orderId, isEqualTo(orderLine.orderId)) - .fullJoin(itemMaster).on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .orderBy(orderLine.orderId, itemMaster.itemId) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select OrderLine.order_id, OrderLine.quantity, ItemMaster.item_id, ItemMaster.description" - + " from OrderMaster join OrderLine on OrderMaster.order_id = OrderLine.order_id" - + " full join ItemMaster on OrderLine.item_id = ItemMaster.item_id" - + " order by order_id, item_id"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(6); - Map<String, Object> row = rows.get(0); - assertThat(row).doesNotContainKey("ORDER_ID"); - assertThat(row).doesNotContainKey("QUANTITY"); - assertThat(row).containsEntry("DESCRIPTION", "Catcher Glove"); - assertThat(row).containsEntry("ITEM_ID", 55); - - row = rows.get(3); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 6); - assertThat(row).doesNotContainKey("DESCRIPTION"); - assertThat(row).doesNotContainKey("ITEM_ID"); - - row = rows.get(5); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); - assertThat(row).containsEntry("ITEM_ID", 44); - } - } - - @Test - void testSelf() { - try (SqlSession session = sqlSessionFactory.openSession()) { - JoinMapper mapper = session.getMapper(JoinMapper.class); - - // create second table instance for self-join - UserDynamicSQLSupport.User user2 = new UserDynamicSQLSupport.User(); - - // get Bamm Bamm's parent - should be Barney - SelectStatementProvider selectStatement = select(user.userId, user.userName, user.parentId) - .from(user, "u1") - .join(user2, "u2").on(user.userId, isEqualTo(user2.parentId)) - .where(user2.userId, isEqualTo(4)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select u1.user_id, u1.user_name, u1.parent_id" - + " from User u1 join User u2 on u1.user_id = u2.parent_id" - + " where u2.user_id = #{parameters.p1,jdbcType=INTEGER}"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<User> rows = mapper.selectUsers(selectStatement); - - assertThat(rows).hasSize(1); - User row = rows.get(0); - assertThat(row.getUserId()).isEqualTo(2); - assertThat(row.getUserName()).isEqualTo("Barney"); - assertThat(row.getParentId()).isNull(); - } - } - - @Test - void testSelfWithDuplicateAlias() { - QueryExpressionDSL<SelectModel> dsl = select(user.userId, user.userName, user.parentId) - .from(user, "u1"); - - assertThatExceptionOfType(DuplicateTableAliasException.class).isThrownBy(() -> dsl.join(user, "u2")) - .withMessage(Messages.getString("ERROR.1", user.tableName(), "u2", "u1")); - } - - @Test - void testSelfWithNewAlias() { - try (SqlSession session = sqlSessionFactory.openSession()) { - JoinMapper mapper = session.getMapper(JoinMapper.class); - - // create second table instance for self-join - UserDynamicSQLSupport.User user2 = user.withAlias("u2"); - - // get Bamm Bamm's parent - should be Barney - SelectStatementProvider selectStatement = select(user.userId, user.userName, user.parentId) - .from(user) - .join(user2).on(user.userId, isEqualTo(user2.parentId)) - .where(user2.userId, isEqualTo(4)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select User.user_id, User.user_name, User.parent_id" - + " from User join User u2 on User.user_id = u2.parent_id" - + " where u2.user_id = #{parameters.p1,jdbcType=INTEGER}"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<User> rows = mapper.selectUsers(selectStatement); - - assertThat(rows).hasSize(1); - User row = rows.get(0); - assertThat(row.getUserId()).isEqualTo(2); - assertThat(row.getUserName()).isEqualTo("Barney"); - assertThat(row.getParentId()).isNull(); - } - } - - @Test - void testSelfWithNewAliasAndOverride() { - try (SqlSession session = sqlSessionFactory.openSession()) { - JoinMapper mapper = session.getMapper(JoinMapper.class); - - // create second table instance for self-join - UserDynamicSQLSupport.User user2 = user.withAlias("other_user"); - - // get Bamm Bamm's parent - should be Barney - SelectStatementProvider selectStatement = select(user.userId, user.userName, user.parentId) - .from(user, "u1") - .join(user2, "u2").on(user.userId, isEqualTo(user2.parentId)) - .where(user2.userId, isEqualTo(4)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select u1.user_id, u1.user_name, u1.parent_id" - + " from User u1 join User u2 on u1.user_id = u2.parent_id" - + " where u2.user_id = #{parameters.p1,jdbcType=INTEGER}"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<User> rows = mapper.selectUsers(selectStatement); - - assertThat(rows).hasSize(1); - User row = rows.get(0); - assertThat(row.getUserId()).isEqualTo(2); - assertThat(row.getUserName()).isEqualTo("Barney"); - assertThat(row.getParentId()).isNull(); - } - } - - @Test - void testLimitAndOffsetAfterJoin() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(itemMaster, "im") - .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .limit(2) - .offset(1) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" - + " from ItemMaster im left join OrderLine ol on ol.item_id = im.item_id" - + " limit #{parameters.p1} offset #{parameters.p2}"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(2); - Map<String, Object> row = rows.get(0); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Helmet"); - assertThat(row).containsEntry("ITEM_ID", 22); - - row = rows.get(1); - assertThat(row).containsEntry("ORDER_ID", 1); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "First Base Glove"); - assertThat(row).containsEntry("ITEM_ID", 33); - } - } - - @Test - void testLimitOnlyAfterJoin() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(itemMaster, "im") - .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .limit(2) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" - + " from ItemMaster im left join OrderLine ol on ol.item_id = im.item_id" - + " limit #{parameters.p1}"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(2); - Map<String, Object> row = rows.get(0); - assertThat(row).containsEntry("ORDER_ID", 1); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Helmet"); - assertThat(row).containsEntry("ITEM_ID", 22); - - row = rows.get(1); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Helmet"); - assertThat(row).containsEntry("ITEM_ID", 22); - } - } - - @Test - void testOffsetOnlyAfterJoin() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(itemMaster, "im") - .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .offset(2) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" - + " from ItemMaster im left join OrderLine ol on ol.item_id = im.item_id" - + " offset #{parameters.p1} rows"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(3); - Map<String, Object> row = rows.get(0); - assertThat(row).containsEntry("ORDER_ID", 1); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "First Base Glove"); - assertThat(row).containsEntry("ITEM_ID", 33); - - row = rows.get(1); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Outfield Glove"); - assertThat(row).containsEntry("ITEM_ID", 44); - } - } - - @Test - void testOffsetAndFetchFirstAfterJoin() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(itemMaster, "im") - .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .offset(1) - .fetchFirst(2).rowsOnly() - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" - + " from ItemMaster im left join OrderLine ol on ol.item_id = im.item_id" - + " offset #{parameters.p1} rows fetch first #{parameters.p2} rows only"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(2); - Map<String, Object> row = rows.get(0); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Helmet"); - assertThat(row).containsEntry("ITEM_ID", 22); - - row = rows.get(1); - assertThat(row).containsEntry("ORDER_ID", 1); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "First Base Glove"); - assertThat(row).containsEntry("ITEM_ID", 33); - } - } - - @Test - void testFetchFirstOnlyAfterJoin() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(itemMaster, "im") - .leftJoin(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .fetchFirst(2).rowsOnly() - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" - + " from ItemMaster im left join OrderLine ol on ol.item_id = im.item_id" - + " fetch first #{parameters.p1} rows only"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(2); - Map<String, Object> row = rows.get(0); - assertThat(row).containsEntry("ORDER_ID", 1); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Helmet"); - assertThat(row).containsEntry("ITEM_ID", 22); - - row = rows.get(1); - assertThat(row).containsEntry("ORDER_ID", 2); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Helmet"); - assertThat(row).containsEntry("ITEM_ID", 22); - } - } - - @Test - void testJoinWithParameterValue() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(itemMaster, "im") - .join(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .and(orderLine.orderId, isEqualTo(1)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" - + " from ItemMaster im join OrderLine ol on ol.item_id = im.item_id" - + " and ol.order_id = #{parameters.p1,jdbcType=INTEGER}"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(2); - Map<String, Object> row = rows.get(0); - assertThat(row).containsEntry("ORDER_ID", 1); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Helmet"); - assertThat(row).containsEntry("ITEM_ID", 22); - - row = rows.get(1); - assertThat(row).containsEntry("ORDER_ID", 1); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "First Base Glove"); - assertThat(row).containsEntry("ITEM_ID", 33); - } - } - - @Test - void testJoinWithConstant() { - try (SqlSession session = sqlSessionFactory.openSession()) { - CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); - - SelectStatementProvider selectStatement = select(orderLine.orderId, orderLine.quantity, itemMaster.itemId, itemMaster.description) - .from(itemMaster, "im") - .join(orderLine, "ol").on(orderLine.itemId, isEqualTo(itemMaster.itemId)) - .and(orderLine.orderId, isEqualTo(constant("1"))) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expectedStatement = "select ol.order_id, ol.quantity, im.item_id, im.description" - + " from ItemMaster im join OrderLine ol on ol.item_id = im.item_id" - + " and ol.order_id = 1"; - assertThat(selectStatement.getSelectStatement()).isEqualTo(expectedStatement); - - List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); - - assertThat(rows).hasSize(2); - Map<String, Object> row = rows.get(0); - assertThat(row).containsEntry("ORDER_ID", 1); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "Helmet"); - assertThat(row).containsEntry("ITEM_ID", 22); - - row = rows.get(1); - assertThat(row).containsEntry("ORDER_ID", 1); - assertThat(row).containsEntry("QUANTITY", 1); - assertThat(row).containsEntry("DESCRIPTION", "First Base Glove"); - assertThat(row).containsEntry("ITEM_ID", 33); - } - } -} diff --git a/src/test/java/examples/simple/PersonWithAddressMapper.java b/src/test/java/examples/simple/PersonWithAddressMapper.java index a36946bad..5a51cf465 100644 --- a/src/test/java/examples/simple/PersonWithAddressMapper.java +++ b/src/test/java/examples/simple/PersonWithAddressMapper.java @@ -80,13 +80,13 @@ public interface PersonWithAddressMapper extends CommonCountMapper { default Optional<PersonWithAddress> selectOne(SelectDSLCompleter completer) { QueryExpressionDSL<SelectModel> start = SqlBuilder.select(selectList).from(person) - .join(address, on(person.addressId, equalTo(address.id))); + .join(address, on(person.addressId, isEqualTo(address.id))); return MyBatis3Utils.selectOne(this::selectOne, start, completer); } default List<PersonWithAddress> select(SelectDSLCompleter completer) { QueryExpressionDSL<SelectModel> start = SqlBuilder.select(selectList).from(person) - .join(address, on(person.addressId, equalTo(address.id))); + .join(address, on(person.addressId, isEqualTo(address.id))); return MyBatis3Utils.selectList(this::selectMany, start, completer); } @@ -98,7 +98,7 @@ default Optional<PersonWithAddress> selectByPrimaryKey(Integer id_) { default long count(CountDSLCompleter completer) { CountDSL<SelectModel> start = countFrom(person) - .join(address, on(person.addressId, equalTo(address.id))); + .join(address, on(person.addressId, isEqualTo(address.id))); return MyBatis3Utils.countFrom(this::count, start, completer); } } diff --git a/src/test/java/examples/spring/PersonTemplateTest.java b/src/test/java/examples/spring/PersonTemplateTest.java index 2cd2b6b42..2f0e5b2dc 100644 --- a/src/test/java/examples/spring/PersonTemplateTest.java +++ b/src/test/java/examples/spring/PersonTemplateTest.java @@ -633,7 +633,7 @@ void testJoinAllRows() { Buildable<SelectModel> selectStatement = select(id, firstName, lastName, birthDate, employed, occupation, address.id, address.streetAddress, address.city, address.state) .from(person) - .join(address, on(person.addressId, equalTo(address.id))) + .join(address, on(person.addressId, isEqualTo(address.id))) .orderBy(id); List<PersonWithAddress> records = template.selectList(selectStatement, personWithAddressRowMapper); @@ -656,7 +656,7 @@ void testJoinOneRow() { Buildable<SelectModel> selectStatement = select(id, firstName, lastName, birthDate, employed, occupation, address.id, address.streetAddress, address.city, address.state) .from(person) - .join(address, on(person.addressId, equalTo(address.id))) + .join(address, on(person.addressId, isEqualTo(address.id))) .where(id, isEqualTo(1)); List<PersonWithAddress> records = template.selectList(selectStatement, personWithAddressRowMapper); @@ -679,7 +679,7 @@ void testJoinPrimaryKey() { Buildable<SelectModel> selectStatement = select(id, firstName, lastName, birthDate, employed, occupation, address.id, address.streetAddress, address.city, address.state) .from(person) - .join(address, on(person.addressId, equalTo(address.id))) + .join(address, on(person.addressId, isEqualTo(address.id))) .where(id, isEqualTo(1)); Optional<PersonWithAddress> row = template.selectOne(selectStatement, personWithAddressRowMapper); @@ -703,7 +703,7 @@ void testJoinPrimaryKeyInvalidRecord() { Buildable<SelectModel> selectStatement = select(id, firstName, lastName, birthDate, employed, occupation, address.id, address.streetAddress, address.city, address.state) .from(person) - .join(address, on(person.addressId, equalTo(address.id))) + .join(address, on(person.addressId, isEqualTo(address.id))) .where(id, isEqualTo(55)); Optional<PersonWithAddress> row = template.selectOne(selectStatement, personWithAddressRowMapper); @@ -713,7 +713,7 @@ void testJoinPrimaryKeyInvalidRecord() { @Test void testJoinCount() { Buildable<SelectModel> countStatement = countFrom(person) - .join(address, on(person.addressId, equalTo(address.id))) + .join(address, on(person.addressId, isEqualTo(address.id))) .where(id, isEqualTo(55)); long count = template.count(countStatement); @@ -723,7 +723,7 @@ void testJoinCount() { @Test void testJoinCountWithSubCriteria() { Buildable<SelectModel> countStatement = countFrom(person) - .join(address, on(person.addressId, equalTo(address.id))) + .join(address, on(person.addressId, isEqualTo(address.id))) .where(person.id, isEqualTo(55), or(person.id, isEqualTo(1))); long count = template.count(countStatement); diff --git a/src/test/java/issues/gh100/FromJoinWhereTest.java b/src/test/java/issues/gh100/FromJoinWhereTest.java index 47867128d..6695d56a6 100644 --- a/src/test/java/issues/gh100/FromJoinWhereTest.java +++ b/src/test/java/issues/gh100/FromJoinWhereTest.java @@ -32,7 +32,7 @@ void testNormalUsage() { SelectStatementProvider selectStatement = select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student) .join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)) + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)) .where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")) .union() .select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) @@ -76,7 +76,7 @@ void testFromJoinB1() { .from(StudentDynamicSqlSupport.student); builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -93,7 +93,7 @@ void testFromJoinB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); String expected = "select student.id, student.name, student.idcard" + " from student" @@ -110,7 +110,7 @@ void testfromJoinWhereB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -130,7 +130,7 @@ void testfromJoinWhereB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -150,7 +150,7 @@ void testfromJoinWhereB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -170,7 +170,7 @@ void testFromJoinWhereUnionB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -197,7 +197,7 @@ void testFromJoinWhereUnionB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -224,7 +224,7 @@ void testFromJoinWhereUnionB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -251,7 +251,7 @@ void testFromJoinWhereUnionB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -278,7 +278,7 @@ void testFromJoinWhereUnionUnionB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -316,7 +316,7 @@ void testFromJoinWhereUnionUnionB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -354,7 +354,7 @@ void testFromJoinWhereUnionUnionB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -392,7 +392,7 @@ void testFromJoinWhereUnionUnionB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -430,7 +430,7 @@ void testFromJoinWhereUnionUnionB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -468,7 +468,7 @@ void testFromJoinWhereUnionOrderByB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -498,7 +498,7 @@ void testFromJoinWhereUnionOrderByB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -528,7 +528,7 @@ void testFromJoinWhereUnionOrderByB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -558,7 +558,7 @@ void testFromJoinWhereUnionOrderByB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -588,7 +588,7 @@ void testFromJoinWhereUnionOrderByB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -618,7 +618,7 @@ void testFromJoinWhereUnionOrderByLimitB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -651,7 +651,7 @@ void testFromJoinWhereUnionOrderByLimitB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -684,7 +684,7 @@ void testFromJoinWhereUnionOrderByLimitB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -717,7 +717,7 @@ void testFromJoinWhereUnionOrderByLimitB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -750,7 +750,7 @@ void testFromJoinWhereUnionOrderByLimitB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -783,7 +783,7 @@ void testFromJoinWhereUnionOrderByLimitB6() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -816,7 +816,7 @@ void testFromJoinWhereUnionOrderByLimitOffsetB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -852,7 +852,7 @@ void testFromJoinWhereUnionOrderByLimitOffsetB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -888,7 +888,7 @@ void testFromJoinWhereUnionOrderByLimitOffsetB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -924,7 +924,7 @@ void testFromJoinWhereUnionOrderByLimitOffsetB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -960,7 +960,7 @@ void testFromJoinWhereUnionOrderByLimitOffsetB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -996,7 +996,7 @@ void testFromJoinWhereUnionOrderByLimitOffsetB6() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1032,7 +1032,7 @@ void testFromJoinWhereUnionOrderByLimitOffsetB7() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1068,7 +1068,7 @@ void testFromJoinWhereUnionOrderByOffsetB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1102,7 +1102,7 @@ void testFromJoinWhereUnionOrderByOffsetB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1136,7 +1136,7 @@ void testFromJoinWhereUnionOrderByOffsetB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1170,7 +1170,7 @@ void testFromJoinWhereUnionOrderByOffsetB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1204,7 +1204,7 @@ void testFromJoinWhereUnionOrderByOffsetB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1238,7 +1238,7 @@ void testFromJoinWhereUnionOrderByOffsetB6() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1272,7 +1272,7 @@ void testFromJoinWhereUnionOrderByOffsetFetchFirstB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1308,7 +1308,7 @@ void testFromJoinWhereUnionOrderByOffsetFetchFirstB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1344,7 +1344,7 @@ void testFromJoinWhereUnionOrderByOffsetFetchFirstB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1380,7 +1380,7 @@ void testFromJoinWhereUnionOrderByOffsetFetchFirstB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1416,7 +1416,7 @@ void testFromJoinWhereUnionOrderByOffsetFetchFirstB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1452,7 +1452,7 @@ void testFromJoinWhereUnionOrderByOffsetFetchFirstB6() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1488,7 +1488,7 @@ void testFromJoinWhereUnionOrderByOffsetFetchFirstB7() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1524,7 +1524,7 @@ void testFromJoinWhereUnionOrderByFetchFirstB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1557,7 +1557,7 @@ void testFromJoinWhereUnionOrderByFetchFirstB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1590,7 +1590,7 @@ void testFromJoinWhereUnionOrderByFetchFirstB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1623,7 +1623,7 @@ void testFromJoinWhereUnionOrderByFetchFirstB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1656,7 +1656,7 @@ void testFromJoinWhereUnionOrderByFetchFirstB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1689,7 +1689,7 @@ void testFromJoinWhereUnionOrderByFetchFirstB6() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1722,7 +1722,7 @@ void testFromJoinWhereUnionLimitB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1752,7 +1752,7 @@ void testFromJoinWhereUnionLimitB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1782,7 +1782,7 @@ void testFromJoinWhereUnionLimitB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1812,7 +1812,7 @@ void testFromJoinWhereUnionLimitB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1842,7 +1842,7 @@ void testFromJoinWhereUnionLimitB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1872,7 +1872,7 @@ void testFromJoinWhereUnionLimitOffsetB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1905,7 +1905,7 @@ void testFromJoinWhereUnionLimitOffsetB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1938,7 +1938,7 @@ void testFromJoinWhereUnionLimitOffsetB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -1971,7 +1971,7 @@ void testFromJoinWhereUnionLimitOffsetB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2004,7 +2004,7 @@ void testFromJoinWhereUnionLimitOffsetB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2037,7 +2037,7 @@ void testFromJoinWhereUnionLimitOffsetB6() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2070,7 +2070,7 @@ void testFromJoinWhereUnionOffsetB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2100,7 +2100,7 @@ void testFromJoinWhereUnionOffsetB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2130,7 +2130,7 @@ void testFromJoinWhereUnionOffsetB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2160,7 +2160,7 @@ void testFromJoinWhereUnionOffsetB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2190,7 +2190,7 @@ void testFromJoinWhereUnionOffsetB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2220,7 +2220,7 @@ void testFromJoinWhereUnionOffsetFetchFirstB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2253,7 +2253,7 @@ void testFromJoinWhereUnionOffsetFetchFirstB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2286,7 +2286,7 @@ void testFromJoinWhereUnionOffsetFetchFirstB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2319,7 +2319,7 @@ void testFromJoinWhereUnionOffsetFetchFirstB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2352,7 +2352,7 @@ void testFromJoinWhereUnionOffsetFetchFirstB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2385,7 +2385,7 @@ void testFromJoinWhereUnionOffsetFetchFirstB6() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2418,7 +2418,7 @@ void testFromJoinWhereUnionFetchFirstB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2448,7 +2448,7 @@ void testFromJoinWhereUnionFetchFirstB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2478,7 +2478,7 @@ void testFromJoinWhereUnionFetchFirstB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2508,7 +2508,7 @@ void testFromJoinWhereUnionFetchFirstB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2538,7 +2538,7 @@ void testFromJoinWhereUnionFetchFirstB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2568,7 +2568,7 @@ void testFromJoinWhereOrderByB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2591,7 +2591,7 @@ void testFromJoinWhereOrderByB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2614,7 +2614,7 @@ void testFromJoinWhereOrderByB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2637,7 +2637,7 @@ void testFromJoinWhereOrderByB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2660,7 +2660,7 @@ void testFromJoinWhereOrderByLimitB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2686,7 +2686,7 @@ void testFromJoinWhereOrderByLimitB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2712,7 +2712,7 @@ void testFromJoinWhereOrderByLimitB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2738,7 +2738,7 @@ void testFromJoinWhereOrderByLimitB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2764,7 +2764,7 @@ void testFromJoinWhereOrderByLimitB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2790,7 +2790,7 @@ void testFromJoinWhereOrderByLimitOffsetB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2819,7 +2819,7 @@ void testFromJoinWhereOrderByLimitOffsetB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2848,7 +2848,7 @@ void testFromJoinWhereOrderByLimitOffsetB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2877,7 +2877,7 @@ void testFromJoinWhereOrderByLimitOffsetB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2906,7 +2906,7 @@ void testFromJoinWhereOrderByLimitOffsetB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2935,7 +2935,7 @@ void testFromJoinWhereOrderByLimitOffsetB6() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2964,7 +2964,7 @@ void testFromJoinWhereOrderByOffsetB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -2990,7 +2990,7 @@ void testFromJoinWhereOrderByOffsetB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3016,7 +3016,7 @@ void testFromJoinWhereOrderByOffsetB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3042,7 +3042,7 @@ void testFromJoinWhereOrderByOffsetB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3068,7 +3068,7 @@ void testFromJoinWhereOrderByOffsetB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3094,7 +3094,7 @@ void testFromJoinWhereOrderByOffsetFetchFirstB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3123,7 +3123,7 @@ void testFromJoinWhereOrderByOffsetFetchFirstB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3152,7 +3152,7 @@ void testFromJoinWhereOrderByOffsetFetchFirstB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3181,7 +3181,7 @@ void testFromJoinWhereOrderByOffsetFetchFirstB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3210,7 +3210,7 @@ void testFromJoinWhereOrderByOffsetFetchFirstB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3239,7 +3239,7 @@ void testFromJoinWhereOrderByOffsetFetchFirstB6() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3268,7 +3268,7 @@ void testFromJoinWhereOrderByFetchFirstB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3294,7 +3294,7 @@ void testFromJoinWhereOrderByFetchFirstB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3320,7 +3320,7 @@ void testFromJoinWhereOrderByFetchFirstB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3346,7 +3346,7 @@ void testFromJoinWhereOrderByFetchFirstB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3372,7 +3372,7 @@ void testFromJoinWhereOrderByFetchFirstB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3398,7 +3398,7 @@ void testFromJoinWhereLimitB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3421,7 +3421,7 @@ void testFromJoinWhereLimitB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3444,7 +3444,7 @@ void testFromJoinWhereLimitB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3467,7 +3467,7 @@ void testFromJoinWhereLimitB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3490,7 +3490,7 @@ void testFromJoinWhereLimitOffsetB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3516,7 +3516,7 @@ void testFromJoinWhereLimitOffsetB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3542,7 +3542,7 @@ void testFromJoinWhereLimitOffsetB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3568,7 +3568,7 @@ void testFromJoinWhereLimitOffsetB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3594,7 +3594,7 @@ void testFromJoinWhereLimitOffsetB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3620,7 +3620,7 @@ void testFromJoinWhereOffsetB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3643,7 +3643,7 @@ void testFromJoinWhereOffsetB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3666,7 +3666,7 @@ void testFromJoinWhereOffsetB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3689,7 +3689,7 @@ void testFromJoinWhereOffsetB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3712,7 +3712,7 @@ void testFromJoinWhereOffsetFetchFirstB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3738,7 +3738,7 @@ void testFromJoinWhereOffsetFetchFirstB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3764,7 +3764,7 @@ void testFromJoinWhereOffsetFetchFirstB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3790,7 +3790,7 @@ void testFromJoinWhereOffsetFetchFirstB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3816,7 +3816,7 @@ void testFromJoinWhereOffsetFetchFirstB5() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3842,7 +3842,7 @@ void testFromJoinWhereFetchFirstB1() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3865,7 +3865,7 @@ void testFromJoinWhereFetchFirstB2() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3888,7 +3888,7 @@ void testFromJoinWhereFetchFirstB3() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -3911,7 +3911,7 @@ void testFromJoinWhereFetchFirstB4() { .from(StudentDynamicSqlSupport.student); QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder2 = builder1.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder3 = builder2.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); diff --git a/src/test/java/issues/gh100/Issue100StartAfterJoinTest.java b/src/test/java/issues/gh100/Issue100StartAfterJoinTest.java index 9c3631c4d..aff76db96 100644 --- a/src/test/java/issues/gh100/Issue100StartAfterJoinTest.java +++ b/src/test/java/issues/gh100/Issue100StartAfterJoinTest.java @@ -32,7 +32,7 @@ void testSuccessiveBuild02() { QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder = select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student) .join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); builder.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); @@ -50,7 +50,7 @@ void testSuccessiveBuild03() { QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder = select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student) .join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); SelectDSL<SelectModel> selectModel = builder.orderBy(StudentDynamicSqlSupport.id); @@ -71,7 +71,7 @@ void testSuccessiveBuild04() { QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder = select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student) .join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); builder.limit(3); @@ -89,7 +89,7 @@ void testSuccessiveBuild05() { QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder = select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student) .join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); builder.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")) .orderBy(StudentDynamicSqlSupport.id) @@ -113,7 +113,7 @@ void testSuccessiveBuild06() { QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder = select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student) .join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); builder.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")) .orderBy(StudentDynamicSqlSupport.id) @@ -135,7 +135,7 @@ void testSuccessiveBuild07() { QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder = select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student) .join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); builder.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")) .orderBy(StudentDynamicSqlSupport.id) @@ -159,7 +159,7 @@ void testSuccessiveBuild08() { QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher builder = select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student) .join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); builder.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")) .orderBy(StudentDynamicSqlSupport.id) diff --git a/src/test/java/issues/gh100/Issue100Test.java b/src/test/java/issues/gh100/Issue100Test.java index f0411c774..01a8e0b0e 100644 --- a/src/test/java/issues/gh100/Issue100Test.java +++ b/src/test/java/issues/gh100/Issue100Test.java @@ -31,7 +31,7 @@ void testNormalUsage() { SelectStatementProvider selectStatement = select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student) .join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)) + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)) .where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")) .union() .select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) @@ -60,7 +60,7 @@ void testSuccessiveBuild01() { .from(StudentDynamicSqlSupport.student); builder.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); SelectStatementProvider selectStatement = builder.build() .render(RenderingStrategies.MYBATIS3); @@ -76,7 +76,7 @@ void testSuccessiveBuild02() { .from(StudentDynamicSqlSupport.student); builder.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)) + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)) .where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); SelectStatementProvider selectStatement = builder.build() @@ -94,7 +94,7 @@ void testSuccessiveBuild03() { .from(StudentDynamicSqlSupport.student); builder.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)) + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)) .where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")) .orderBy(StudentDynamicSqlSupport.id); @@ -114,7 +114,7 @@ void testSuccessiveBuild04() { .from(StudentDynamicSqlSupport.student); builder.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)) + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)) .where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")) .orderBy(StudentDynamicSqlSupport.id) .limit(3); @@ -136,7 +136,7 @@ void testSuccessiveBuild05() { .from(StudentDynamicSqlSupport.student); builder.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)) + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)) .where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")) .orderBy(StudentDynamicSqlSupport.id) .limit(3) @@ -182,8 +182,8 @@ void testSuccessiveBuild07() { .from(StudentDynamicSqlSupport.student); builder.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)) - .where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")) + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)) + .where(StudentDynamicSqlSupport.idcard, equalTo("fred")) .orderBy(StudentDynamicSqlSupport.id) .offset(2) .fetchFirst(3).rowsOnly(); @@ -206,7 +206,7 @@ void testSuccessiveBuild08() { .from(StudentDynamicSqlSupport.student); builder.join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)) + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)) .where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")) .orderBy(StudentDynamicSqlSupport.id) .fetchFirst(3).rowsOnly(); @@ -227,7 +227,7 @@ void test3() { QueryExpressionDSL<SelectModel>.JoinSpecificationFinisher on = select(StudentDynamicSqlSupport.id, StudentDynamicSqlSupport.name, StudentDynamicSqlSupport.idcard) .from(StudentDynamicSqlSupport.student) .join(StudentRegDynamicSqlSupport.studentReg) - .on(StudentDynamicSqlSupport.id, equalTo(StudentRegDynamicSqlSupport.studentid)); + .on(StudentDynamicSqlSupport.id, isEqualTo(StudentRegDynamicSqlSupport.studentid)); on.where(StudentDynamicSqlSupport.idcard, isEqualTo("fred")); diff --git a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonWithAddressMapperExtensions.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonWithAddressMapperExtensions.kt index c24c3a967..df4c91da8 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonWithAddressMapperExtensions.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonWithAddressMapperExtensions.kt @@ -35,8 +35,8 @@ private val columnList = listOf(id `as` "A_ID", firstName, lastName, birthDate, fun PersonWithAddressMapper.selectOne(completer: SelectCompleter): PersonWithAddress? = select(columnList) { from(person) - fullJoin(address) { - on(person.addressId) equalTo address.id + fullJoin(address) on { + person.addressId isEqualTo address.id } completer() }.run(this::selectOne) @@ -44,8 +44,8 @@ fun PersonWithAddressMapper.selectOne(completer: SelectCompleter): PersonWithAdd fun PersonWithAddressMapper.select(completer: SelectCompleter): List<PersonWithAddress> = select(columnList) { from(person, "p") - fullJoin(address) { - on(person.addressId) equalTo address.id + fullJoin(address) on { + person.addressId isEqualTo address.id } completer() }.run(this::selectMany) @@ -53,8 +53,8 @@ fun PersonWithAddressMapper.select(completer: SelectCompleter): List<PersonWithA fun PersonWithAddressMapper.selectDistinct(completer: SelectCompleter): List<PersonWithAddress> = selectDistinct(columnList) { from(person) - fullJoin(address) { - on(person.addressId) equalTo address.id + fullJoin(address) on { + person.addressId isEqualTo address.id } completer() }.run(this::selectMany) diff --git a/src/test/kotlin/examples/kotlin/mybatis3/general/GeneralKotlinTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/general/GeneralKotlinTest.kt index 68d073cc9..4f0368248 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/general/GeneralKotlinTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/general/GeneralKotlinTest.kt @@ -367,8 +367,8 @@ class GeneralKotlinTest { address.id, address.streetAddress, address.city, address.state ) { from(person) - join(address) { - on(addressId) equalTo address.id + join(address) on { + addressId isEqualTo address.id } where { id isLessThan 4 } orderBy(id) @@ -403,8 +403,8 @@ class GeneralKotlinTest { address.id, address.streetAddress, address.city, address.state ) { from(person) - join(address) { - on(addressId) equalTo address.id + join(address) on { + addressId isEqualTo address.id } where { id isLessThan 5 @@ -446,8 +446,8 @@ class GeneralKotlinTest { address.id, address.streetAddress, address.city, address.state ) { from(person) - join(address) { - on(addressId) equalTo address.id + join(address) on { + addressId isEqualTo address.id } where { id isEqualTo 5 diff --git a/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/DeprecatedJoinMapperTest.kt similarity index 66% rename from src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperTest.kt rename to src/test/kotlin/examples/kotlin/mybatis3/joins/DeprecatedJoinMapperTest.kt index 5754fe631..7a05b79e4 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/DeprecatedJoinMapperTest.kt @@ -30,14 +30,12 @@ import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.mybatis.dynamic.sql.util.Messages import org.mybatis.dynamic.sql.util.kotlin.KInvalidSQLException -import org.mybatis.dynamic.sql.util.kotlin.elements.constant import org.mybatis.dynamic.sql.util.kotlin.elements.invoke -import org.mybatis.dynamic.sql.util.kotlin.elements.max import org.mybatis.dynamic.sql.util.kotlin.mybatis3.select @Suppress("LargeClass") @TestInstance(TestInstance.Lifecycle.PER_CLASS) -class JoinMapperTest { +class DeprecatedJoinMapperTest { private lateinit var sqlSessionFactory: SqlSessionFactory @BeforeAll @@ -48,45 +46,6 @@ class JoinMapperTest { } } - @Test - fun testSingleTableJoin() { - sqlSessionFactory.openSession().use { session -> - val mapper = session.getMapper(JoinMapper::class.java) - - val selectStatement = select( - orderMaster.orderId, orderMaster.orderDate, - orderDetail.lineNumber, orderDetail.description, orderDetail.quantity - ) { - from(orderMaster, "om") - join(orderDetail, "od") { - on(orderMaster.orderId) equalTo orderDetail.orderId - } - } - - val expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" + - " from OrderMaster om join OrderDetail od on om.order_id = od.order_id" - - assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) - - val rows = mapper.selectMany(selectStatement) - - assertThat(rows).hasSize(2) - - with(rows[0]) { - assertThat(id).isEqualTo(1) - assertThat(details).hasSize(2) - assertThat(details?.get(0)?.lineNumber).isEqualTo(1) - assertThat(details?.get(1)?.lineNumber).isEqualTo(2) - } - - with(rows[1]) { - assertThat(id).isEqualTo(2) - assertThat(details).hasSize(1) - assertThat(details?.get(0)?.lineNumber).isEqualTo(1) - } - } - } - @Test fun testSingleTableJoinWithValue() { sqlSessionFactory.openSession().use { session -> @@ -96,51 +55,16 @@ class JoinMapperTest { orderMaster.orderId, orderMaster.orderDate, orderDetail.lineNumber, orderDetail.description, orderDetail.quantity ) { - from(orderMaster, "om") - join(orderDetail, "od") { + from(orderMaster) + join(orderDetail) { on(orderMaster.orderId) equalTo orderDetail.orderId and(orderMaster.orderId) equalTo 1 } } - val expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" + - " from OrderMaster om join OrderDetail od on om.order_id = od.order_id" + - " and om.order_id = #{parameters.p1,jdbcType=INTEGER}" - - assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) - - val rows = mapper.selectMany(selectStatement) - - assertThat(rows).hasSize(1) - - with(rows[0]) { - assertThat(id).isEqualTo(1) - assertThat(details).hasSize(2) - assertThat(details?.get(0)?.lineNumber).isEqualTo(1) - assertThat(details?.get(1)?.lineNumber).isEqualTo(2) - } - } - } - - @Test - fun testSingleTableJoinWithConstant() { - sqlSessionFactory.openSession().use { session -> - val mapper = session.getMapper(JoinMapper::class.java) - - val selectStatement = select( - orderMaster.orderId, orderMaster.orderDate, - orderDetail.lineNumber, orderDetail.description, orderDetail.quantity - ) { - from(orderMaster, "om") - join(orderDetail, "od") { - on(orderMaster.orderId) equalTo orderDetail.orderId - and(orderMaster.orderId) equalTo constant("1") - } - } - - val expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" + - " from OrderMaster om join OrderDetail od on om.order_id = od.order_id" + - " and om.order_id = 1" + val expectedStatement = "select OrderMaster.order_id, OrderMaster.order_date, OrderDetail.line_number, OrderDetail.description, OrderDetail.quantity" + + " from OrderMaster join OrderDetail on OrderMaster.order_id = OrderDetail.order_id" + + " and OrderMaster.order_id = #{parameters.p1,jdbcType=INTEGER}" assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) @@ -176,64 +100,6 @@ class JoinMapperTest { assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) } - @Test - fun testCompoundJoin2() { - // this is a nonsensical join, but it does test the "and" capability - val selectStatement = select( - orderMaster.orderId, orderMaster.orderDate, orderDetail.lineNumber, - orderDetail.description, orderDetail.quantity - ) { - from(orderMaster, "om") - join(orderDetail, "od") { - on(orderMaster.orderId) equalTo orderDetail.orderId - and(orderMaster.orderId) equalTo orderDetail.orderId - } - where { orderMaster.orderId isEqualTo 1 } - } - - val expectedStatement = "select om.order_id, om.order_date, od.line_number, od.description, od.quantity" + - " from OrderMaster om join OrderDetail od on om.order_id = od.order_id and om.order_id = od.order_id" + - " where om.order_id = #{parameters.p1,jdbcType=INTEGER}" - assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) - } - - @Test - fun testMultipleTableJoinWithWhereClause() { - sqlSessionFactory.openSession().use { session -> - val mapper = session.getMapper(JoinMapper::class.java) - - val selectStatement = select( - orderMaster.orderId, orderMaster.orderDate, orderLine.lineNumber, - itemMaster.description, orderLine.quantity - ) { - from(orderMaster, "om") - join(orderLine, "ol") { - on(orderMaster.orderId) equalTo orderLine.orderId - } - join(itemMaster, "im") { - on(orderLine.itemId) equalTo itemMaster.itemId - } - where { orderMaster.orderId isEqualTo 2 } - } - - val expectedStatement = "select om.order_id, om.order_date, ol.line_number, im.description, ol.quantity" + - " from OrderMaster om join OrderLine ol" + - " on om.order_id = ol.order_id join ItemMaster im on ol.item_id = im.item_id" + - " where om.order_id = #{parameters.p1,jdbcType=INTEGER}" - assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) - - val rows = mapper.selectMany(selectStatement) - - assertThat(rows).hasSize(1) - with(rows[0]) { - assertThat(id).isEqualTo(2) - assertThat(details).hasSize(2) - assertThat(details?.get(0)?.lineNumber).isEqualTo(1) - assertThat(details?.get(1)?.lineNumber).isEqualTo(2) - } - } - } - @Test fun testFullJoinWithAliases() { sqlSessionFactory.openSession().use { session -> @@ -703,100 +569,6 @@ class JoinMapperTest { } } - @Test - fun testSelf() { - sqlSessionFactory.openSession().use { session -> - val mapper = session.getMapper(JoinMapper::class.java) - - // create second table instance for self-join - val user2 = UserDynamicSQLSupport.User() - - // get Bamm Bamm's parent - should be Barney - val selectStatement = select(user.userId, user.userName, user.parentId) { - from(user, "u1") - join(user2, "u2") { - on(user.userId) equalTo user2.parentId - } - where { user2.userId isEqualTo 4 } - } - - val expectedStatement = "select u1.user_id, u1.user_name, u1.parent_id" + - " from User u1 join User u2 on u1.user_id = u2.parent_id" + - " where u2.user_id = #{parameters.p1,jdbcType=INTEGER}" - assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) - val rows = mapper.selectManyMappedRows(selectStatement) - - assertThat(rows).hasSize(1) - assertThat(rows[0]).containsExactly( - entry("USER_ID", 2), - entry("USER_NAME", "Barney"), - ) - } - } - - @Test - fun testSelfWithNewAlias() { - sqlSessionFactory.openSession().use { session -> - val mapper = session.getMapper(JoinMapper::class.java) - - // create second table instance for self-join - val user2 = user.withAlias("u2") - - // get Bamm Bamm's parent - should be Barney - val selectStatement = select(user.userId, user.userName, user.parentId) { - from(user) - join(user2) { - on(user.userId) equalTo user2.parentId - } - where { user2.userId isEqualTo 4 } - } - - val expectedStatement = "select User.user_id, User.user_name, User.parent_id" + - " from User join User u2 on User.user_id = u2.parent_id" + - " where u2.user_id = #{parameters.p1,jdbcType=INTEGER}" - assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) - - val rows = mapper.selectManyMappedRows(selectStatement) - assertThat(rows).hasSize(1) - - assertThat(rows[0]).containsExactly( - entry("USER_ID", 2), - entry("USER_NAME", "Barney"), - ) - } - } - - @Test - fun testSelfWithNewAliasAndOverride() { - sqlSessionFactory.openSession().use { session -> - val mapper = session.getMapper(JoinMapper::class.java) - - // create second table instance for self-join - val user2 = user.withAlias("other_user") - - // get Bamm Bamm's parent - should be Barney - val selectStatement = select(user.userId, user.userName, user.parentId) { - from(user, "u1") - join(user2, "u2") { - on(user.userId) equalTo user2.parentId - } - where { user2.userId isEqualTo 4 } - } - - val expectedStatement = "select u1.user_id, u1.user_name, u1.parent_id" + - " from User u1 join User u2 on u1.user_id = u2.parent_id" + - " where u2.user_id = #{parameters.p1,jdbcType=INTEGER}" - assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) - val rows = mapper.selectManyMappedRows(selectStatement) - assertThat(rows).hasSize(1) - - assertThat(rows[0]).containsExactly( - entry("USER_ID", 2), - entry("USER_NAME", "Barney"), - ) - } - } - @Test fun testJoinWithNoOnCondition() { // create second table instance for self-join @@ -829,48 +601,4 @@ class JoinMapperTest { } }.withMessage(Messages.getString("ERROR.45")) //$NON-NLS-1$ } - - @Test - fun testThatAliasesPropagateToSubQueryConditions() { - sqlSessionFactory.openSession().use { session -> - val mapper = session.getMapper(JoinMapper::class.java) - - val orderLine2 = OrderLineDynamicSQLSupport.OrderLine() - - val selectStatement = select(orderLine.orderId, orderLine.lineNumber) { - from(orderLine, "ol") - where { - orderLine.lineNumber isEqualTo { - select(max(orderLine2.lineNumber)) { - from(orderLine2, "ol2") - where { orderLine2.orderId isEqualTo orderLine.orderId } - } - } - } - orderBy(orderLine.orderId) - } - - val expectedStatement = "select ol.order_id, ol.line_number " + - "from OrderLine ol " + - "where ol.line_number = " + - "(select max(ol2.line_number) from OrderLine ol2 where ol2.order_id = ol.order_id) " + - "order by order_id" - - assertThat(selectStatement.selectStatement).isEqualTo(expectedStatement) - - val rows = mapper.selectManyMappedRows(selectStatement) - - assertThat(rows).hasSize(2) - - assertThat(rows[0]).containsOnly( - entry("ORDER_ID", 1), - entry("LINE_NUMBER", 2) - ) - - assertThat(rows[1]).containsOnly( - entry("ORDER_ID", 2), - entry("LINE_NUMBER", 3) - ) - } - } } diff --git a/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTemplateDirectTest.kt b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTemplateDirectTest.kt index 7157e709a..18b4f9922 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTemplateDirectTest.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTemplateDirectTest.kt @@ -577,8 +577,8 @@ open class CanonicalSpringKotlinTemplateDirectTest { address.id, address.streetAddress, address.city, address.state ) { from(person, "p") - join(address, "a") { - on(addressId) equalTo address.id + join(address, "a") on { + addressId isEqualTo address.id } where { id isLessThan 4 } orderBy(id) diff --git a/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt index 7b9093892..23c6e8058 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt @@ -1122,8 +1122,8 @@ open class CanonicalSpringKotlinTest { address.streetAddress, address.city, address.state ) { from(person, "p") - join(address, "a") { - on(addressId) equalTo address.id + join(address, "a") on { + addressId isEqualTo address.id } where { id isLessThan 4 } orderBy(id) From d401491f66468dd074c6612f20907137dd2fd3ed Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 24 Oct 2024 17:12:25 -0400 Subject: [PATCH 104/260] Various Sonar warning cleanup --- .../array/StringArrayTypeHandler.java | 3 +- .../examples/complexquery/GroupingTest.java | 58 +++++++++---------- .../always/mybatis/GeneratedAlwaysMapper.java | 4 +- .../java/examples/simple/PersonMapper.java | 8 +-- .../simple/PersonWithAddressMapper.java | 4 +- .../examples/spring/SpringMapToRowTest.java | 1 - .../java/issues/gh324/NameTableMapper.java | 4 +- .../sql/where/condition/FilterAndMapTest.java | 13 ++--- 8 files changed, 46 insertions(+), 49 deletions(-) diff --git a/src/test/java/examples/array/StringArrayTypeHandler.java b/src/test/java/examples/array/StringArrayTypeHandler.java index 50f2d2907..238124a58 100644 --- a/src/test/java/examples/array/StringArrayTypeHandler.java +++ b/src/test/java/examples/array/StringArrayTypeHandler.java @@ -22,7 +22,6 @@ import java.sql.SQLException; import java.util.Arrays; import java.util.List; -import java.util.stream.Collectors; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; @@ -59,7 +58,7 @@ private String[] extractArray(Array array) throws SQLException { List<String> stringList = Arrays.stream(objArray) .map(Object::toString) - .collect(Collectors.toList()); + .toList(); String[] stringArray = new String[stringList.size()]; return stringList.toArray(stringArray); diff --git a/src/test/java/examples/complexquery/GroupingTest.java b/src/test/java/examples/complexquery/GroupingTest.java index c7e09c467..683fa9d11 100644 --- a/src/test/java/examples/complexquery/GroupingTest.java +++ b/src/test/java/examples/complexquery/GroupingTest.java @@ -33,9 +33,9 @@ class GroupingTest { private static class Foo extends SqlTable { - public SqlColumn<Integer> A = column("A"); - public SqlColumn<Integer> B = column("B"); - public SqlColumn<Integer> C = column("C"); + public SqlColumn<Integer> columnA = column("A"); + public SqlColumn<Integer> columnB = column("B"); + public SqlColumn<Integer> columnC = column("C"); public Foo() { super("Foo"); @@ -43,16 +43,16 @@ public Foo() { } private static final Foo foo = new Foo(); - private static final SqlColumn<Integer> A = foo.A; - private static final SqlColumn<Integer> B = foo.B; - private static final SqlColumn<Integer> C = foo.C; + private static final SqlColumn<Integer> columnA = foo.columnA; + private static final SqlColumn<Integer> columnB = foo.columnB; + private static final SqlColumn<Integer> columnC = foo.columnC; @Test void testSimpleGrouping() { - SelectStatementProvider selectStatement = select(A, B, C) + SelectStatementProvider selectStatement = select(columnA, columnB, columnC) .from(foo) - .where(A, isEqualTo(1), or(A, isEqualTo(2))) - .and(B, isEqualTo(3)) + .where(columnA, isEqualTo(1), or(columnA, isEqualTo(2))) + .and(columnB, isEqualTo(3)) .build() .render(RenderingStrategies.MYBATIS3); @@ -68,14 +68,14 @@ void testSimpleGrouping() { @Test void testComplexGrouping() { - SelectStatementProvider selectStatement = select(A, B, C) + SelectStatementProvider selectStatement = select(columnA, columnB, columnC) .from(foo) .where( - group(A, isEqualTo(1), or(A, isGreaterThan(5))), - and(B, isEqualTo(1)), - or(A, isLessThan(0), and(B, isEqualTo(2))) + group(columnA, isEqualTo(1), or(columnA, isGreaterThan(5))), + and(columnB, isEqualTo(1)), + or(columnA, isLessThan(0), and(columnB, isEqualTo(2))) ) - .and(C, isEqualTo(1)) + .and(columnC, isEqualTo(1)) .build() .render(RenderingStrategies.MYBATIS3); @@ -94,14 +94,14 @@ void testComplexGrouping() { @Test void testGroupAndExists() { - SelectStatementProvider selectStatement = select(A, B, C) + SelectStatementProvider selectStatement = select(columnA, columnB, columnC) .from(foo) .where( - group(exists(select(foo.allColumns()).from(foo).where(A, isEqualTo(3))), and (A, isEqualTo(1)), or(A, isGreaterThan(5))), - and(B, isEqualTo(1)), - or(A, isLessThan(0), and(B, isEqualTo(2))) + group(exists(select(foo.allColumns()).from(foo).where(columnA, isEqualTo(3))), and (columnA, isEqualTo(1)), or(columnA, isGreaterThan(5))), + and(columnB, isEqualTo(1)), + or(columnA, isLessThan(0), and(columnB, isEqualTo(2))) ) - .and(C, isEqualTo(1)) + .and(columnC, isEqualTo(1)) .build() .render(RenderingStrategies.MYBATIS3); @@ -121,14 +121,14 @@ void testGroupAndExists() { @Test void testNestedGrouping() { - SelectStatementProvider selectStatement = select(A, B, C) + SelectStatementProvider selectStatement = select(columnA, columnB, columnC) .from(foo) .where( - group(group(A, isEqualTo(1), or(A, isGreaterThan(5))), and(A, isGreaterThan(5))), - and(group(A, isEqualTo(1), or(A, isGreaterThan(5))), or(B, isEqualTo(1))), - or(group(A, isEqualTo(1), or(A, isGreaterThan(5))), and(A, isLessThan(0), and(B, isEqualTo(2)))) + group(group(columnA, isEqualTo(1), or(columnA, isGreaterThan(5))), and(columnA, isGreaterThan(5))), + and(group(columnA, isEqualTo(1), or(columnA, isGreaterThan(5))), or(columnB, isEqualTo(1))), + or(group(columnA, isEqualTo(1), or(columnA, isGreaterThan(5))), and(columnA, isLessThan(0), and(columnB, isEqualTo(2)))) ) - .and(C, isEqualTo(1)) + .and(columnC, isEqualTo(1)) .build() .render(RenderingStrategies.MYBATIS3); @@ -152,12 +152,12 @@ void testNestedGrouping() { @Test void testAndOrCriteriaGroups() { - SelectStatementProvider selectStatement = select(A, B, C) + SelectStatementProvider selectStatement = select(columnA, columnB, columnC) .from(foo) - .where(A, isEqualTo(6)) - .and(C, isEqualTo(1)) - .and(group(A, isEqualTo(1), or(A, isGreaterThan(5))), or(B, isEqualTo(1))) - .or(group(A, isEqualTo(1), or(A, isGreaterThan(5))), and(A, isLessThan(0), and(B, isEqualTo(2)))) + .where(columnA, isEqualTo(6)) + .and(columnC, isEqualTo(1)) + .and(group(columnA, isEqualTo(1), or(columnA, isGreaterThan(5))), or(columnB, isEqualTo(1))) + .or(group(columnA, isEqualTo(1), or(columnA, isGreaterThan(5))), and(columnA, isLessThan(0), and(columnB, isEqualTo(2)))) .build() .render(RenderingStrategies.MYBATIS3); diff --git a/src/test/java/examples/generated/always/mybatis/GeneratedAlwaysMapper.java b/src/test/java/examples/generated/always/mybatis/GeneratedAlwaysMapper.java index ac2f7f86b..38521f063 100644 --- a/src/test/java/examples/generated/always/mybatis/GeneratedAlwaysMapper.java +++ b/src/test/java/examples/generated/always/mybatis/GeneratedAlwaysMapper.java @@ -76,8 +76,8 @@ default List<GeneratedAlwaysRecord> select(SelectDSLCompleter completer) { return MyBatis3Utils.selectList(this::selectMany, selectList, generatedAlways, completer); } - default Optional<GeneratedAlwaysRecord> selectByPrimaryKey(Integer _id) { - return selectOne(c -> c.where(id, isEqualTo(_id))); + default Optional<GeneratedAlwaysRecord> selectByPrimaryKey(Integer recordId) { + return selectOne(c -> c.where(id, isEqualTo(recordId))); } default int insert(GeneratedAlwaysRecord row) { diff --git a/src/test/java/examples/simple/PersonMapper.java b/src/test/java/examples/simple/PersonMapper.java index bb9560f75..d31f4af1a 100644 --- a/src/test/java/examples/simple/PersonMapper.java +++ b/src/test/java/examples/simple/PersonMapper.java @@ -90,9 +90,9 @@ default int delete(DeleteDSLCompleter completer) { return MyBatis3Utils.deleteFrom(this::delete, person, completer); } - default int deleteByPrimaryKey(Integer id_) { + default int deleteByPrimaryKey(Integer recordId) { return delete(c -> - c.where(id, isEqualTo(id_)) + c.where(id, isEqualTo(recordId)) ); } @@ -152,9 +152,9 @@ default List<PersonRecord> selectDistinct(SelectDSLCompleter completer) { return MyBatis3Utils.selectDistinct(this::selectMany, selectList, person, completer); } - default Optional<PersonRecord> selectByPrimaryKey(Integer id_) { + default Optional<PersonRecord> selectByPrimaryKey(Integer recordId) { return selectOne(c -> - c.where(id, isEqualTo(id_)) + c.where(id, isEqualTo(recordId)) ); } diff --git a/src/test/java/examples/simple/PersonWithAddressMapper.java b/src/test/java/examples/simple/PersonWithAddressMapper.java index 5a51cf465..dc47df896 100644 --- a/src/test/java/examples/simple/PersonWithAddressMapper.java +++ b/src/test/java/examples/simple/PersonWithAddressMapper.java @@ -90,9 +90,9 @@ default List<PersonWithAddress> select(SelectDSLCompleter completer) { return MyBatis3Utils.selectList(this::selectMany, start, completer); } - default Optional<PersonWithAddress> selectByPrimaryKey(Integer id_) { + default Optional<PersonWithAddress> selectByPrimaryKey(Integer recordId) { return selectOne(c -> - c.where(id, isEqualTo(id_)) + c.where(id, isEqualTo(recordId)) ); } diff --git a/src/test/java/examples/spring/SpringMapToRowTest.java b/src/test/java/examples/spring/SpringMapToRowTest.java index c3b1077c9..d87c67201 100644 --- a/src/test/java/examples/spring/SpringMapToRowTest.java +++ b/src/test/java/examples/spring/SpringMapToRowTest.java @@ -24,7 +24,6 @@ import static org.mybatis.dynamic.sql.SqlBuilder.insertMultiple; import static org.mybatis.dynamic.sql.SqlBuilder.select; -import java.util.ArrayList; import java.util.List; import java.util.stream.IntStream; diff --git a/src/test/java/issues/gh324/NameTableMapper.java b/src/test/java/issues/gh324/NameTableMapper.java index 1ba3d0428..6a71f7cc0 100644 --- a/src/test/java/issues/gh324/NameTableMapper.java +++ b/src/test/java/issues/gh324/NameTableMapper.java @@ -49,9 +49,9 @@ default Optional<NameRecord> selectOne(SelectDSLCompleter completer) { return MyBatis3Utils.selectOne(this::selectOne, selectList, nameTable, completer); } - default Optional<NameRecord> selectByPrimaryKey(Integer id_) { + default Optional<NameRecord> selectByPrimaryKey(Integer recordId) { return selectOne(c -> - c.where(id, isEqualTo(id_)) + c.where(id, isEqualTo(recordId)) ); } diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java index 3e35af01b..3ab419b33 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.SqlBuilder; @@ -432,7 +431,7 @@ void testIsInRenderableMapShouldReturnMappedObject() { IsIn<String> cond = SqlBuilder.isIn("Fred", "Wilma"); assertThat(cond.isEmpty()).isFalse(); IsIn<String> mapped = cond.map(String::toUpperCase); - List<String> mappedValues = mapped.values().collect(Collectors.toList()); + List<String> mappedValues = mapped.values().toList(); assertThat(mappedValues).containsExactly("FRED", "WILMA"); } @@ -441,31 +440,31 @@ void testIsNotInRenderableMapShouldReturnMappedObject() { IsNotIn<String> cond = SqlBuilder.isNotIn("Fred", "Wilma"); assertThat(cond.isEmpty()).isFalse(); IsNotIn<String> mapped = cond.map(String::toUpperCase); - List<String> mappedValues = mapped.values().collect(Collectors.toList()); + List<String> mappedValues = mapped.values().toList(); assertThat(mappedValues).containsExactly("FRED", "WILMA"); } @Test void testIsNotInCaseInsensitiveRenderableMapShouldReturnMappedObject() { IsNotInCaseInsensitive cond = SqlBuilder.isNotInCaseInsensitive("Fred ", "Wilma "); - List<String> values = cond.values().collect(Collectors.toList()); + List<String> values = cond.values().toList(); assertThat(values).containsExactly("FRED ", "WILMA "); assertThat(cond.isEmpty()).isFalse(); IsNotInCaseInsensitive mapped = cond.map(String::trim); - List<String> mappedValues = mapped.values().collect(Collectors.toList()); + List<String> mappedValues = mapped.values().toList(); assertThat(mappedValues).containsExactly("FRED", "WILMA"); } @Test void testIsInCaseInsensitiveRenderableMapShouldReturnMappedObject() { IsInCaseInsensitive cond = SqlBuilder.isInCaseInsensitive("Fred ", "Wilma "); - List<String> values = cond.values().collect(Collectors.toList()); + List<String> values = cond.values().toList(); assertThat(values).containsExactly("FRED ", "WILMA "); assertThat(cond.isEmpty()).isFalse(); IsInCaseInsensitive mapped = cond.map(String::trim); - List<String> mappedValues = mapped.values().collect(Collectors.toList()); + List<String> mappedValues = mapped.values().toList(); assertThat(mappedValues).containsExactly("FRED", "WILMA"); } From ecea6da4eec7128199237bb9a5d4164dbff24e5e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 25 Oct 2024 00:36:25 +0000 Subject: [PATCH 105/260] Update dependency org.mariadb.jdbc:mariadb-java-client to v3.5.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8f73f520e..30c8fd38f 100644 --- a/pom.xml +++ b/pom.xml @@ -195,7 +195,7 @@ <dependency> <groupId>org.mariadb.jdbc</groupId> <artifactId>mariadb-java-client</artifactId> - <version>3.4.1</version> + <version>3.5.0</version> <scope>test</scope> </dependency> </dependencies> From 163e7a03b082e1eb1c56715504621baa568c7594 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 25 Oct 2024 21:54:35 +0000 Subject: [PATCH 106/260] Update dependency ch.qos.logback:logback-classic to v1.5.12 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 30c8fd38f..994ba2058 100644 --- a/pom.xml +++ b/pom.xml @@ -165,7 +165,7 @@ <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> - <version>1.5.11</version> + <version>1.5.12</version> <scope>test</scope> </dependency> <dependency> From 16593d3c58e46111677bf98f10afc91866894aee Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 25 Oct 2024 18:10:05 -0400 Subject: [PATCH 107/260] Refactor to remove renderer cycles --- .../dynamic/sql/delete/DeleteModel.java | 9 +- .../dynamic/sql/insert/BatchInsertModel.java | 8 +- .../sql/insert/GeneralInsertModel.java | 9 +- .../dynamic/sql/insert/InsertModel.java | 8 +- .../dynamic/sql/insert/InsertSelectModel.java | 9 +- .../sql/insert/MultiRowInsertModel.java | 8 +- .../dynamic/sql/render/Renderable.java | 21 +++ .../dynamic/sql/render/RendererFactory.java | 135 ++++++++++++++++++ .../dynamic/sql/select/MultiSelectModel.java | 10 +- .../dynamic/sql/select/SelectModel.java | 13 +- .../dynamic/sql/update/UpdateModel.java | 9 +- 11 files changed, 184 insertions(+), 55 deletions(-) create mode 100644 src/main/java/org/mybatis/dynamic/sql/render/Renderable.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java diff --git a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java index 54770d5d4..015f9823c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java @@ -23,8 +23,8 @@ import org.mybatis.dynamic.sql.common.CommonBuilder; import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; -import org.mybatis.dynamic.sql.delete.render.DeleteRenderer; import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider; +import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.where.EmbeddedWhereModel; @@ -67,11 +67,8 @@ public Optional<OrderByModel> orderByModel() { @NotNull public DeleteStatementProvider render(RenderingStrategy renderingStrategy) { - return DeleteRenderer.withDeleteModel(this) - .withRenderingStrategy(renderingStrategy) - .withStatementConfiguration(statementConfiguration) - .build() - .render(); + return RendererFactory.createDeleteRenderer(this, statementConfiguration) + .render(renderingStrategy); } public static Builder withTable(SqlTable table) { diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java index b591753a2..5e48e9035 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java @@ -19,7 +19,7 @@ import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.insert.render.BatchInsert; -import org.mybatis.dynamic.sql.insert.render.BatchInsertRenderer; +import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.util.Validator; @@ -33,10 +33,8 @@ private BatchInsertModel(Builder<T> builder) { @NotNull public BatchInsert<T> render(RenderingStrategy renderingStrategy) { - return BatchInsertRenderer.withBatchInsertModel(this) - .withRenderingStrategy(renderingStrategy) - .build() - .render(); + return RendererFactory.createBatchInsertRenderer(this) + .render(renderingStrategy); } public static <T> Builder<T> withRecords(Collection<T> records) { diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java index 7f219027d..f3fb146ee 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java @@ -23,8 +23,8 @@ import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; -import org.mybatis.dynamic.sql.insert.render.GeneralInsertRenderer; import org.mybatis.dynamic.sql.insert.render.GeneralInsertStatementProvider; +import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.util.AbstractColumnMapping; import org.mybatis.dynamic.sql.util.Validator; @@ -52,11 +52,8 @@ public SqlTable table() { @NotNull public GeneralInsertStatementProvider render(RenderingStrategy renderingStrategy) { - return GeneralInsertRenderer.withInsertModel(this) - .withRenderingStrategy(renderingStrategy) - .withStatementConfiguration(statementConfiguration) - .build() - .render(); + return RendererFactory.createGeneralInsertRenderer(this, statementConfiguration) + .render(renderingStrategy); } public static class Builder { diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/InsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/InsertModel.java index 7f740051e..07fac79ed 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/InsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/InsertModel.java @@ -22,8 +22,8 @@ import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.SqlTable; -import org.mybatis.dynamic.sql.insert.render.InsertRenderer; import org.mybatis.dynamic.sql.insert.render.InsertStatementProvider; +import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.util.AbstractColumnMapping; import org.mybatis.dynamic.sql.util.Validator; @@ -54,10 +54,8 @@ public SqlTable table() { @NotNull public InsertStatementProvider<T> render(RenderingStrategy renderingStrategy) { - return InsertRenderer.withInsertModel(this) - .withRenderingStrategy(renderingStrategy) - .build() - .render(); + return RendererFactory.createInsertRenderer(this) + .render(renderingStrategy); } public static <T> Builder<T> withRow(T row) { diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java index 4da2cef1c..5b22eaeb7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java @@ -21,8 +21,8 @@ import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; -import org.mybatis.dynamic.sql.insert.render.InsertSelectRenderer; import org.mybatis.dynamic.sql.insert.render.InsertSelectStatementProvider; +import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.select.SelectModel; @@ -53,11 +53,8 @@ public Optional<InsertColumnListModel> columnList() { @NotNull public InsertSelectStatementProvider render(RenderingStrategy renderingStrategy) { - return InsertSelectRenderer.withInsertSelectModel(this) - .withRenderingStrategy(renderingStrategy) - .withStatementConfiguration(statementConfiguration) - .build() - .render(); + return RendererFactory.createInsertSelectRenderer(this, statementConfiguration) + .render(renderingStrategy); } public static Builder withTable(SqlTable table) { diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertModel.java index 406c02b7a..d5d7f478d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertModel.java @@ -18,8 +18,8 @@ import java.util.Collection; import org.jetbrains.annotations.NotNull; -import org.mybatis.dynamic.sql.insert.render.MultiRowInsertRenderer; import org.mybatis.dynamic.sql.insert.render.MultiRowInsertStatementProvider; +import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.util.Validator; @@ -33,10 +33,8 @@ private MultiRowInsertModel(Builder<T> builder) { @NotNull public MultiRowInsertStatementProvider<T> render(RenderingStrategy renderingStrategy) { - return MultiRowInsertRenderer.withMultiRowInsertModel(this) - .withRenderingStrategy(renderingStrategy) - .build() - .render(); + return RendererFactory.createMultiRowInsertRenderer(this) + .render(renderingStrategy); } public static <T> Builder<T> withRecords(Collection<T> records) { diff --git a/src/main/java/org/mybatis/dynamic/sql/render/Renderable.java b/src/main/java/org/mybatis/dynamic/sql/render/Renderable.java new file mode 100644 index 000000000..da999bfb8 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/render/Renderable.java @@ -0,0 +1,21 @@ +/* + * Copyright 2016-2024 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 + * + * https://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.render; + +@FunctionalInterface +public interface Renderable<T, R> { + R render(T t); +} diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java new file mode 100644 index 000000000..2b8208272 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java @@ -0,0 +1,135 @@ +/* + * Copyright 2016-2024 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 + * + * https://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.render; + +import org.mybatis.dynamic.sql.configuration.StatementConfiguration; +import org.mybatis.dynamic.sql.delete.DeleteModel; +import org.mybatis.dynamic.sql.delete.render.DeleteRenderer; +import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider; +import org.mybatis.dynamic.sql.insert.BatchInsertModel; +import org.mybatis.dynamic.sql.insert.GeneralInsertModel; +import org.mybatis.dynamic.sql.insert.InsertModel; +import org.mybatis.dynamic.sql.insert.InsertSelectModel; +import org.mybatis.dynamic.sql.insert.MultiRowInsertModel; +import org.mybatis.dynamic.sql.insert.render.BatchInsert; +import org.mybatis.dynamic.sql.insert.render.BatchInsertRenderer; +import org.mybatis.dynamic.sql.insert.render.GeneralInsertRenderer; +import org.mybatis.dynamic.sql.insert.render.GeneralInsertStatementProvider; +import org.mybatis.dynamic.sql.insert.render.InsertRenderer; +import org.mybatis.dynamic.sql.insert.render.InsertSelectRenderer; +import org.mybatis.dynamic.sql.insert.render.InsertSelectStatementProvider; +import org.mybatis.dynamic.sql.insert.render.InsertStatementProvider; +import org.mybatis.dynamic.sql.insert.render.MultiRowInsertRenderer; +import org.mybatis.dynamic.sql.insert.render.MultiRowInsertStatementProvider; +import org.mybatis.dynamic.sql.select.MultiSelectModel; +import org.mybatis.dynamic.sql.select.SelectModel; +import org.mybatis.dynamic.sql.select.render.MultiSelectRenderer; +import org.mybatis.dynamic.sql.select.render.SelectRenderer; +import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; +import org.mybatis.dynamic.sql.update.UpdateModel; +import org.mybatis.dynamic.sql.update.render.UpdateRenderer; +import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider; + +public interface RendererFactory { + static Renderable<RenderingStrategy, DeleteStatementProvider> createDeleteRenderer(DeleteModel deleteModel, + StatementConfiguration statementConfiguration) { + return renderingStrategy -> DeleteRenderer.withDeleteModel(deleteModel) + .withStatementConfiguration(statementConfiguration) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); + } + + static <T> Renderable<RenderingStrategy, BatchInsert<T>> createBatchInsertRenderer( + BatchInsertModel<T> batchInsertModel) { + return renderingStrategy -> BatchInsertRenderer.withBatchInsertModel(batchInsertModel) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); + } + + static Renderable<RenderingStrategy, GeneralInsertStatementProvider> createGeneralInsertRenderer( + GeneralInsertModel generalInsertModel, StatementConfiguration statementConfiguration) { + return renderingStrategy -> GeneralInsertRenderer.withInsertModel(generalInsertModel) + .withStatementConfiguration(statementConfiguration) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); + } + + static <T> Renderable<RenderingStrategy, InsertStatementProvider<T>> createInsertRenderer( + InsertModel<T> insertModel) { + return renderingStrategy -> InsertRenderer.withInsertModel(insertModel) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); + } + + static Renderable<RenderingStrategy, InsertSelectStatementProvider> createInsertSelectRenderer( + InsertSelectModel insertSelectModel, StatementConfiguration statementConfiguration) { + return renderingStrategy -> InsertSelectRenderer.withInsertSelectModel(insertSelectModel) + .withStatementConfiguration(statementConfiguration) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); + } + + static <T> Renderable<RenderingStrategy, MultiRowInsertStatementProvider<T>> createMultiRowInsertRenderer( + MultiRowInsertModel<T> multiRowInsertModel) { + return renderingStrategy -> MultiRowInsertRenderer.withMultiRowInsertModel(multiRowInsertModel) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); + } + + static Renderable<RenderingStrategy, SelectStatementProvider> createMultiSelectRenderer( + MultiSelectModel multiSelectModel, StatementConfiguration statementConfiguration) { + return renderingStrategy -> new MultiSelectRenderer.Builder() + .withMultiSelectModel(multiSelectModel) + .withStatementConfiguration(statementConfiguration) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); + } + + static Renderable<RenderingStrategy, SelectStatementProvider> createSelectRenderer( + SelectModel selectModel, StatementConfiguration statementConfiguration) { + return renderingStrategy -> { + RenderingContext renderingContext = RenderingContext.withRenderingStrategy(renderingStrategy) + .withStatementConfiguration(statementConfiguration) + .build(); + + return createSelectRenderer(selectModel).render(renderingContext); + }; + } + + static Renderable<RenderingContext, SelectStatementProvider> createSelectRenderer( + SelectModel selectModel) { + return renderingContext -> SelectRenderer.withSelectModel(selectModel) + .withRenderingContext(renderingContext) + .build() + .render(); + } + + static Renderable<RenderingStrategy, UpdateStatementProvider> createUpdateRenderer( + UpdateModel updateModel, StatementConfiguration statementConfiguration) { + return renderingStrategy -> UpdateRenderer.withUpdateModel(updateModel) + .withStatementConfiguration(statementConfiguration) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); + } +} diff --git a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java index f9a1a388a..607378c20 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java @@ -21,8 +21,8 @@ import java.util.stream.Stream; import org.jetbrains.annotations.NotNull; +import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingStrategy; -import org.mybatis.dynamic.sql.select.render.MultiSelectRenderer; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.mybatis.dynamic.sql.util.Validator; @@ -47,12 +47,8 @@ public Stream<UnionQuery> unionQueries() { @NotNull public SelectStatementProvider render(RenderingStrategy renderingStrategy) { - return new MultiSelectRenderer.Builder() - .withMultiSelectModel(this) - .withRenderingStrategy(renderingStrategy) - .withStatementConfiguration(statementConfiguration) - .build() - .render(); + return RendererFactory.createMultiSelectRenderer(this, statementConfiguration) + .render(renderingStrategy); } public static class Builder extends AbstractBuilder<Builder> { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java index 57fd06a43..32b745e0e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java @@ -21,9 +21,9 @@ import java.util.stream.Stream; import org.jetbrains.annotations.NotNull; +import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.render.RenderingStrategy; -import org.mybatis.dynamic.sql.select.render.SelectRenderer; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.mybatis.dynamic.sql.util.Validator; @@ -42,10 +42,8 @@ public Stream<QueryExpressionModel> queryExpressions() { @NotNull public SelectStatementProvider render(RenderingStrategy renderingStrategy) { - RenderingContext renderingContext = RenderingContext.withRenderingStrategy(renderingStrategy) - .withStatementConfiguration(statementConfiguration) - .build(); - return render(renderingContext); + return RendererFactory.createSelectRenderer(this, statementConfiguration) + .render(renderingStrategy); } /** @@ -56,10 +54,7 @@ public SelectStatementProvider render(RenderingStrategy renderingStrategy) { */ @NotNull public SelectStatementProvider render(RenderingContext renderingContext) { - return SelectRenderer.withSelectModel(this) - .withRenderingContext(renderingContext) - .build() - .render(); + return RendererFactory.createSelectRenderer(this).render(renderingContext); } public static Builder withQueryExpressions(List<QueryExpressionModel> queryExpressions) { diff --git a/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java b/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java index 7ff82df26..672b08c44 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java @@ -26,8 +26,8 @@ import org.mybatis.dynamic.sql.common.CommonBuilder; import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; +import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingStrategy; -import org.mybatis.dynamic.sql.update.render.UpdateRenderer; import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider; import org.mybatis.dynamic.sql.util.AbstractColumnMapping; import org.mybatis.dynamic.sql.util.Validator; @@ -79,11 +79,8 @@ public Optional<OrderByModel> orderByModel() { @NotNull public UpdateStatementProvider render(RenderingStrategy renderingStrategy) { - return UpdateRenderer.withUpdateModel(this) - .withRenderingStrategy(renderingStrategy) - .withStatementConfiguration(statementConfiguration) - .build() - .render(); + return RendererFactory.createUpdateRenderer(this, statementConfiguration) + .render(renderingStrategy); } public static Builder withTable(SqlTable table) { From df83f4331dec9579e7c29c5b39278bc82ecf7bcf Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Sun, 27 Oct 2024 14:32:12 -0400 Subject: [PATCH 108/260] Method reuse --- .../mybatis/dynamic/sql/render/RendererFactory.java | 11 ----------- .../org/mybatis/dynamic/sql/select/SelectModel.java | 6 ++++-- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java index 2b8208272..b925d8fde 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java @@ -105,17 +105,6 @@ static Renderable<RenderingStrategy, SelectStatementProvider> createMultiSelectR .render(); } - static Renderable<RenderingStrategy, SelectStatementProvider> createSelectRenderer( - SelectModel selectModel, StatementConfiguration statementConfiguration) { - return renderingStrategy -> { - RenderingContext renderingContext = RenderingContext.withRenderingStrategy(renderingStrategy) - .withStatementConfiguration(statementConfiguration) - .build(); - - return createSelectRenderer(selectModel).render(renderingContext); - }; - } - static Renderable<RenderingContext, SelectStatementProvider> createSelectRenderer( SelectModel selectModel) { return renderingContext -> SelectRenderer.withSelectModel(selectModel) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java index 32b745e0e..85196be7b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java @@ -42,8 +42,10 @@ public Stream<QueryExpressionModel> queryExpressions() { @NotNull public SelectStatementProvider render(RenderingStrategy renderingStrategy) { - return RendererFactory.createSelectRenderer(this, statementConfiguration) - .render(renderingStrategy); + RenderingContext renderingContext = RenderingContext.withRenderingStrategy(renderingStrategy) + .withStatementConfiguration(statementConfiguration) + .build(); + return render(renderingContext); } /** From 3ddf8bd601ac29dede66c4d2b521c79e54eb2b73 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 28 Oct 2024 09:35:50 -0400 Subject: [PATCH 109/260] Better name --- .../render/{Renderable.java => Renderer.java} | 2 +- .../dynamic/sql/render/RendererFactory.java | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) rename src/main/java/org/mybatis/dynamic/sql/render/{Renderable.java => Renderer.java} (95%) diff --git a/src/main/java/org/mybatis/dynamic/sql/render/Renderable.java b/src/main/java/org/mybatis/dynamic/sql/render/Renderer.java similarity index 95% rename from src/main/java/org/mybatis/dynamic/sql/render/Renderable.java rename to src/main/java/org/mybatis/dynamic/sql/render/Renderer.java index da999bfb8..acb84a98f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/Renderable.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/Renderer.java @@ -16,6 +16,6 @@ package org.mybatis.dynamic.sql.render; @FunctionalInterface -public interface Renderable<T, R> { +public interface Renderer<T, R> { R render(T t); } diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java index b925d8fde..c47ca1f78 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java @@ -44,8 +44,8 @@ import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider; public interface RendererFactory { - static Renderable<RenderingStrategy, DeleteStatementProvider> createDeleteRenderer(DeleteModel deleteModel, - StatementConfiguration statementConfiguration) { + static Renderer<RenderingStrategy, DeleteStatementProvider> createDeleteRenderer(DeleteModel deleteModel, + StatementConfiguration statementConfiguration) { return renderingStrategy -> DeleteRenderer.withDeleteModel(deleteModel) .withStatementConfiguration(statementConfiguration) .withRenderingStrategy(renderingStrategy) @@ -53,7 +53,7 @@ static Renderable<RenderingStrategy, DeleteStatementProvider> createDeleteRender .render(); } - static <T> Renderable<RenderingStrategy, BatchInsert<T>> createBatchInsertRenderer( + static <T> Renderer<RenderingStrategy, BatchInsert<T>> createBatchInsertRenderer( BatchInsertModel<T> batchInsertModel) { return renderingStrategy -> BatchInsertRenderer.withBatchInsertModel(batchInsertModel) .withRenderingStrategy(renderingStrategy) @@ -61,7 +61,7 @@ static <T> Renderable<RenderingStrategy, BatchInsert<T>> createBatchInsertRender .render(); } - static Renderable<RenderingStrategy, GeneralInsertStatementProvider> createGeneralInsertRenderer( + static Renderer<RenderingStrategy, GeneralInsertStatementProvider> createGeneralInsertRenderer( GeneralInsertModel generalInsertModel, StatementConfiguration statementConfiguration) { return renderingStrategy -> GeneralInsertRenderer.withInsertModel(generalInsertModel) .withStatementConfiguration(statementConfiguration) @@ -70,7 +70,7 @@ static Renderable<RenderingStrategy, GeneralInsertStatementProvider> createGener .render(); } - static <T> Renderable<RenderingStrategy, InsertStatementProvider<T>> createInsertRenderer( + static <T> Renderer<RenderingStrategy, InsertStatementProvider<T>> createInsertRenderer( InsertModel<T> insertModel) { return renderingStrategy -> InsertRenderer.withInsertModel(insertModel) .withRenderingStrategy(renderingStrategy) @@ -78,7 +78,7 @@ static <T> Renderable<RenderingStrategy, InsertStatementProvider<T>> createInser .render(); } - static Renderable<RenderingStrategy, InsertSelectStatementProvider> createInsertSelectRenderer( + static Renderer<RenderingStrategy, InsertSelectStatementProvider> createInsertSelectRenderer( InsertSelectModel insertSelectModel, StatementConfiguration statementConfiguration) { return renderingStrategy -> InsertSelectRenderer.withInsertSelectModel(insertSelectModel) .withStatementConfiguration(statementConfiguration) @@ -87,7 +87,7 @@ static Renderable<RenderingStrategy, InsertSelectStatementProvider> createInsert .render(); } - static <T> Renderable<RenderingStrategy, MultiRowInsertStatementProvider<T>> createMultiRowInsertRenderer( + static <T> Renderer<RenderingStrategy, MultiRowInsertStatementProvider<T>> createMultiRowInsertRenderer( MultiRowInsertModel<T> multiRowInsertModel) { return renderingStrategy -> MultiRowInsertRenderer.withMultiRowInsertModel(multiRowInsertModel) .withRenderingStrategy(renderingStrategy) @@ -95,7 +95,7 @@ static <T> Renderable<RenderingStrategy, MultiRowInsertStatementProvider<T>> cre .render(); } - static Renderable<RenderingStrategy, SelectStatementProvider> createMultiSelectRenderer( + static Renderer<RenderingStrategy, SelectStatementProvider> createMultiSelectRenderer( MultiSelectModel multiSelectModel, StatementConfiguration statementConfiguration) { return renderingStrategy -> new MultiSelectRenderer.Builder() .withMultiSelectModel(multiSelectModel) @@ -105,7 +105,7 @@ static Renderable<RenderingStrategy, SelectStatementProvider> createMultiSelectR .render(); } - static Renderable<RenderingContext, SelectStatementProvider> createSelectRenderer( + static Renderer<RenderingContext, SelectStatementProvider> createSelectRenderer( SelectModel selectModel) { return renderingContext -> SelectRenderer.withSelectModel(selectModel) .withRenderingContext(renderingContext) @@ -113,7 +113,7 @@ static Renderable<RenderingContext, SelectStatementProvider> createSelectRendere .render(); } - static Renderable<RenderingStrategy, UpdateStatementProvider> createUpdateRenderer( + static Renderer<RenderingStrategy, UpdateStatementProvider> createUpdateRenderer( UpdateModel updateModel, StatementConfiguration statementConfiguration) { return renderingStrategy -> UpdateRenderer.withUpdateModel(updateModel) .withStatementConfiguration(statementConfiguration) From 8d6b2264bd250d1e7b64c7dbb47721bd05eee424 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 3 Nov 2024 05:14:02 +0000 Subject: [PATCH 110/260] Update dependency org.hsqldb:hsqldb to v2.7.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 994ba2058..bb41c7c12 100644 --- a/pom.xml +++ b/pom.xml @@ -141,7 +141,7 @@ <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> - <version>2.7.3</version> + <version>2.7.4</version> <scope>test</scope> </dependency> <dependency> From ade363dacca6c22789aef6f18f4bffe1b6a40f30 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 15 Nov 2024 12:10:12 +0000 Subject: [PATCH 111/260] Update dependency org.springframework:spring-jdbc to v6.2.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bb41c7c12..fc513913c 100644 --- a/pom.xml +++ b/pom.xml @@ -96,7 +96,7 @@ <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> - <version>6.1.14</version> + <version>6.2.0</version> <scope>provided</scope> <optional>true</optional> </dependency> From 506d30e1c3fb169512f63e9c622503f277be8d89 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 18 Nov 2024 17:52:45 -0500 Subject: [PATCH 112/260] Use Fragment Mapping where it makes sense --- .../sql/select/render/QueryExpressionRenderer.java | 8 ++------ .../dynamic/sql/where/render/DefaultConditionVisitor.java | 8 ++------ src/test/java/examples/animal/data/Length.java | 7 ++----- src/test/java/examples/type_conversion/ToBase64.java | 7 ++----- 4 files changed, 8 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/QueryExpressionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/QueryExpressionRenderer.java index 0f3ddcb01..618ea2f9c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/QueryExpressionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/QueryExpressionRenderer.java @@ -139,12 +139,8 @@ private FragmentAndParameters calculateColumnList() { private FragmentAndParameters renderColumnAndAlias(BasicColumn selectListItem) { FragmentAndParameters renderedColumn = selectListItem.render(renderingContext); - String nameAndTableAlias = selectListItem.alias().map(a -> renderedColumn.fragment() + " as " + a) //$NON-NLS-1$ - .orElse(renderedColumn.fragment()); - - return FragmentAndParameters.withFragment(nameAndTableAlias) - .withParameters(renderedColumn.parameters()) - .build(); + return selectListItem.alias().map(a -> renderedColumn.mapFragment(f -> f + " as " + a)) //$NON-NLS-1$ + .orElse(renderedColumn); } private FragmentAndParameters renderTableExpression(TableExpression table) { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java index 9adda9f64..309a10f3b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java @@ -109,12 +109,8 @@ public FragmentAndParameters visit(AbstractSubselectCondition<T> condition) { @Override public FragmentAndParameters visit(AbstractColumnComparisonCondition<T> condition) { - FragmentAndParameters renderedRightColumn = condition.rightColumn().render(renderingContext); - String finalFragment = condition.operator() - + spaceBefore(renderedRightColumn.fragment()); - return FragmentAndParameters.withFragment(finalFragment) - .withParameters(renderedRightColumn.parameters()) - .build(); + return condition.rightColumn().render(renderingContext) + .mapFragment(f -> condition.operator() + spaceBefore(f)); } private Object convertValue(T value) { diff --git a/src/test/java/examples/animal/data/Length.java b/src/test/java/examples/animal/data/Length.java index 6fb90e40d..34bb7f3c9 100644 --- a/src/test/java/examples/animal/data/Length.java +++ b/src/test/java/examples/animal/data/Length.java @@ -36,11 +36,8 @@ public Optional<JDBCType> jdbcType() { @Override public FragmentAndParameters render(RenderingContext renderingContext) { - FragmentAndParameters renderedColumn = column.render(renderingContext); - - return FragmentAndParameters.withFragment("length(" + renderedColumn.fragment() + ")") //$NON-NLS-1$ //$NON-NLS-2$ - .withParameters(renderedColumn.parameters()) - .build(); + return column.render(renderingContext) + .mapFragment(f -> "length(" + f + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } @Override diff --git a/src/test/java/examples/type_conversion/ToBase64.java b/src/test/java/examples/type_conversion/ToBase64.java index ce5ab5891..42bfe40d1 100644 --- a/src/test/java/examples/type_conversion/ToBase64.java +++ b/src/test/java/examples/type_conversion/ToBase64.java @@ -37,11 +37,8 @@ public Optional<JDBCType> jdbcType() { @Override public FragmentAndParameters render(RenderingContext renderingContext) { - FragmentAndParameters renderedColumn = column.render(renderingContext); - - return FragmentAndParameters.withFragment("TO_BASE64(" + renderedColumn.fragment() + ")") //$NON-NLS-1$ //$NON-NLS-2$ - .withParameters(renderedColumn.parameters()) - .build(); + return column.render(renderingContext) + .mapFragment(f -> "TO_BASE64(" + f + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } @Override From 283f0a5f281cdb604e4f637b84111cb800089cee Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 19 Nov 2024 10:27:56 -0500 Subject: [PATCH 113/260] SelectRenderer should return FragmentAndParameters Many usages of the select renderer are for sub queries - no need to build an intermediate statement provider in those cases. --- .../insert/render/InsertSelectRenderer.java | 8 +++---- .../dynamic/sql/render/RendererFactory.java | 3 ++- .../dynamic/sql/select/SelectModel.java | 9 +++++-- .../select/render/MultiSelectRenderer.java | 16 ++++--------- .../sql/select/render/SelectRenderer.java | 11 ++------- .../render/TableExpressionRenderer.java | 11 ++------- .../sql/update/render/SetPhraseVisitor.java | 24 ++++--------------- .../sql/where/render/CriterionRenderer.java | 14 ++--------- .../where/render/DefaultConditionVisitor.java | 13 ++-------- 9 files changed, 30 insertions(+), 79 deletions(-) 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 16afe6767..3825d4e3d 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 @@ -27,7 +27,7 @@ import org.mybatis.dynamic.sql.insert.InsertSelectModel; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.render.RenderingStrategy; -import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.StringUtilities; public class InsertSelectRenderer { @@ -43,18 +43,18 @@ private InsertSelectRenderer(Builder builder) { } public InsertSelectStatementProvider render() { - SelectStatementProvider selectStatement = model.selectModel().render(renderingContext); + FragmentAndParameters selectStatement = model.selectModel().render(renderingContext); String statementStart = InsertRenderingUtilities.calculateInsertStatementStart(model.table()); Optional<String> columnsPhrase = calculateColumnsPhrase(); - String renderedSelectStatement = selectStatement.getSelectStatement(); + String renderedSelectStatement = selectStatement.fragment(); String insertStatement = statementStart + columnsPhrase.map(StringUtilities::spaceBefore).orElse("") //$NON-NLS-1$ + spaceBefore(renderedSelectStatement); return DefaultGeneralInsertStatementProvider.withInsertStatement(insertStatement) - .withParameters(selectStatement.getParameters()) + .withParameters(selectStatement.parameters()) .build(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java index c47ca1f78..0ac97d702 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java @@ -42,6 +42,7 @@ import org.mybatis.dynamic.sql.update.UpdateModel; import org.mybatis.dynamic.sql.update.render.UpdateRenderer; import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; public interface RendererFactory { static Renderer<RenderingStrategy, DeleteStatementProvider> createDeleteRenderer(DeleteModel deleteModel, @@ -105,7 +106,7 @@ static Renderer<RenderingStrategy, SelectStatementProvider> createMultiSelectRen .render(); } - static Renderer<RenderingContext, SelectStatementProvider> createSelectRenderer( + static Renderer<RenderingContext, FragmentAndParameters> createSelectRenderer( SelectModel selectModel) { return renderingContext -> SelectRenderer.withSelectModel(selectModel) .withRenderingContext(renderingContext) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java index 85196be7b..3dff3162e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java @@ -24,7 +24,9 @@ import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.render.RenderingStrategy; +import org.mybatis.dynamic.sql.select.render.DefaultSelectStatementProvider; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.Validator; public class SelectModel extends AbstractSelectModel { @@ -45,7 +47,10 @@ public SelectStatementProvider render(RenderingStrategy renderingStrategy) { RenderingContext renderingContext = RenderingContext.withRenderingStrategy(renderingStrategy) .withStatementConfiguration(statementConfiguration) .build(); - return render(renderingContext); + FragmentAndParameters fragmentAndParameters = render(renderingContext); + return DefaultSelectStatementProvider.withSelectStatement(fragmentAndParameters.fragment()) + .withParameters(fragmentAndParameters.parameters()) + .build(); } /** @@ -55,7 +60,7 @@ public SelectStatementProvider render(RenderingStrategy renderingStrategy) { * @return a rendered select statement and parameters */ @NotNull - public SelectStatementProvider render(RenderingContext renderingContext) { + public FragmentAndParameters render(RenderingContext renderingContext) { return RendererFactory.createSelectRenderer(this).render(renderingContext); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java index c063e7866..78d6ae8ff 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java @@ -65,21 +65,13 @@ private SelectStatementProvider toSelectStatementProvider(FragmentCollector frag } private FragmentAndParameters renderSelect(SelectModel selectModel) { - SelectStatementProvider selectStatement = selectModel.render(renderingContext); - - return FragmentAndParameters - .withFragment("(" + selectStatement.getSelectStatement() + ")") //$NON-NLS-1$ //$NON-NLS-2$ - .withParameters(selectStatement.getParameters()) - .build(); + return selectModel.render(renderingContext) + .mapFragment(f -> "(" + f + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } private FragmentAndParameters renderSelect(UnionQuery unionQuery) { - SelectStatementProvider selectStatement = unionQuery.selectModel().render(renderingContext); - - return FragmentAndParameters.withFragment( - unionQuery.connector() + " (" + selectStatement.getSelectStatement() + ")") //$NON-NLS-1$ //$NON-NLS-2$ - .withParameters(selectStatement.getParameters()) - .build(); + return unionQuery.selectModel().render(renderingContext) + .mapFragment(f -> unionQuery.connector() + " (" + f + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } private Optional<FragmentAndParameters> renderOrderBy() { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java index 128ab3e8e..25e2e408b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java @@ -37,7 +37,7 @@ private SelectRenderer(Builder builder) { renderingContext = Objects.requireNonNull(builder.renderingContext); } - public SelectStatementProvider render() { + public FragmentAndParameters render() { FragmentCollector fragmentCollector = selectModel .queryExpressions() .map(this::renderQueryExpression) @@ -46,14 +46,7 @@ public SelectStatementProvider render() { renderOrderBy().ifPresent(fragmentCollector::add); renderPagingModel().ifPresent(fragmentCollector::add); - return toSelectStatementProvider(fragmentCollector); - } - - private SelectStatementProvider toSelectStatementProvider(FragmentCollector fragmentCollector) { - return DefaultSelectStatementProvider - .withSelectStatement(fragmentCollector.collectFragments(Collectors.joining(" "))) //$NON-NLS-1$ - .withParameters(fragmentCollector.parameters()) - .build(); + return fragmentCollector.toFragmentAndParameters(Collectors.joining(" ")); //$NON-NLS-1$ } private FragmentAndParameters renderQueryExpression(QueryExpressionModel queryExpressionModel) { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java index ccb9b1d84..3ba013825 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java @@ -39,15 +39,8 @@ public FragmentAndParameters visit(SqlTable table) { @Override public FragmentAndParameters visit(SubQuery subQuery) { - SelectStatementProvider selectStatement = subQuery.selectModel().render(renderingContext); - - String fragment = "(" + selectStatement.getSelectStatement() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ - - fragment = applyAlias(fragment, subQuery); - - return FragmentAndParameters.withFragment(fragment) - .withParameters(selectStatement.getParameters()) - .build(); + return subQuery.selectModel().render(renderingContext) + .mapFragment(f -> applyAlias("(" + f + ")", subQuery)); //$NON-NLS-1$ //$NON-NLS-2$ } private String applyAlias(String fragment, SubQuery subQuery) { diff --git a/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java b/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java index 07d955c80..77a898ea2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java @@ -20,7 +20,6 @@ import org.mybatis.dynamic.sql.render.RenderedParameterInfo; import org.mybatis.dynamic.sql.render.RenderingContext; -import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.mybatis.dynamic.sql.util.AbstractColumnMapping; import org.mybatis.dynamic.sql.util.ColumnToColumnMapping; import org.mybatis.dynamic.sql.util.ConstantMapping; @@ -84,28 +83,15 @@ public <T> Optional<FragmentAndParameters> visit(ValueWhenPresentMapping<T> mapp @Override public Optional<FragmentAndParameters> visit(SelectMapping mapping) { - SelectStatementProvider selectStatement = mapping.selectModel().render(renderingContext); - String fragment = renderingContext.aliasedColumnName(mapping.column()) - + " = (" //$NON-NLS-1$ - + selectStatement.getSelectStatement() - + ")"; //$NON-NLS-1$ - - return FragmentAndParameters.withFragment(fragment) - .withParameters(selectStatement.getParameters()) - .buildOptional(); + return Optional.of(mapping.selectModel().render(renderingContext) + .mapFragment(f -> renderingContext.aliasedColumnName(mapping.column()) + + " = (" + f + ")")); //$NON-NLS-1$ //$NON-NLS-2$ } @Override public Optional<FragmentAndParameters> visit(ColumnToColumnMapping mapping) { - FragmentAndParameters renderedColumn = mapping.rightColumn().render(renderingContext); - - String setPhrase = renderingContext.aliasedColumnName(mapping.column()) - + " = " //$NON-NLS-1$ - + renderedColumn.fragment(); - - return FragmentAndParameters.withFragment(setPhrase) - .withParameters(renderedColumn.parameters()) - .buildOptional(); + return Optional.of(mapping.rightColumn().render(renderingContext) + .mapFragment(f -> renderingContext.aliasedColumnName(mapping.column()) + " = " + f)); //$NON-NLS-1$ } private <T> Optional<FragmentAndParameters> buildValueFragment(AbstractColumnMapping mapping, T value) { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java index 0e4325179..f56fc3e79 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java @@ -30,7 +30,6 @@ import org.mybatis.dynamic.sql.SqlCriterion; import org.mybatis.dynamic.sql.SqlCriterionVisitor; import org.mybatis.dynamic.sql.render.RenderingContext; -import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.FragmentCollector; @@ -120,17 +119,8 @@ private <T> Optional<FragmentAndParameters> renderColumnAndCondition(ColumnAndCo private FragmentAndParameters renderExists(ExistsCriterion criterion) { ExistsPredicate existsPredicate = criterion.existsPredicate(); - SelectStatementProvider selectStatement = existsPredicate.selectModelBuilder().build().render(renderingContext); - - String fragment = existsPredicate.operator() - + " (" //$NON-NLS-1$ - + selectStatement.getSelectStatement() - + ")"; //$NON-NLS-1$ - - return FragmentAndParameters - .withFragment(fragment) - .withParameters(selectStatement.getParameters()) - .build(); + return existsPredicate.selectModelBuilder().build().render(renderingContext) + .mapFragment(f -> existsPredicate.operator() + " (" + f + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } private List<RenderedCriterion> renderSubCriteria(List<AndOrCriteriaGroup> subCriteria) { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java index 309a10f3b..6bd518663 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java @@ -30,7 +30,6 @@ import org.mybatis.dynamic.sql.ConditionVisitor; import org.mybatis.dynamic.sql.render.RenderedParameterInfo; import org.mybatis.dynamic.sql.render.RenderingContext; -import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.FragmentCollector; @@ -95,16 +94,8 @@ public FragmentAndParameters visit(AbstractTwoValueCondition<T> condition) { @Override public FragmentAndParameters visit(AbstractSubselectCondition<T> condition) { - SelectStatementProvider selectStatement = condition.selectModel().render(renderingContext); - - String finalFragment = condition.operator() - + " (" //$NON-NLS-1$ - + selectStatement.getSelectStatement() - + ")"; //$NON-NLS-1$ - - return FragmentAndParameters.withFragment(finalFragment) - .withParameters(selectStatement.getParameters()) - .build(); + return condition.selectModel().render(renderingContext) + .mapFragment(f -> condition.operator() + " (" + f + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } @Override From d4c3d113321ba6b4ea76b8d2bd8d63240fc96250 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 22:01:20 +0000 Subject: [PATCH 114/260] Update dependency org.mariadb.jdbc:mariadb-java-client to v3.5.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fc513913c..ab0869db9 100644 --- a/pom.xml +++ b/pom.xml @@ -195,7 +195,7 @@ <dependency> <groupId>org.mariadb.jdbc</groupId> <artifactId>mariadb-java-client</artifactId> - <version>3.5.0</version> + <version>3.5.1</version> <scope>test</scope> </dependency> </dependencies> From fd9f44e35d83b80d222c61b3f52486873edec04b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 20 Nov 2024 22:43:02 +0000 Subject: [PATCH 115/260] Update dependency org.testcontainers:postgresql to v1.20.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ab0869db9..441e52cb5 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ <sonar.tests>src/test/java,src/test/kotlin</sonar.tests> <kotlin.code.style>official</kotlin.code.style> - <test.containers.version>1.20.3</test.containers.version> + <test.containers.version>1.20.4</test.containers.version> <osgi.export>org.mybatis.dynamic.sql.*;version=${project.version};-noimport:=true</osgi.export> <!-- Reproducible Builds --> From 9aab3fabf735945ed9928c4e81c42db240460830 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 21 Nov 2024 14:38:47 +0000 Subject: [PATCH 116/260] Update dependency org.springframework.batch:spring-batch-core to v5.2.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 441e52cb5..d914073b2 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ <java.test.version>17</java.test.version> <java.test.release.version>17</java.test.release.version> <junit.jupiter.version>5.11.3</junit.jupiter.version> - <spring.batch.version>5.1.2</spring.batch.version> + <spring.batch.version>5.2.0</spring.batch.version> <checkstyle.config>checkstyle-override.xml</checkstyle.config> From d8f631b1aa9bf04bf6d9e97caa08248c528199f4 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 22 Nov 2024 10:53:47 -0500 Subject: [PATCH 117/260] Simplify renderer factory --- .../dynamic/sql/delete/DeleteModel.java | 6 +++++- .../sql/delete/render/DeleteRenderer.java | 9 +------- .../sql/insert/GeneralInsertModel.java | 6 +++++- .../dynamic/sql/insert/InsertSelectModel.java | 6 +++++- .../insert/render/GeneralInsertRenderer.java | 9 +------- .../insert/render/InsertSelectRenderer.java | 9 +------- .../dynamic/sql/render/RendererFactory.java | 21 ++++++------------- .../sql/select/AbstractSelectModel.java | 4 ++++ .../dynamic/sql/select/MultiSelectModel.java | 2 +- .../select/render/MultiSelectRenderer.java | 11 ++-------- .../dynamic/sql/update/UpdateModel.java | 6 +++++- .../sql/update/render/UpdateRenderer.java | 9 +------- 12 files changed, 37 insertions(+), 61 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java index 015f9823c..581d2250a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java @@ -65,9 +65,13 @@ public Optional<OrderByModel> orderByModel() { return Optional.ofNullable(orderByModel); } + public StatementConfiguration statementConfiguration() { + return statementConfiguration; + } + @NotNull public DeleteStatementProvider render(RenderingStrategy renderingStrategy) { - return RendererFactory.createDeleteRenderer(this, statementConfiguration) + return RendererFactory.createDeleteRenderer(this) .render(renderingStrategy); } 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 fa4cd0d28..7b3dbfc97 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 @@ -21,7 +21,6 @@ import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.common.OrderByRenderer; -import org.mybatis.dynamic.sql.configuration.StatementConfiguration; import org.mybatis.dynamic.sql.delete.DeleteModel; import org.mybatis.dynamic.sql.render.ExplicitTableAliasCalculator; import org.mybatis.dynamic.sql.render.RenderedParameterInfo; @@ -44,7 +43,7 @@ private DeleteRenderer(Builder builder) { renderingContext = RenderingContext .withRenderingStrategy(Objects.requireNonNull(builder.renderingStrategy)) .withTableAliasCalculator(tableAliasCalculator) - .withStatementConfiguration(builder.statementConfiguration) + .withStatementConfiguration(deleteModel.statementConfiguration()) .build(); } @@ -106,7 +105,6 @@ public static Builder withDeleteModel(DeleteModel deleteModel) { public static class Builder { private DeleteModel deleteModel; private RenderingStrategy renderingStrategy; - private StatementConfiguration statementConfiguration; public Builder withDeleteModel(DeleteModel deleteModel) { this.deleteModel = deleteModel; @@ -118,11 +116,6 @@ public Builder withRenderingStrategy(RenderingStrategy renderingStrategy) { return this; } - public Builder withStatementConfiguration(StatementConfiguration statementConfiguration) { - this.statementConfiguration = statementConfiguration; - return this; - } - public DeleteRenderer build() { return new DeleteRenderer(this); } diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java index f3fb146ee..955d5fe7c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java @@ -50,9 +50,13 @@ public SqlTable table() { return table; } + public StatementConfiguration statementConfiguration() { + return statementConfiguration; + } + @NotNull public GeneralInsertStatementProvider render(RenderingStrategy renderingStrategy) { - return RendererFactory.createGeneralInsertRenderer(this, statementConfiguration) + return RendererFactory.createGeneralInsertRenderer(this) .render(renderingStrategy); } diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java index 5b22eaeb7..37df5e10e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java @@ -51,9 +51,13 @@ public Optional<InsertColumnListModel> columnList() { return Optional.ofNullable(columnList); } + public StatementConfiguration statementConfiguration() { + return statementConfiguration; + } + @NotNull public InsertSelectStatementProvider render(RenderingStrategy renderingStrategy) { - return RendererFactory.createInsertSelectRenderer(this, statementConfiguration) + return RendererFactory.createInsertSelectRenderer(this) .render(renderingStrategy); } diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertRenderer.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertRenderer.java index c5378b493..de91037a6 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertRenderer.java @@ -18,7 +18,6 @@ import java.util.Objects; import java.util.Optional; -import org.mybatis.dynamic.sql.configuration.StatementConfiguration; import org.mybatis.dynamic.sql.insert.GeneralInsertModel; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.render.RenderingStrategy; @@ -32,7 +31,7 @@ public class GeneralInsertRenderer { private GeneralInsertRenderer(Builder builder) { model = Objects.requireNonNull(builder.model); RenderingContext renderingContext = RenderingContext.withRenderingStrategy(builder.renderingStrategy) - .withStatementConfiguration(builder.statementConfiguration) + .withStatementConfiguration(model.statementConfiguration()) .build(); visitor = new GeneralInsertValuePhraseVisitor(renderingContext); } @@ -59,7 +58,6 @@ public static Builder withInsertModel(GeneralInsertModel model) { public static class Builder { private GeneralInsertModel model; private RenderingStrategy renderingStrategy; - private StatementConfiguration statementConfiguration; public Builder withInsertModel(GeneralInsertModel model) { this.model = model; @@ -71,11 +69,6 @@ public Builder withRenderingStrategy(RenderingStrategy renderingStrategy) { return this; } - public Builder withStatementConfiguration(StatementConfiguration statementConfiguration) { - this.statementConfiguration = statementConfiguration; - return this; - } - public GeneralInsertRenderer build() { return new GeneralInsertRenderer(this); } 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 3825d4e3d..77adaa0df 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 @@ -22,7 +22,6 @@ import java.util.stream.Collectors; import org.mybatis.dynamic.sql.SqlColumn; -import org.mybatis.dynamic.sql.configuration.StatementConfiguration; import org.mybatis.dynamic.sql.insert.InsertColumnListModel; import org.mybatis.dynamic.sql.insert.InsertSelectModel; import org.mybatis.dynamic.sql.render.RenderingContext; @@ -38,7 +37,7 @@ public class InsertSelectRenderer { private InsertSelectRenderer(Builder builder) { model = Objects.requireNonNull(builder.model); renderingContext = RenderingContext.withRenderingStrategy(builder.renderingStrategy) - .withStatementConfiguration(builder.statementConfiguration) + .withStatementConfiguration(model.statementConfiguration()) .build(); } @@ -75,7 +74,6 @@ public static Builder withInsertSelectModel(InsertSelectModel model) { public static class Builder { private InsertSelectModel model; private RenderingStrategy renderingStrategy; - private StatementConfiguration statementConfiguration; public Builder withInsertSelectModel(InsertSelectModel model) { this.model = model; @@ -87,11 +85,6 @@ public Builder withRenderingStrategy(RenderingStrategy renderingStrategy) { return this; } - public Builder withStatementConfiguration(StatementConfiguration statementConfiguration) { - this.statementConfiguration = statementConfiguration; - return this; - } - public InsertSelectRenderer build() { return new InsertSelectRenderer(this); } diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java index 0ac97d702..edf6e71a2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java @@ -15,7 +15,6 @@ */ package org.mybatis.dynamic.sql.render; -import org.mybatis.dynamic.sql.configuration.StatementConfiguration; import org.mybatis.dynamic.sql.delete.DeleteModel; import org.mybatis.dynamic.sql.delete.render.DeleteRenderer; import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider; @@ -45,10 +44,8 @@ import org.mybatis.dynamic.sql.util.FragmentAndParameters; public interface RendererFactory { - static Renderer<RenderingStrategy, DeleteStatementProvider> createDeleteRenderer(DeleteModel deleteModel, - StatementConfiguration statementConfiguration) { + static Renderer<RenderingStrategy, DeleteStatementProvider> createDeleteRenderer(DeleteModel deleteModel) { return renderingStrategy -> DeleteRenderer.withDeleteModel(deleteModel) - .withStatementConfiguration(statementConfiguration) .withRenderingStrategy(renderingStrategy) .build() .render(); @@ -63,9 +60,8 @@ static <T> Renderer<RenderingStrategy, BatchInsert<T>> createBatchInsertRenderer } static Renderer<RenderingStrategy, GeneralInsertStatementProvider> createGeneralInsertRenderer( - GeneralInsertModel generalInsertModel, StatementConfiguration statementConfiguration) { + GeneralInsertModel generalInsertModel) { return renderingStrategy -> GeneralInsertRenderer.withInsertModel(generalInsertModel) - .withStatementConfiguration(statementConfiguration) .withRenderingStrategy(renderingStrategy) .build() .render(); @@ -80,9 +76,8 @@ static <T> Renderer<RenderingStrategy, InsertStatementProvider<T>> createInsertR } static Renderer<RenderingStrategy, InsertSelectStatementProvider> createInsertSelectRenderer( - InsertSelectModel insertSelectModel, StatementConfiguration statementConfiguration) { + InsertSelectModel insertSelectModel) { return renderingStrategy -> InsertSelectRenderer.withInsertSelectModel(insertSelectModel) - .withStatementConfiguration(statementConfiguration) .withRenderingStrategy(renderingStrategy) .build() .render(); @@ -97,27 +92,23 @@ static <T> Renderer<RenderingStrategy, MultiRowInsertStatementProvider<T>> creat } static Renderer<RenderingStrategy, SelectStatementProvider> createMultiSelectRenderer( - MultiSelectModel multiSelectModel, StatementConfiguration statementConfiguration) { + MultiSelectModel multiSelectModel) { return renderingStrategy -> new MultiSelectRenderer.Builder() .withMultiSelectModel(multiSelectModel) - .withStatementConfiguration(statementConfiguration) .withRenderingStrategy(renderingStrategy) .build() .render(); } - static Renderer<RenderingContext, FragmentAndParameters> createSelectRenderer( - SelectModel selectModel) { + static Renderer<RenderingContext, FragmentAndParameters> createSelectRenderer(SelectModel selectModel) { return renderingContext -> SelectRenderer.withSelectModel(selectModel) .withRenderingContext(renderingContext) .build() .render(); } - static Renderer<RenderingStrategy, UpdateStatementProvider> createUpdateRenderer( - UpdateModel updateModel, StatementConfiguration statementConfiguration) { + static Renderer<RenderingStrategy, UpdateStatementProvider> createUpdateRenderer(UpdateModel updateModel) { return renderingStrategy -> UpdateRenderer.withUpdateModel(updateModel) - .withStatementConfiguration(statementConfiguration) .withRenderingStrategy(renderingStrategy) .build() .render(); diff --git a/src/main/java/org/mybatis/dynamic/sql/select/AbstractSelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/AbstractSelectModel.java index 49c20789f..8fc3fb898 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/AbstractSelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/AbstractSelectModel.java @@ -40,6 +40,10 @@ public Optional<PagingModel> pagingModel() { return Optional.ofNullable(pagingModel); } + public StatementConfiguration statementConfiguration() { + return statementConfiguration; + } + public abstract static class AbstractBuilder<T extends AbstractBuilder<T>> { private OrderByModel orderByModel; private PagingModel pagingModel; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java index 607378c20..443a42c56 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java @@ -47,7 +47,7 @@ public Stream<UnionQuery> unionQueries() { @NotNull public SelectStatementProvider render(RenderingStrategy renderingStrategy) { - return RendererFactory.createMultiSelectRenderer(this, statementConfiguration) + return RendererFactory.createMultiSelectRenderer(this) .render(renderingStrategy); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java index 78d6ae8ff..9eb11e84a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java @@ -21,7 +21,6 @@ import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.common.OrderByRenderer; -import org.mybatis.dynamic.sql.configuration.StatementConfiguration; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.select.MultiSelectModel; @@ -36,11 +35,11 @@ public class MultiSelectRenderer { private final RenderingContext renderingContext; private MultiSelectRenderer(Builder builder) { + multiSelectModel = Objects.requireNonNull(builder.multiSelectModel); renderingContext = RenderingContext .withRenderingStrategy(builder.renderingStrategy) - .withStatementConfiguration(builder.statementConfiguration) + .withStatementConfiguration(multiSelectModel.statementConfiguration()) .build(); - multiSelectModel = Objects.requireNonNull(builder.multiSelectModel); } public SelectStatementProvider render() { @@ -97,7 +96,6 @@ private FragmentAndParameters renderPagingModel(PagingModel pagingModel) { public static class Builder { private RenderingStrategy renderingStrategy; private MultiSelectModel multiSelectModel; - private StatementConfiguration statementConfiguration; public Builder withRenderingStrategy(RenderingStrategy renderingStrategy) { this.renderingStrategy = renderingStrategy; @@ -109,11 +107,6 @@ public Builder withMultiSelectModel(MultiSelectModel multiSelectModel) { return this; } - public Builder withStatementConfiguration(StatementConfiguration statementConfiguration) { - this.statementConfiguration = statementConfiguration; - return this; - } - public MultiSelectRenderer build() { return new MultiSelectRenderer(this); } diff --git a/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java b/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java index 672b08c44..f4ad201e5 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java @@ -77,9 +77,13 @@ public Optional<OrderByModel> orderByModel() { return Optional.ofNullable(orderByModel); } + public StatementConfiguration statementConfiguration() { + return statementConfiguration; + } + @NotNull public UpdateStatementProvider render(RenderingStrategy renderingStrategy) { - return RendererFactory.createUpdateRenderer(this, statementConfiguration) + return RendererFactory.createUpdateRenderer(this) .render(renderingStrategy); } 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 352c1de7a..3af6aa6d2 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 @@ -22,7 +22,6 @@ import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.common.OrderByRenderer; -import org.mybatis.dynamic.sql.configuration.StatementConfiguration; import org.mybatis.dynamic.sql.render.ExplicitTableAliasCalculator; import org.mybatis.dynamic.sql.render.RenderedParameterInfo; import org.mybatis.dynamic.sql.render.RenderingContext; @@ -47,7 +46,7 @@ private UpdateRenderer(Builder builder) { renderingContext = RenderingContext .withRenderingStrategy(Objects.requireNonNull(builder.renderingStrategy)) .withTableAliasCalculator(tableAliasCalculator) - .withStatementConfiguration(builder.statementConfiguration) + .withStatementConfiguration(updateModel.statementConfiguration()) .build(); visitor = new SetPhraseVisitor(renderingContext); } @@ -131,7 +130,6 @@ public static Builder withUpdateModel(UpdateModel updateModel) { public static class Builder { private UpdateModel updateModel; private RenderingStrategy renderingStrategy; - private StatementConfiguration statementConfiguration; public Builder withUpdateModel(UpdateModel updateModel) { this.updateModel = updateModel; @@ -143,11 +141,6 @@ public Builder withRenderingStrategy(RenderingStrategy renderingStrategy) { return this; } - public Builder withStatementConfiguration(StatementConfiguration statementConfiguration) { - this.statementConfiguration = statementConfiguration; - return this; - } - public UpdateRenderer build() { return new UpdateRenderer(this); } From 1321973a0e3ce80bc689d251582786471bdcd8cf Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 22 Nov 2024 13:12:01 -0500 Subject: [PATCH 118/260] Make an explicit subquery renderer --- .../insert/render/InsertSelectRenderer.java | 2 +- .../dynamic/sql/render/RendererFactory.java | 12 ++- .../dynamic/sql/select/SelectModel.java | 13 +-- .../select/render/MultiSelectRenderer.java | 4 +- .../sql/select/render/SelectRenderer.java | 62 +++-------- .../sql/select/render/SubQueryRenderer.java | 101 ++++++++++++++++++ .../render/TableExpressionRenderer.java | 2 +- .../sql/update/render/SetPhraseVisitor.java | 2 +- .../sql/where/render/CriterionRenderer.java | 2 +- .../where/render/DefaultConditionVisitor.java | 2 +- 10 files changed, 135 insertions(+), 67 deletions(-) create mode 100644 src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java 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 77adaa0df..eb53e333b 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 @@ -42,7 +42,7 @@ private InsertSelectRenderer(Builder builder) { } public InsertSelectStatementProvider render() { - FragmentAndParameters selectStatement = model.selectModel().render(renderingContext); + FragmentAndParameters selectStatement = model.selectModel().renderSubQuery(renderingContext); String statementStart = InsertRenderingUtilities.calculateInsertStatementStart(model.table()); Optional<String> columnsPhrase = calculateColumnsPhrase(); diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java index edf6e71a2..380585358 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java @@ -38,6 +38,7 @@ import org.mybatis.dynamic.sql.select.render.MultiSelectRenderer; import org.mybatis.dynamic.sql.select.render.SelectRenderer; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; +import org.mybatis.dynamic.sql.select.render.SubQueryRenderer; import org.mybatis.dynamic.sql.update.UpdateModel; import org.mybatis.dynamic.sql.update.render.UpdateRenderer; import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider; @@ -100,8 +101,15 @@ static Renderer<RenderingStrategy, SelectStatementProvider> createMultiSelectRen .render(); } - static Renderer<RenderingContext, FragmentAndParameters> createSelectRenderer(SelectModel selectModel) { - return renderingContext -> SelectRenderer.withSelectModel(selectModel) + static Renderer<RenderingStrategy, SelectStatementProvider> createSelectRenderer(SelectModel selectModel) { + return renderingStrategy -> SelectRenderer.withSelectModel(selectModel) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); + } + + static Renderer<RenderingContext, FragmentAndParameters> createSubQueryRenderer(SelectModel selectModel) { + return renderingContext -> SubQueryRenderer.withSelectModel(selectModel) .withRenderingContext(renderingContext) .build() .render(); diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java index 3dff3162e..ae9e9027f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java @@ -24,7 +24,6 @@ import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.render.RenderingStrategy; -import org.mybatis.dynamic.sql.select.render.DefaultSelectStatementProvider; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.Validator; @@ -44,13 +43,7 @@ public Stream<QueryExpressionModel> queryExpressions() { @NotNull public SelectStatementProvider render(RenderingStrategy renderingStrategy) { - RenderingContext renderingContext = RenderingContext.withRenderingStrategy(renderingStrategy) - .withStatementConfiguration(statementConfiguration) - .build(); - FragmentAndParameters fragmentAndParameters = render(renderingContext); - return DefaultSelectStatementProvider.withSelectStatement(fragmentAndParameters.fragment()) - .withParameters(fragmentAndParameters.parameters()) - .build(); + return RendererFactory.createSelectRenderer(this).render(renderingStrategy); } /** @@ -60,8 +53,8 @@ public SelectStatementProvider render(RenderingStrategy renderingStrategy) { * @return a rendered select statement and parameters */ @NotNull - public FragmentAndParameters render(RenderingContext renderingContext) { - return RendererFactory.createSelectRenderer(this).render(renderingContext); + public FragmentAndParameters renderSubQuery(RenderingContext renderingContext) { + return RendererFactory.createSubQueryRenderer(this).render(renderingContext); } public static Builder withQueryExpressions(List<QueryExpressionModel> queryExpressions) { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java index 9eb11e84a..b90c8d6cb 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java @@ -64,12 +64,12 @@ private SelectStatementProvider toSelectStatementProvider(FragmentCollector frag } private FragmentAndParameters renderSelect(SelectModel selectModel) { - return selectModel.render(renderingContext) + return selectModel.renderSubQuery(renderingContext) .mapFragment(f -> "(" + f + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } private FragmentAndParameters renderSelect(UnionQuery unionQuery) { - return unionQuery.selectModel().render(renderingContext) + return unionQuery.selectModel().renderSubQuery(renderingContext) .mapFragment(f -> unionQuery.connector() + " (" + f + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java index 25e2e408b..76617f038 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java @@ -16,17 +16,12 @@ package org.mybatis.dynamic.sql.select.render; import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; -import org.mybatis.dynamic.sql.common.OrderByModel; -import org.mybatis.dynamic.sql.common.OrderByRenderer; +import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; -import org.mybatis.dynamic.sql.select.PagingModel; -import org.mybatis.dynamic.sql.select.QueryExpressionModel; +import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.select.SelectModel; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -import org.mybatis.dynamic.sql.util.FragmentCollector; public class SelectRenderer { private final SelectModel selectModel; @@ -34,46 +29,17 @@ public class SelectRenderer { private SelectRenderer(Builder builder) { selectModel = Objects.requireNonNull(builder.selectModel); - renderingContext = Objects.requireNonNull(builder.renderingContext); + renderingContext = RenderingContext.withRenderingStrategy(builder.renderingStrategy) + .withStatementConfiguration(selectModel.statementConfiguration()) + .build(); } - public FragmentAndParameters render() { - FragmentCollector fragmentCollector = selectModel - .queryExpressions() - .map(this::renderQueryExpression) - .collect(FragmentCollector.collect()); - - renderOrderBy().ifPresent(fragmentCollector::add); - renderPagingModel().ifPresent(fragmentCollector::add); - - return fragmentCollector.toFragmentAndParameters(Collectors.joining(" ")); //$NON-NLS-1$ - } - - private FragmentAndParameters renderQueryExpression(QueryExpressionModel queryExpressionModel) { - return QueryExpressionRenderer.withQueryExpression(queryExpressionModel) - .withRenderingContext(renderingContext) - .build() - .render(); - } - - private Optional<FragmentAndParameters> renderOrderBy() { - return selectModel.orderByModel().map(this::renderOrderBy); - } - - private FragmentAndParameters renderOrderBy(OrderByModel orderByModel) { - return new OrderByRenderer(renderingContext).render(orderByModel); - } - - private Optional<FragmentAndParameters> renderPagingModel() { - return selectModel.pagingModel().map(this::renderPagingModel); - } - - private FragmentAndParameters renderPagingModel(PagingModel pagingModel) { - return new PagingModelRenderer.Builder() - .withPagingModel(pagingModel) - .withRenderingContext(renderingContext) - .build() - .render(); + public SelectStatementProvider render() { + FragmentAndParameters fragmentAndParameters = RendererFactory.createSubQueryRenderer(selectModel) + .render(renderingContext); + return DefaultSelectStatementProvider.withSelectStatement(fragmentAndParameters.fragment()) + .withParameters(fragmentAndParameters.parameters()) + .build(); } public static Builder withSelectModel(SelectModel selectModel) { @@ -82,10 +48,10 @@ public static Builder withSelectModel(SelectModel selectModel) { public static class Builder { private SelectModel selectModel; - private RenderingContext renderingContext; + private RenderingStrategy renderingStrategy; - public Builder withRenderingContext(RenderingContext renderingContext) { - this.renderingContext = renderingContext; + public Builder withRenderingStrategy(RenderingStrategy renderingStrategy) { + this.renderingStrategy = renderingStrategy; return this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java new file mode 100644 index 000000000..013cae505 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java @@ -0,0 +1,101 @@ +/* + * Copyright 2016-2024 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 + * + * https://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.select.render; + +import org.mybatis.dynamic.sql.common.OrderByModel; +import org.mybatis.dynamic.sql.common.OrderByRenderer; +import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.select.PagingModel; +import org.mybatis.dynamic.sql.select.QueryExpressionModel; +import org.mybatis.dynamic.sql.select.SelectModel; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; +import org.mybatis.dynamic.sql.util.FragmentCollector; + +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +public class SubQueryRenderer { + private final SelectModel selectModel; + private final RenderingContext renderingContext; + + private SubQueryRenderer(Builder builder) { + selectModel = Objects.requireNonNull(builder.selectModel); + renderingContext = Objects.requireNonNull(builder.renderingContext); + } + + public FragmentAndParameters render() { + FragmentCollector fragmentCollector = selectModel + .queryExpressions() + .map(this::renderQueryExpression) + .collect(FragmentCollector.collect()); + + renderOrderBy().ifPresent(fragmentCollector::add); + renderPagingModel().ifPresent(fragmentCollector::add); + + return fragmentCollector.toFragmentAndParameters(Collectors.joining(" ")); //$NON-NLS-1$ + } + + private FragmentAndParameters renderQueryExpression(QueryExpressionModel queryExpressionModel) { + return QueryExpressionRenderer.withQueryExpression(queryExpressionModel) + .withRenderingContext(renderingContext) + .build() + .render(); + } + + private Optional<FragmentAndParameters> renderOrderBy() { + return selectModel.orderByModel().map(this::renderOrderBy); + } + + private FragmentAndParameters renderOrderBy(OrderByModel orderByModel) { + return new OrderByRenderer(renderingContext).render(orderByModel); + } + + private Optional<FragmentAndParameters> renderPagingModel() { + return selectModel.pagingModel().map(this::renderPagingModel); + } + + private FragmentAndParameters renderPagingModel(PagingModel pagingModel) { + return new PagingModelRenderer.Builder() + .withPagingModel(pagingModel) + .withRenderingContext(renderingContext) + .build() + .render(); + } + + public static Builder withSelectModel(SelectModel selectModel) { + return new Builder().withSelectModel(selectModel); + } + + public static class Builder { + private SelectModel selectModel; + private RenderingContext renderingContext; + + public Builder withRenderingContext(RenderingContext renderingContext) { + this.renderingContext = renderingContext; + return this; + } + + public Builder withSelectModel(SelectModel selectModel) { + this.selectModel = selectModel; + return this; + } + + public SubQueryRenderer build() { + return new SubQueryRenderer(this); + } + } +} diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java index 3ba013825..0448a2396 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java @@ -39,7 +39,7 @@ public FragmentAndParameters visit(SqlTable table) { @Override public FragmentAndParameters visit(SubQuery subQuery) { - return subQuery.selectModel().render(renderingContext) + return subQuery.selectModel().renderSubQuery(renderingContext) .mapFragment(f -> applyAlias("(" + f + ")", subQuery)); //$NON-NLS-1$ //$NON-NLS-2$ } diff --git a/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java b/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java index 77a898ea2..dd3d6ed78 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java @@ -83,7 +83,7 @@ public <T> Optional<FragmentAndParameters> visit(ValueWhenPresentMapping<T> mapp @Override public Optional<FragmentAndParameters> visit(SelectMapping mapping) { - return Optional.of(mapping.selectModel().render(renderingContext) + return Optional.of(mapping.selectModel().renderSubQuery(renderingContext) .mapFragment(f -> renderingContext.aliasedColumnName(mapping.column()) + " = (" + f + ")")); //$NON-NLS-1$ //$NON-NLS-2$ } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java index f56fc3e79..f19a6b340 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java @@ -119,7 +119,7 @@ private <T> Optional<FragmentAndParameters> renderColumnAndCondition(ColumnAndCo private FragmentAndParameters renderExists(ExistsCriterion criterion) { ExistsPredicate existsPredicate = criterion.existsPredicate(); - return existsPredicate.selectModelBuilder().build().render(renderingContext) + return existsPredicate.selectModelBuilder().build().renderSubQuery(renderingContext) .mapFragment(f -> existsPredicate.operator() + " (" + f + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java index 6bd518663..debb4d9c8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java @@ -94,7 +94,7 @@ public FragmentAndParameters visit(AbstractTwoValueCondition<T> condition) { @Override public FragmentAndParameters visit(AbstractSubselectCondition<T> condition) { - return condition.selectModel().render(renderingContext) + return condition.selectModel().renderSubQuery(renderingContext) .mapFragment(f -> condition.operator() + " (" + f + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } From de7d595b62e0a576043512013ff7e982092637ea Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 22 Nov 2024 14:17:40 -0500 Subject: [PATCH 119/260] Use the subquery renderer directly - less garbage --- .../insert/render/InsertSelectRenderer.java | 27 +++++++++---------- .../dynamic/sql/render/RendererFactory.java | 8 ++++++ .../dynamic/sql/select/SelectModel.java | 13 --------- .../select/render/MultiSelectRenderer.java | 13 ++++++--- .../sql/select/render/SubQueryRenderer.java | 13 ++++++++- .../render/TableExpressionRenderer.java | 14 ++++------ .../sql/update/render/SetPhraseVisitor.java | 10 ++++--- .../sql/where/render/CriterionRenderer.java | 8 +++--- .../where/render/DefaultConditionVisitor.java | 7 +++-- 9 files changed, 63 insertions(+), 50 deletions(-) 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 eb53e333b..fb3b37503 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 @@ -15,19 +15,18 @@ */ package org.mybatis.dynamic.sql.insert.render; -import static org.mybatis.dynamic.sql.util.StringUtilities.spaceBefore; +import static org.mybatis.dynamic.sql.util.StringUtilities.spaceAfter; import java.util.Objects; -import java.util.Optional; import java.util.stream.Collectors; import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.insert.InsertColumnListModel; import org.mybatis.dynamic.sql.insert.InsertSelectModel; +import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -import org.mybatis.dynamic.sql.util.StringUtilities; public class InsertSelectRenderer { @@ -42,29 +41,27 @@ private InsertSelectRenderer(Builder builder) { } public InsertSelectStatementProvider render() { - FragmentAndParameters selectStatement = model.selectModel().renderSubQuery(renderingContext); - String statementStart = InsertRenderingUtilities.calculateInsertStatementStart(model.table()); - Optional<String> columnsPhrase = calculateColumnsPhrase(); - String renderedSelectStatement = selectStatement.fragment(); + String columnsPhrase = calculateColumnsPhrase(); + String prefix = statementStart + spaceAfter(columnsPhrase); - String insertStatement = statementStart - + columnsPhrase.map(StringUtilities::spaceBefore).orElse("") //$NON-NLS-1$ - + spaceBefore(renderedSelectStatement); + FragmentAndParameters fragmentAndParameters = RendererFactory.createSubQueryRenderer(model.selectModel(), + prefix, "") //$NON-NLS-1$ + .render(renderingContext); - return DefaultGeneralInsertStatementProvider.withInsertStatement(insertStatement) - .withParameters(selectStatement.parameters()) + return DefaultGeneralInsertStatementProvider.withInsertStatement(fragmentAndParameters.fragment()) + .withParameters(fragmentAndParameters.parameters()) .build(); } - private Optional<String> calculateColumnsPhrase() { - return model.columnList().map(this::calculateColumnsPhrase); + private String calculateColumnsPhrase() { + return model.columnList().map(this::calculateColumnsPhrase).orElse(""); //$NON-NLS-1$ } private String calculateColumnsPhrase(InsertColumnListModel columnList) { return columnList.columns() .map(SqlColumn::name) - .collect(Collectors.joining(", ", "(", ")")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + .collect(Collectors.joining(", ", " (", ")")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } public static Builder withInsertSelectModel(InsertSelectModel model) { diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java index 380585358..2b7b2e945 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java @@ -115,6 +115,14 @@ static Renderer<RenderingContext, FragmentAndParameters> createSubQueryRenderer( .render(); } + static Renderer<RenderingContext, FragmentAndParameters> createSubQueryRenderer(SelectModel selectModel, + String prefix, String suffix) { + return renderingContext -> SubQueryRenderer.withSelectModel(selectModel) + .withRenderingContext(renderingContext) + .build() + .render(prefix, suffix); + } + static Renderer<RenderingStrategy, UpdateStatementProvider> createUpdateRenderer(UpdateModel updateModel) { return renderingStrategy -> UpdateRenderer.withUpdateModel(updateModel) .withRenderingStrategy(renderingStrategy) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java index ae9e9027f..14225147f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java @@ -22,10 +22,8 @@ import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.render.RendererFactory; -import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; -import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.Validator; public class SelectModel extends AbstractSelectModel { @@ -46,17 +44,6 @@ public SelectStatementProvider render(RenderingStrategy renderingStrategy) { return RendererFactory.createSelectRenderer(this).render(renderingStrategy); } - /** - * This version is for rendering sub-queries, union queries, etc. - * - * @param renderingContext the rendering context - * @return a rendered select statement and parameters - */ - @NotNull - public FragmentAndParameters renderSubQuery(RenderingContext renderingContext) { - return RendererFactory.createSubQueryRenderer(this).render(renderingContext); - } - public static Builder withQueryExpressions(List<QueryExpressionModel> queryExpressions) { return new Builder().withQueryExpressions(queryExpressions); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java index b90c8d6cb..4fe0b7e92 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java @@ -21,6 +21,7 @@ import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.common.OrderByRenderer; +import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.select.MultiSelectModel; @@ -64,13 +65,17 @@ private SelectStatementProvider toSelectStatementProvider(FragmentCollector frag } private FragmentAndParameters renderSelect(SelectModel selectModel) { - return selectModel.renderSubQuery(renderingContext) - .mapFragment(f -> "(" + f + ")"); //$NON-NLS-1$ //$NON-NLS-2$ + return RendererFactory.createSubQueryRenderer(selectModel, + "(", //$NON-NLS-1$ + ")") //$NON-NLS-1$ + .render(renderingContext); } private FragmentAndParameters renderSelect(UnionQuery unionQuery) { - return unionQuery.selectModel().renderSubQuery(renderingContext) - .mapFragment(f -> unionQuery.connector() + " (" + f + ")"); //$NON-NLS-1$ //$NON-NLS-2$ + return RendererFactory.createSubQueryRenderer(unionQuery.selectModel(), + unionQuery.connector() + " (", //$NON-NLS-1$ + ")") //$NON-NLS-1$ + .render(renderingContext); } private Optional<FragmentAndParameters> renderOrderBy() { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java index 013cae505..5e95886c5 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java @@ -26,6 +26,7 @@ import java.util.Objects; import java.util.Optional; +import java.util.stream.Collector; import java.util.stream.Collectors; public class SubQueryRenderer { @@ -38,6 +39,16 @@ private SubQueryRenderer(Builder builder) { } public FragmentAndParameters render() { + var collector = Collectors.joining(" "); //$NON-NLS-1$ + return render(collector); + } + + public FragmentAndParameters render(String prefix, String suffix) { + var collector = Collectors.joining(" ", prefix, suffix); //$NON-NLS-1$ + return render(collector); + } + + private FragmentAndParameters render(Collector<CharSequence, ?, String> collector) { FragmentCollector fragmentCollector = selectModel .queryExpressions() .map(this::renderQueryExpression) @@ -46,7 +57,7 @@ public FragmentAndParameters render() { renderOrderBy().ifPresent(fragmentCollector::add); renderPagingModel().ifPresent(fragmentCollector::add); - return fragmentCollector.toFragmentAndParameters(Collectors.joining(" ")); //$NON-NLS-1$ + return fragmentCollector.toFragmentAndParameters(collector); } private FragmentAndParameters renderQueryExpression(QueryExpressionModel queryExpressionModel) { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java index 0448a2396..ede734ece 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java @@ -15,12 +15,11 @@ */ package org.mybatis.dynamic.sql.select.render; -import static org.mybatis.dynamic.sql.util.StringUtilities.spaceBefore; - import java.util.Objects; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.TableExpressionVisitor; +import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.SubQuery; import org.mybatis.dynamic.sql.util.FragmentAndParameters; @@ -39,14 +38,11 @@ public FragmentAndParameters visit(SqlTable table) { @Override public FragmentAndParameters visit(SubQuery subQuery) { - return subQuery.selectModel().renderSubQuery(renderingContext) - .mapFragment(f -> applyAlias("(" + f + ")", subQuery)); //$NON-NLS-1$ //$NON-NLS-2$ - } + String suffix = subQuery.alias().map(a -> ") " + a) //$NON-NLS-1$ + .orElse(")"); //$NON-NLS-1$ - private String applyAlias(String fragment, SubQuery subQuery) { - return subQuery.alias() - .map(a -> fragment + spaceBefore(a)) - .orElse(fragment); + return RendererFactory.createSubQueryRenderer(subQuery.selectModel(), "(", suffix) //$NON-NLS-1$ + .render(renderingContext); } public static class Builder { diff --git a/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java b/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java index dd3d6ed78..f44c036dc 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java @@ -19,6 +19,7 @@ import java.util.Optional; import org.mybatis.dynamic.sql.render.RenderedParameterInfo; +import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.AbstractColumnMapping; import org.mybatis.dynamic.sql.util.ColumnToColumnMapping; @@ -83,9 +84,12 @@ public <T> Optional<FragmentAndParameters> visit(ValueWhenPresentMapping<T> mapp @Override public Optional<FragmentAndParameters> visit(SelectMapping mapping) { - return Optional.of(mapping.selectModel().renderSubQuery(renderingContext) - .mapFragment(f -> renderingContext.aliasedColumnName(mapping.column()) - + " = (" + f + ")")); //$NON-NLS-1$ //$NON-NLS-2$ + FragmentAndParameters fragmentAndParameters = RendererFactory.createSubQueryRenderer(mapping.selectModel(), + renderingContext.aliasedColumnName(mapping.column()) + " = (", //$NON-NLS-1$ + ")") //$NON-NLS-1$ + .render(renderingContext); + + return Optional.of(fragmentAndParameters); } @Override diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java index f19a6b340..6935b8b54 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java @@ -29,6 +29,7 @@ import org.mybatis.dynamic.sql.NotCriterion; import org.mybatis.dynamic.sql.SqlCriterion; import org.mybatis.dynamic.sql.SqlCriterionVisitor; +import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.FragmentCollector; @@ -118,9 +119,10 @@ private <T> Optional<FragmentAndParameters> renderColumnAndCondition(ColumnAndCo private FragmentAndParameters renderExists(ExistsCriterion criterion) { ExistsPredicate existsPredicate = criterion.existsPredicate(); - - return existsPredicate.selectModelBuilder().build().renderSubQuery(renderingContext) - .mapFragment(f -> existsPredicate.operator() + " (" + f + ")"); //$NON-NLS-1$ //$NON-NLS-2$ + return RendererFactory.createSubQueryRenderer(existsPredicate.selectModelBuilder().build(), + existsPredicate.operator() + " (", //$NON-NLS-1$ + ")") //$NON-NLS-1$ + .render(renderingContext); } private List<RenderedCriterion> renderSubCriteria(List<AndOrCriteriaGroup> subCriteria) { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java index debb4d9c8..c13633b1d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java @@ -29,6 +29,7 @@ import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.ConditionVisitor; import org.mybatis.dynamic.sql.render.RenderedParameterInfo; +import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.FragmentCollector; @@ -94,8 +95,10 @@ public FragmentAndParameters visit(AbstractTwoValueCondition<T> condition) { @Override public FragmentAndParameters visit(AbstractSubselectCondition<T> condition) { - return condition.selectModel().renderSubQuery(renderingContext) - .mapFragment(f -> condition.operator() + " (" + f + ")"); //$NON-NLS-1$ //$NON-NLS-2$ + return RendererFactory.createSubQueryRenderer(condition.selectModel(), + condition.operator() + " (", //$NON-NLS-1$ + ")") //$NON-NLS-1$ + .render(renderingContext); } @Override From 7dd88a3c3930691f91f621dffc161f2ed4b7ca11 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 22 Nov 2024 14:41:46 -0500 Subject: [PATCH 120/260] Make the SelectRenderer work for sub-queries --- .../dynamic/sql/render/RendererFactory.java | 26 ++-- .../sql/select/render/SelectRenderer.java | 66 ++++++++--- .../sql/select/render/SubQueryRenderer.java | 112 ------------------ 3 files changed, 64 insertions(+), 140 deletions(-) delete mode 100644 src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java index 2b7b2e945..d43ddd6f8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java @@ -35,10 +35,10 @@ import org.mybatis.dynamic.sql.insert.render.MultiRowInsertStatementProvider; import org.mybatis.dynamic.sql.select.MultiSelectModel; import org.mybatis.dynamic.sql.select.SelectModel; +import org.mybatis.dynamic.sql.select.render.DefaultSelectStatementProvider; import org.mybatis.dynamic.sql.select.render.MultiSelectRenderer; import org.mybatis.dynamic.sql.select.render.SelectRenderer; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; -import org.mybatis.dynamic.sql.select.render.SubQueryRenderer; import org.mybatis.dynamic.sql.update.UpdateModel; import org.mybatis.dynamic.sql.update.render.UpdateRenderer; import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider; @@ -102,22 +102,24 @@ static Renderer<RenderingStrategy, SelectStatementProvider> createMultiSelectRen } static Renderer<RenderingStrategy, SelectStatementProvider> createSelectRenderer(SelectModel selectModel) { - return renderingStrategy -> SelectRenderer.withSelectModel(selectModel) - .withRenderingStrategy(renderingStrategy) - .build() - .render(); - } + return renderingStrategy -> { + RenderingContext renderingContext = RenderingContext.withRenderingStrategy(renderingStrategy) + .withStatementConfiguration(selectModel.statementConfiguration()) + .build(); - static Renderer<RenderingContext, FragmentAndParameters> createSubQueryRenderer(SelectModel selectModel) { - return renderingContext -> SubQueryRenderer.withSelectModel(selectModel) - .withRenderingContext(renderingContext) - .build() - .render(); + FragmentAndParameters fragmentAndParameters = createSubQueryRenderer(selectModel, + "", "") //$NON-NLS-1$ //$NON-NLS-2$ + .render(renderingContext); + + return DefaultSelectStatementProvider.withSelectStatement(fragmentAndParameters.fragment()) + .withParameters(fragmentAndParameters.parameters()) + .build(); + }; } static Renderer<RenderingContext, FragmentAndParameters> createSubQueryRenderer(SelectModel selectModel, String prefix, String suffix) { - return renderingContext -> SubQueryRenderer.withSelectModel(selectModel) + return renderingContext -> SelectRenderer.withSelectModel(selectModel) .withRenderingContext(renderingContext) .build() .render(prefix, suffix); diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java index 76617f038..64725710b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java @@ -15,13 +15,18 @@ */ package org.mybatis.dynamic.sql.select.render; -import java.util.Objects; - -import org.mybatis.dynamic.sql.render.RendererFactory; +import org.mybatis.dynamic.sql.common.OrderByModel; +import org.mybatis.dynamic.sql.common.OrderByRenderer; import org.mybatis.dynamic.sql.render.RenderingContext; -import org.mybatis.dynamic.sql.render.RenderingStrategy; +import org.mybatis.dynamic.sql.select.PagingModel; +import org.mybatis.dynamic.sql.select.QueryExpressionModel; import org.mybatis.dynamic.sql.select.SelectModel; import org.mybatis.dynamic.sql.util.FragmentAndParameters; +import org.mybatis.dynamic.sql.util.FragmentCollector; + +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; public class SelectRenderer { private final SelectModel selectModel; @@ -29,17 +34,46 @@ public class SelectRenderer { private SelectRenderer(Builder builder) { selectModel = Objects.requireNonNull(builder.selectModel); - renderingContext = RenderingContext.withRenderingStrategy(builder.renderingStrategy) - .withStatementConfiguration(selectModel.statementConfiguration()) - .build(); + renderingContext = Objects.requireNonNull(builder.renderingContext); + } + + public FragmentAndParameters render(String prefix, String suffix) { + FragmentCollector fragmentCollector = selectModel + .queryExpressions() + .map(this::renderQueryExpression) + .collect(FragmentCollector.collect()); + + renderOrderBy().ifPresent(fragmentCollector::add); + renderPagingModel().ifPresent(fragmentCollector::add); + + return fragmentCollector.toFragmentAndParameters(Collectors.joining(" ", prefix, suffix)); //$NON-NLS-1$ + } + + private FragmentAndParameters renderQueryExpression(QueryExpressionModel queryExpressionModel) { + return QueryExpressionRenderer.withQueryExpression(queryExpressionModel) + .withRenderingContext(renderingContext) + .build() + .render(); + } + + private Optional<FragmentAndParameters> renderOrderBy() { + return selectModel.orderByModel().map(this::renderOrderBy); + } + + private FragmentAndParameters renderOrderBy(OrderByModel orderByModel) { + return new OrderByRenderer(renderingContext).render(orderByModel); + } + + private Optional<FragmentAndParameters> renderPagingModel() { + return selectModel.pagingModel().map(this::renderPagingModel); } - public SelectStatementProvider render() { - FragmentAndParameters fragmentAndParameters = RendererFactory.createSubQueryRenderer(selectModel) - .render(renderingContext); - return DefaultSelectStatementProvider.withSelectStatement(fragmentAndParameters.fragment()) - .withParameters(fragmentAndParameters.parameters()) - .build(); + private FragmentAndParameters renderPagingModel(PagingModel pagingModel) { + return new PagingModelRenderer.Builder() + .withPagingModel(pagingModel) + .withRenderingContext(renderingContext) + .build() + .render(); } public static Builder withSelectModel(SelectModel selectModel) { @@ -48,10 +82,10 @@ public static Builder withSelectModel(SelectModel selectModel) { public static class Builder { private SelectModel selectModel; - private RenderingStrategy renderingStrategy; + private RenderingContext renderingContext; - public Builder withRenderingStrategy(RenderingStrategy renderingStrategy) { - this.renderingStrategy = renderingStrategy; + public Builder withRenderingContext(RenderingContext renderingContext) { + this.renderingContext = renderingContext; return this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java deleted file mode 100644 index 5e95886c5..000000000 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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.select.render; - -import org.mybatis.dynamic.sql.common.OrderByModel; -import org.mybatis.dynamic.sql.common.OrderByRenderer; -import org.mybatis.dynamic.sql.render.RenderingContext; -import org.mybatis.dynamic.sql.select.PagingModel; -import org.mybatis.dynamic.sql.select.QueryExpressionModel; -import org.mybatis.dynamic.sql.select.SelectModel; -import org.mybatis.dynamic.sql.util.FragmentAndParameters; -import org.mybatis.dynamic.sql.util.FragmentCollector; - -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collector; -import java.util.stream.Collectors; - -public class SubQueryRenderer { - private final SelectModel selectModel; - private final RenderingContext renderingContext; - - private SubQueryRenderer(Builder builder) { - selectModel = Objects.requireNonNull(builder.selectModel); - renderingContext = Objects.requireNonNull(builder.renderingContext); - } - - public FragmentAndParameters render() { - var collector = Collectors.joining(" "); //$NON-NLS-1$ - return render(collector); - } - - public FragmentAndParameters render(String prefix, String suffix) { - var collector = Collectors.joining(" ", prefix, suffix); //$NON-NLS-1$ - return render(collector); - } - - private FragmentAndParameters render(Collector<CharSequence, ?, String> collector) { - FragmentCollector fragmentCollector = selectModel - .queryExpressions() - .map(this::renderQueryExpression) - .collect(FragmentCollector.collect()); - - renderOrderBy().ifPresent(fragmentCollector::add); - renderPagingModel().ifPresent(fragmentCollector::add); - - return fragmentCollector.toFragmentAndParameters(collector); - } - - private FragmentAndParameters renderQueryExpression(QueryExpressionModel queryExpressionModel) { - return QueryExpressionRenderer.withQueryExpression(queryExpressionModel) - .withRenderingContext(renderingContext) - .build() - .render(); - } - - private Optional<FragmentAndParameters> renderOrderBy() { - return selectModel.orderByModel().map(this::renderOrderBy); - } - - private FragmentAndParameters renderOrderBy(OrderByModel orderByModel) { - return new OrderByRenderer(renderingContext).render(orderByModel); - } - - private Optional<FragmentAndParameters> renderPagingModel() { - return selectModel.pagingModel().map(this::renderPagingModel); - } - - private FragmentAndParameters renderPagingModel(PagingModel pagingModel) { - return new PagingModelRenderer.Builder() - .withPagingModel(pagingModel) - .withRenderingContext(renderingContext) - .build() - .render(); - } - - public static Builder withSelectModel(SelectModel selectModel) { - return new Builder().withSelectModel(selectModel); - } - - public static class Builder { - private SelectModel selectModel; - private RenderingContext renderingContext; - - public Builder withRenderingContext(RenderingContext renderingContext) { - this.renderingContext = renderingContext; - return this; - } - - public Builder withSelectModel(SelectModel selectModel) { - this.selectModel = selectModel; - return this; - } - - public SubQueryRenderer build() { - return new SubQueryRenderer(this); - } - } -} From 4da1e6dbcce1320121b2a532389c765f5fee40f5 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 22 Nov 2024 14:42:52 -0500 Subject: [PATCH 121/260] Checkstyle --- .../mybatis/dynamic/sql/select/render/SelectRenderer.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java index 64725710b..cd390d088 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java @@ -15,6 +15,10 @@ */ package org.mybatis.dynamic.sql.select.render; +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.common.OrderByRenderer; import org.mybatis.dynamic.sql.render.RenderingContext; @@ -24,10 +28,6 @@ import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.FragmentCollector; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; - public class SelectRenderer { private final SelectModel selectModel; private final RenderingContext renderingContext; From 63223f35772f6ba8727f7102e46757c5a457b13c Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 22 Nov 2024 14:49:45 -0500 Subject: [PATCH 122/260] Checkstyle --- .../mybatis/dynamic/sql/update/render/SetPhraseVisitor.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java b/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java index f44c036dc..5464a253f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java @@ -88,14 +88,14 @@ public Optional<FragmentAndParameters> visit(SelectMapping mapping) { renderingContext.aliasedColumnName(mapping.column()) + " = (", //$NON-NLS-1$ ")") //$NON-NLS-1$ .render(renderingContext); - return Optional.of(fragmentAndParameters); } @Override public Optional<FragmentAndParameters> visit(ColumnToColumnMapping mapping) { - return Optional.of(mapping.rightColumn().render(renderingContext) - .mapFragment(f -> renderingContext.aliasedColumnName(mapping.column()) + " = " + f)); //$NON-NLS-1$ + FragmentAndParameters fragmentAndParameters = mapping.rightColumn().render(renderingContext) + .mapFragment(f -> renderingContext.aliasedColumnName(mapping.column()) + " = " + f); //$NON-NLS-1$ + return Optional.of(fragmentAndParameters); } private <T> Optional<FragmentAndParameters> buildValueFragment(AbstractColumnMapping mapping, T value) { From 99669aba99d734c4d368e9709f9a55811a7e113c Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 22 Nov 2024 15:02:06 -0500 Subject: [PATCH 123/260] Back to explicit subquery renderer --- .../dynamic/sql/render/RendererFactory.java | 21 ++-- .../sql/select/render/SelectRenderer.java | 62 +++-------- .../sql/select/render/SubQueryRenderer.java | 101 ++++++++++++++++++ 3 files changed, 122 insertions(+), 62 deletions(-) create mode 100644 src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java index d43ddd6f8..48d495bd3 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java @@ -35,10 +35,10 @@ import org.mybatis.dynamic.sql.insert.render.MultiRowInsertStatementProvider; import org.mybatis.dynamic.sql.select.MultiSelectModel; import org.mybatis.dynamic.sql.select.SelectModel; -import org.mybatis.dynamic.sql.select.render.DefaultSelectStatementProvider; import org.mybatis.dynamic.sql.select.render.MultiSelectRenderer; import org.mybatis.dynamic.sql.select.render.SelectRenderer; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; +import org.mybatis.dynamic.sql.select.render.SubQueryRenderer; import org.mybatis.dynamic.sql.update.UpdateModel; import org.mybatis.dynamic.sql.update.render.UpdateRenderer; import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider; @@ -102,24 +102,15 @@ static Renderer<RenderingStrategy, SelectStatementProvider> createMultiSelectRen } static Renderer<RenderingStrategy, SelectStatementProvider> createSelectRenderer(SelectModel selectModel) { - return renderingStrategy -> { - RenderingContext renderingContext = RenderingContext.withRenderingStrategy(renderingStrategy) - .withStatementConfiguration(selectModel.statementConfiguration()) - .build(); - - FragmentAndParameters fragmentAndParameters = createSubQueryRenderer(selectModel, - "", "") //$NON-NLS-1$ //$NON-NLS-2$ - .render(renderingContext); - - return DefaultSelectStatementProvider.withSelectStatement(fragmentAndParameters.fragment()) - .withParameters(fragmentAndParameters.parameters()) - .build(); - }; + return renderingStrategy -> SelectRenderer.withSelectModel(selectModel) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); } static Renderer<RenderingContext, FragmentAndParameters> createSubQueryRenderer(SelectModel selectModel, String prefix, String suffix) { - return renderingContext -> SelectRenderer.withSelectModel(selectModel) + return renderingContext -> SubQueryRenderer.withSelectModel(selectModel) .withRenderingContext(renderingContext) .build() .render(prefix, suffix); diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java index cd390d088..5789b0298 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java @@ -16,17 +16,12 @@ package org.mybatis.dynamic.sql.select.render; import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; -import org.mybatis.dynamic.sql.common.OrderByModel; -import org.mybatis.dynamic.sql.common.OrderByRenderer; +import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; -import org.mybatis.dynamic.sql.select.PagingModel; -import org.mybatis.dynamic.sql.select.QueryExpressionModel; +import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.select.SelectModel; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -import org.mybatis.dynamic.sql.util.FragmentCollector; public class SelectRenderer { private final SelectModel selectModel; @@ -34,46 +29,19 @@ public class SelectRenderer { private SelectRenderer(Builder builder) { selectModel = Objects.requireNonNull(builder.selectModel); - renderingContext = Objects.requireNonNull(builder.renderingContext); + renderingContext = RenderingContext.withRenderingStrategy(builder.renderingStrategy) + .withStatementConfiguration(selectModel.statementConfiguration()) + .build(); } - public FragmentAndParameters render(String prefix, String suffix) { - FragmentCollector fragmentCollector = selectModel - .queryExpressions() - .map(this::renderQueryExpression) - .collect(FragmentCollector.collect()); + public SelectStatementProvider render() { + FragmentAndParameters fragmentAndParameters = RendererFactory.createSubQueryRenderer(selectModel, + "", "") //$NON-NLS-1$ //$NON-NLS-2$ + .render(renderingContext); - renderOrderBy().ifPresent(fragmentCollector::add); - renderPagingModel().ifPresent(fragmentCollector::add); - - return fragmentCollector.toFragmentAndParameters(Collectors.joining(" ", prefix, suffix)); //$NON-NLS-1$ - } - - private FragmentAndParameters renderQueryExpression(QueryExpressionModel queryExpressionModel) { - return QueryExpressionRenderer.withQueryExpression(queryExpressionModel) - .withRenderingContext(renderingContext) - .build() - .render(); - } - - private Optional<FragmentAndParameters> renderOrderBy() { - return selectModel.orderByModel().map(this::renderOrderBy); - } - - private FragmentAndParameters renderOrderBy(OrderByModel orderByModel) { - return new OrderByRenderer(renderingContext).render(orderByModel); - } - - private Optional<FragmentAndParameters> renderPagingModel() { - return selectModel.pagingModel().map(this::renderPagingModel); - } - - private FragmentAndParameters renderPagingModel(PagingModel pagingModel) { - return new PagingModelRenderer.Builder() - .withPagingModel(pagingModel) - .withRenderingContext(renderingContext) - .build() - .render(); + return DefaultSelectStatementProvider.withSelectStatement(fragmentAndParameters.fragment()) + .withParameters(fragmentAndParameters.parameters()) + .build(); } public static Builder withSelectModel(SelectModel selectModel) { @@ -82,10 +50,10 @@ public static Builder withSelectModel(SelectModel selectModel) { public static class Builder { private SelectModel selectModel; - private RenderingContext renderingContext; + private RenderingStrategy renderingStrategy; - public Builder withRenderingContext(RenderingContext renderingContext) { - this.renderingContext = renderingContext; + public Builder withRenderingStrategy(RenderingStrategy renderingStrategy) { + this.renderingStrategy = renderingStrategy; return this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java new file mode 100644 index 000000000..1f97f5e7d --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java @@ -0,0 +1,101 @@ +/* + * Copyright 2016-2024 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 + * + * https://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.select.render; + +import java.util.Objects; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.mybatis.dynamic.sql.common.OrderByModel; +import org.mybatis.dynamic.sql.common.OrderByRenderer; +import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.select.PagingModel; +import org.mybatis.dynamic.sql.select.QueryExpressionModel; +import org.mybatis.dynamic.sql.select.SelectModel; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; +import org.mybatis.dynamic.sql.util.FragmentCollector; + +public class SubQueryRenderer { + private final SelectModel selectModel; + private final RenderingContext renderingContext; + + private SubQueryRenderer(Builder builder) { + selectModel = Objects.requireNonNull(builder.selectModel); + renderingContext = Objects.requireNonNull(builder.renderingContext); + } + + public FragmentAndParameters render(String prefix, String suffix) { + FragmentCollector fragmentCollector = selectModel + .queryExpressions() + .map(this::renderQueryExpression) + .collect(FragmentCollector.collect()); + + renderOrderBy().ifPresent(fragmentCollector::add); + renderPagingModel().ifPresent(fragmentCollector::add); + + return fragmentCollector.toFragmentAndParameters(Collectors.joining(" ", prefix, suffix)); //$NON-NLS-1$ + } + + private FragmentAndParameters renderQueryExpression(QueryExpressionModel queryExpressionModel) { + return QueryExpressionRenderer.withQueryExpression(queryExpressionModel) + .withRenderingContext(renderingContext) + .build() + .render(); + } + + private Optional<FragmentAndParameters> renderOrderBy() { + return selectModel.orderByModel().map(this::renderOrderBy); + } + + private FragmentAndParameters renderOrderBy(OrderByModel orderByModel) { + return new OrderByRenderer(renderingContext).render(orderByModel); + } + + private Optional<FragmentAndParameters> renderPagingModel() { + return selectModel.pagingModel().map(this::renderPagingModel); + } + + private FragmentAndParameters renderPagingModel(PagingModel pagingModel) { + return new PagingModelRenderer.Builder() + .withPagingModel(pagingModel) + .withRenderingContext(renderingContext) + .build() + .render(); + } + + public static Builder withSelectModel(SelectModel selectModel) { + return new Builder().withSelectModel(selectModel); + } + + public static class Builder { + private SelectModel selectModel; + private RenderingContext renderingContext; + + public Builder withRenderingContext(RenderingContext renderingContext) { + this.renderingContext = renderingContext; + return this; + } + + public Builder withSelectModel(SelectModel selectModel) { + this.selectModel = selectModel; + return this; + } + + public SubQueryRenderer build() { + return new SubQueryRenderer(this); + } + } +} From 8db58a8f861200b0fec01e1b50cb2dd1b35cc761 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Sat, 23 Nov 2024 15:32:23 -0500 Subject: [PATCH 124/260] Remove renderer factory It didn't reduce the Sonar cycles, and added unnecessary complexity --- .../dynamic/sql/delete/DeleteModel.java | 8 +- .../dynamic/sql/insert/BatchInsertModel.java | 8 +- .../sql/insert/GeneralInsertModel.java | 8 +- .../dynamic/sql/insert/InsertModel.java | 8 +- .../dynamic/sql/insert/InsertSelectModel.java | 8 +- .../sql/insert/MultiRowInsertModel.java | 8 +- .../insert/render/InsertSelectRenderer.java | 10 +- .../mybatis/dynamic/sql/render/Renderer.java | 21 --- .../dynamic/sql/render/RendererFactory.java | 125 ------------------ .../dynamic/sql/select/MultiSelectModel.java | 8 +- .../dynamic/sql/select/SelectModel.java | 7 +- .../select/render/MultiSelectRenderer.java | 25 ++-- .../sql/select/render/SelectRenderer.java | 18 +-- .../sql/select/render/SubQueryRenderer.java | 18 ++- .../render/TableExpressionRenderer.java | 9 +- .../dynamic/sql/update/UpdateModel.java | 8 +- .../sql/update/render/SetPhraseVisitor.java | 15 ++- .../sql/where/render/CriterionRenderer.java | 12 +- .../where/render/DefaultConditionVisitor.java | 12 +- 19 files changed, 124 insertions(+), 212 deletions(-) delete mode 100644 src/main/java/org/mybatis/dynamic/sql/render/Renderer.java delete mode 100644 src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java diff --git a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java index 581d2250a..4519b1002 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java @@ -23,8 +23,8 @@ import org.mybatis.dynamic.sql.common.CommonBuilder; import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; +import org.mybatis.dynamic.sql.delete.render.DeleteRenderer; import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider; -import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.where.EmbeddedWhereModel; @@ -71,8 +71,10 @@ public StatementConfiguration statementConfiguration() { @NotNull public DeleteStatementProvider render(RenderingStrategy renderingStrategy) { - return RendererFactory.createDeleteRenderer(this) - .render(renderingStrategy); + return DeleteRenderer.withDeleteModel(this) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); } public static Builder withTable(SqlTable table) { diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java index 5e48e9035..b591753a2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java @@ -19,7 +19,7 @@ import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.insert.render.BatchInsert; -import org.mybatis.dynamic.sql.render.RendererFactory; +import org.mybatis.dynamic.sql.insert.render.BatchInsertRenderer; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.util.Validator; @@ -33,8 +33,10 @@ private BatchInsertModel(Builder<T> builder) { @NotNull public BatchInsert<T> render(RenderingStrategy renderingStrategy) { - return RendererFactory.createBatchInsertRenderer(this) - .render(renderingStrategy); + return BatchInsertRenderer.withBatchInsertModel(this) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); } public static <T> Builder<T> withRecords(Collection<T> records) { diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java index 955d5fe7c..1fe845090 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java @@ -23,8 +23,8 @@ import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; +import org.mybatis.dynamic.sql.insert.render.GeneralInsertRenderer; import org.mybatis.dynamic.sql.insert.render.GeneralInsertStatementProvider; -import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.util.AbstractColumnMapping; import org.mybatis.dynamic.sql.util.Validator; @@ -56,8 +56,10 @@ public StatementConfiguration statementConfiguration() { @NotNull public GeneralInsertStatementProvider render(RenderingStrategy renderingStrategy) { - return RendererFactory.createGeneralInsertRenderer(this) - .render(renderingStrategy); + return GeneralInsertRenderer.withInsertModel(this) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); } public static class Builder { diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/InsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/InsertModel.java index 07fac79ed..7f740051e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/InsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/InsertModel.java @@ -22,8 +22,8 @@ import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.SqlTable; +import org.mybatis.dynamic.sql.insert.render.InsertRenderer; import org.mybatis.dynamic.sql.insert.render.InsertStatementProvider; -import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.util.AbstractColumnMapping; import org.mybatis.dynamic.sql.util.Validator; @@ -54,8 +54,10 @@ public SqlTable table() { @NotNull public InsertStatementProvider<T> render(RenderingStrategy renderingStrategy) { - return RendererFactory.createInsertRenderer(this) - .render(renderingStrategy); + return InsertRenderer.withInsertModel(this) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); } public static <T> Builder<T> withRow(T row) { diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java index 37df5e10e..3d9580942 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java @@ -21,8 +21,8 @@ import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; +import org.mybatis.dynamic.sql.insert.render.InsertSelectRenderer; import org.mybatis.dynamic.sql.insert.render.InsertSelectStatementProvider; -import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.select.SelectModel; @@ -57,8 +57,10 @@ public StatementConfiguration statementConfiguration() { @NotNull public InsertSelectStatementProvider render(RenderingStrategy renderingStrategy) { - return RendererFactory.createInsertSelectRenderer(this) - .render(renderingStrategy); + return InsertSelectRenderer.withInsertSelectModel(this) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); } public static Builder withTable(SqlTable table) { diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertModel.java index d5d7f478d..406c02b7a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertModel.java @@ -18,8 +18,8 @@ import java.util.Collection; import org.jetbrains.annotations.NotNull; +import org.mybatis.dynamic.sql.insert.render.MultiRowInsertRenderer; import org.mybatis.dynamic.sql.insert.render.MultiRowInsertStatementProvider; -import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.util.Validator; @@ -33,8 +33,10 @@ private MultiRowInsertModel(Builder<T> builder) { @NotNull public MultiRowInsertStatementProvider<T> render(RenderingStrategy renderingStrategy) { - return RendererFactory.createMultiRowInsertRenderer(this) - .render(renderingStrategy); + return MultiRowInsertRenderer.withMultiRowInsertModel(this) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); } public static <T> Builder<T> withRecords(Collection<T> records) { 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 fb3b37503..cd052f45d 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 @@ -23,9 +23,9 @@ import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.insert.InsertColumnListModel; import org.mybatis.dynamic.sql.insert.InsertSelectModel; -import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.render.RenderingStrategy; +import org.mybatis.dynamic.sql.select.render.SubQueryRenderer; import org.mybatis.dynamic.sql.util.FragmentAndParameters; public class InsertSelectRenderer { @@ -45,9 +45,11 @@ public InsertSelectStatementProvider render() { String columnsPhrase = calculateColumnsPhrase(); String prefix = statementStart + spaceAfter(columnsPhrase); - FragmentAndParameters fragmentAndParameters = RendererFactory.createSubQueryRenderer(model.selectModel(), - prefix, "") //$NON-NLS-1$ - .render(renderingContext); + FragmentAndParameters fragmentAndParameters = SubQueryRenderer.withSelectModel(model.selectModel()) + .withRenderingContext(renderingContext) + .withPrefix(prefix) + .build() + .render(); return DefaultGeneralInsertStatementProvider.withInsertStatement(fragmentAndParameters.fragment()) .withParameters(fragmentAndParameters.parameters()) diff --git a/src/main/java/org/mybatis/dynamic/sql/render/Renderer.java b/src/main/java/org/mybatis/dynamic/sql/render/Renderer.java deleted file mode 100644 index acb84a98f..000000000 --- a/src/main/java/org/mybatis/dynamic/sql/render/Renderer.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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.render; - -@FunctionalInterface -public interface Renderer<T, R> { - R render(T t); -} diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java b/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java deleted file mode 100644 index 48d495bd3..000000000 --- a/src/main/java/org/mybatis/dynamic/sql/render/RendererFactory.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2016-2024 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 - * - * https://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.render; - -import org.mybatis.dynamic.sql.delete.DeleteModel; -import org.mybatis.dynamic.sql.delete.render.DeleteRenderer; -import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider; -import org.mybatis.dynamic.sql.insert.BatchInsertModel; -import org.mybatis.dynamic.sql.insert.GeneralInsertModel; -import org.mybatis.dynamic.sql.insert.InsertModel; -import org.mybatis.dynamic.sql.insert.InsertSelectModel; -import org.mybatis.dynamic.sql.insert.MultiRowInsertModel; -import org.mybatis.dynamic.sql.insert.render.BatchInsert; -import org.mybatis.dynamic.sql.insert.render.BatchInsertRenderer; -import org.mybatis.dynamic.sql.insert.render.GeneralInsertRenderer; -import org.mybatis.dynamic.sql.insert.render.GeneralInsertStatementProvider; -import org.mybatis.dynamic.sql.insert.render.InsertRenderer; -import org.mybatis.dynamic.sql.insert.render.InsertSelectRenderer; -import org.mybatis.dynamic.sql.insert.render.InsertSelectStatementProvider; -import org.mybatis.dynamic.sql.insert.render.InsertStatementProvider; -import org.mybatis.dynamic.sql.insert.render.MultiRowInsertRenderer; -import org.mybatis.dynamic.sql.insert.render.MultiRowInsertStatementProvider; -import org.mybatis.dynamic.sql.select.MultiSelectModel; -import org.mybatis.dynamic.sql.select.SelectModel; -import org.mybatis.dynamic.sql.select.render.MultiSelectRenderer; -import org.mybatis.dynamic.sql.select.render.SelectRenderer; -import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; -import org.mybatis.dynamic.sql.select.render.SubQueryRenderer; -import org.mybatis.dynamic.sql.update.UpdateModel; -import org.mybatis.dynamic.sql.update.render.UpdateRenderer; -import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider; -import org.mybatis.dynamic.sql.util.FragmentAndParameters; - -public interface RendererFactory { - static Renderer<RenderingStrategy, DeleteStatementProvider> createDeleteRenderer(DeleteModel deleteModel) { - return renderingStrategy -> DeleteRenderer.withDeleteModel(deleteModel) - .withRenderingStrategy(renderingStrategy) - .build() - .render(); - } - - static <T> Renderer<RenderingStrategy, BatchInsert<T>> createBatchInsertRenderer( - BatchInsertModel<T> batchInsertModel) { - return renderingStrategy -> BatchInsertRenderer.withBatchInsertModel(batchInsertModel) - .withRenderingStrategy(renderingStrategy) - .build() - .render(); - } - - static Renderer<RenderingStrategy, GeneralInsertStatementProvider> createGeneralInsertRenderer( - GeneralInsertModel generalInsertModel) { - return renderingStrategy -> GeneralInsertRenderer.withInsertModel(generalInsertModel) - .withRenderingStrategy(renderingStrategy) - .build() - .render(); - } - - static <T> Renderer<RenderingStrategy, InsertStatementProvider<T>> createInsertRenderer( - InsertModel<T> insertModel) { - return renderingStrategy -> InsertRenderer.withInsertModel(insertModel) - .withRenderingStrategy(renderingStrategy) - .build() - .render(); - } - - static Renderer<RenderingStrategy, InsertSelectStatementProvider> createInsertSelectRenderer( - InsertSelectModel insertSelectModel) { - return renderingStrategy -> InsertSelectRenderer.withInsertSelectModel(insertSelectModel) - .withRenderingStrategy(renderingStrategy) - .build() - .render(); - } - - static <T> Renderer<RenderingStrategy, MultiRowInsertStatementProvider<T>> createMultiRowInsertRenderer( - MultiRowInsertModel<T> multiRowInsertModel) { - return renderingStrategy -> MultiRowInsertRenderer.withMultiRowInsertModel(multiRowInsertModel) - .withRenderingStrategy(renderingStrategy) - .build() - .render(); - } - - static Renderer<RenderingStrategy, SelectStatementProvider> createMultiSelectRenderer( - MultiSelectModel multiSelectModel) { - return renderingStrategy -> new MultiSelectRenderer.Builder() - .withMultiSelectModel(multiSelectModel) - .withRenderingStrategy(renderingStrategy) - .build() - .render(); - } - - static Renderer<RenderingStrategy, SelectStatementProvider> createSelectRenderer(SelectModel selectModel) { - return renderingStrategy -> SelectRenderer.withSelectModel(selectModel) - .withRenderingStrategy(renderingStrategy) - .build() - .render(); - } - - static Renderer<RenderingContext, FragmentAndParameters> createSubQueryRenderer(SelectModel selectModel, - String prefix, String suffix) { - return renderingContext -> SubQueryRenderer.withSelectModel(selectModel) - .withRenderingContext(renderingContext) - .build() - .render(prefix, suffix); - } - - static Renderer<RenderingStrategy, UpdateStatementProvider> createUpdateRenderer(UpdateModel updateModel) { - return renderingStrategy -> UpdateRenderer.withUpdateModel(updateModel) - .withRenderingStrategy(renderingStrategy) - .build() - .render(); - } -} diff --git a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java index 443a42c56..60539c660 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java @@ -21,8 +21,8 @@ import java.util.stream.Stream; import org.jetbrains.annotations.NotNull; -import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingStrategy; +import org.mybatis.dynamic.sql.select.render.MultiSelectRenderer; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.mybatis.dynamic.sql.util.Validator; @@ -47,8 +47,10 @@ public Stream<UnionQuery> unionQueries() { @NotNull public SelectStatementProvider render(RenderingStrategy renderingStrategy) { - return RendererFactory.createMultiSelectRenderer(this) - .render(renderingStrategy); + return MultiSelectRenderer.withMultiSelectModel(this) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); } public static class Builder extends AbstractBuilder<Builder> { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java index 14225147f..da01d09b5 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java @@ -21,8 +21,8 @@ import java.util.stream.Stream; import org.jetbrains.annotations.NotNull; -import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingStrategy; +import org.mybatis.dynamic.sql.select.render.SelectRenderer; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.mybatis.dynamic.sql.util.Validator; @@ -41,7 +41,10 @@ public Stream<QueryExpressionModel> queryExpressions() { @NotNull public SelectStatementProvider render(RenderingStrategy renderingStrategy) { - return RendererFactory.createSelectRenderer(this).render(renderingStrategy); + return SelectRenderer.withSelectModel(this) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); } public static Builder withQueryExpressions(List<QueryExpressionModel> queryExpressions) { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java index 4fe0b7e92..634896ad2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java @@ -21,7 +21,6 @@ import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.common.OrderByRenderer; -import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.select.MultiSelectModel; @@ -65,17 +64,21 @@ private SelectStatementProvider toSelectStatementProvider(FragmentCollector frag } private FragmentAndParameters renderSelect(SelectModel selectModel) { - return RendererFactory.createSubQueryRenderer(selectModel, - "(", //$NON-NLS-1$ - ")") //$NON-NLS-1$ - .render(renderingContext); + return SubQueryRenderer.withSelectModel(selectModel) + .withRenderingContext(renderingContext) + .withPrefix("(") //$NON-NLS-1$ + .withSuffix(")") //$NON-NLS-1$ + .build() + .render(); } private FragmentAndParameters renderSelect(UnionQuery unionQuery) { - return RendererFactory.createSubQueryRenderer(unionQuery.selectModel(), - unionQuery.connector() + " (", //$NON-NLS-1$ - ")") //$NON-NLS-1$ - .render(renderingContext); + return SubQueryRenderer.withSelectModel(unionQuery.selectModel()) + .withRenderingContext(renderingContext) + .withPrefix(unionQuery.connector() + " (") //$NON-NLS-1$ + .withSuffix(")") //$NON-NLS-1$ + .build() + .render(); } private Optional<FragmentAndParameters> renderOrderBy() { @@ -98,6 +101,10 @@ private FragmentAndParameters renderPagingModel(PagingModel pagingModel) { .render(); } + public static Builder withMultiSelectModel(MultiSelectModel multiSelectModel) { + return new Builder().withMultiSelectModel(multiSelectModel); + } + public static class Builder { private RenderingStrategy renderingStrategy; private MultiSelectModel multiSelectModel; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java index 5789b0298..6284b0b49 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java @@ -17,7 +17,6 @@ import java.util.Objects; -import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.select.SelectModel; @@ -25,19 +24,22 @@ public class SelectRenderer { private final SelectModel selectModel; - private final RenderingContext renderingContext; + private final RenderingStrategy renderingStrategy; private SelectRenderer(Builder builder) { selectModel = Objects.requireNonNull(builder.selectModel); - renderingContext = RenderingContext.withRenderingStrategy(builder.renderingStrategy) - .withStatementConfiguration(selectModel.statementConfiguration()) - .build(); + renderingStrategy = Objects.requireNonNull(builder.renderingStrategy); } public SelectStatementProvider render() { - FragmentAndParameters fragmentAndParameters = RendererFactory.createSubQueryRenderer(selectModel, - "", "") //$NON-NLS-1$ //$NON-NLS-2$ - .render(renderingContext); + RenderingContext renderingContext = RenderingContext.withRenderingStrategy(renderingStrategy) + .withStatementConfiguration(selectModel.statementConfiguration()) + .build(); + + FragmentAndParameters fragmentAndParameters = SubQueryRenderer.withSelectModel(selectModel) + .withRenderingContext(renderingContext) + .build() + .render(); return DefaultSelectStatementProvider.withSelectStatement(fragmentAndParameters.fragment()) .withParameters(fragmentAndParameters.parameters()) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java index 1f97f5e7d..b1d6c28ce 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java @@ -31,13 +31,17 @@ public class SubQueryRenderer { private final SelectModel selectModel; private final RenderingContext renderingContext; + private final String prefix; + private final String suffix; private SubQueryRenderer(Builder builder) { selectModel = Objects.requireNonNull(builder.selectModel); renderingContext = Objects.requireNonNull(builder.renderingContext); + prefix = builder.prefix == null ? "" : builder.prefix; //$NON-NLS-1$ + suffix = builder.suffix == null ? "" : builder.suffix; //$NON-NLS-1$ } - public FragmentAndParameters render(String prefix, String suffix) { + public FragmentAndParameters render() { FragmentCollector fragmentCollector = selectModel .queryExpressions() .map(this::renderQueryExpression) @@ -83,6 +87,8 @@ public static Builder withSelectModel(SelectModel selectModel) { public static class Builder { private SelectModel selectModel; private RenderingContext renderingContext; + private String prefix; + private String suffix; public Builder withRenderingContext(RenderingContext renderingContext) { this.renderingContext = renderingContext; @@ -94,6 +100,16 @@ public Builder withSelectModel(SelectModel selectModel) { return this; } + public Builder withPrefix(String prefix) { + this.prefix = prefix; + return this; + } + + public Builder withSuffix(String suffix) { + this.suffix = suffix; + return this; + } + public SubQueryRenderer build() { return new SubQueryRenderer(this); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java index ede734ece..24dfb190f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java @@ -19,7 +19,6 @@ import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.TableExpressionVisitor; -import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.SubQuery; import org.mybatis.dynamic.sql.util.FragmentAndParameters; @@ -41,8 +40,12 @@ public FragmentAndParameters visit(SubQuery subQuery) { String suffix = subQuery.alias().map(a -> ") " + a) //$NON-NLS-1$ .orElse(")"); //$NON-NLS-1$ - return RendererFactory.createSubQueryRenderer(subQuery.selectModel(), "(", suffix) //$NON-NLS-1$ - .render(renderingContext); + return SubQueryRenderer.withSelectModel(subQuery.selectModel()) + .withRenderingContext(renderingContext) + .withPrefix("(")//$NON-NLS-1$ + .withSuffix(suffix) + .build() + .render(); } public static class Builder { diff --git a/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java b/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java index f4ad201e5..2c828da91 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java @@ -26,8 +26,8 @@ import org.mybatis.dynamic.sql.common.CommonBuilder; import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; -import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingStrategy; +import org.mybatis.dynamic.sql.update.render.UpdateRenderer; import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider; import org.mybatis.dynamic.sql.util.AbstractColumnMapping; import org.mybatis.dynamic.sql.util.Validator; @@ -83,8 +83,10 @@ public StatementConfiguration statementConfiguration() { @NotNull public UpdateStatementProvider render(RenderingStrategy renderingStrategy) { - return RendererFactory.createUpdateRenderer(this) - .render(renderingStrategy); + return UpdateRenderer.withUpdateModel(this) + .withRenderingStrategy(renderingStrategy) + .build() + .render(); } public static Builder withTable(SqlTable table) { diff --git a/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java b/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java index 5464a253f..7bbe575fc 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java @@ -19,8 +19,8 @@ import java.util.Optional; import org.mybatis.dynamic.sql.render.RenderedParameterInfo; -import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.select.render.SubQueryRenderer; import org.mybatis.dynamic.sql.util.AbstractColumnMapping; import org.mybatis.dynamic.sql.util.ColumnToColumnMapping; import org.mybatis.dynamic.sql.util.ConstantMapping; @@ -84,10 +84,15 @@ public <T> Optional<FragmentAndParameters> visit(ValueWhenPresentMapping<T> mapp @Override public Optional<FragmentAndParameters> visit(SelectMapping mapping) { - FragmentAndParameters fragmentAndParameters = RendererFactory.createSubQueryRenderer(mapping.selectModel(), - renderingContext.aliasedColumnName(mapping.column()) + " = (", //$NON-NLS-1$ - ")") //$NON-NLS-1$ - .render(renderingContext); + String prefix = renderingContext.aliasedColumnName(mapping.column()) + " = ("; //$NON-NLS-1$ + + FragmentAndParameters fragmentAndParameters = SubQueryRenderer.withSelectModel(mapping.selectModel()) + .withRenderingContext(renderingContext) + .withPrefix(prefix) + .withSuffix(")") //$NON-NLS-1$ + .build() + .render(); + return Optional.of(fragmentAndParameters); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java index 6935b8b54..7e29a10d3 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java @@ -29,8 +29,8 @@ import org.mybatis.dynamic.sql.NotCriterion; import org.mybatis.dynamic.sql.SqlCriterion; import org.mybatis.dynamic.sql.SqlCriterionVisitor; -import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.select.render.SubQueryRenderer; import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.FragmentCollector; @@ -119,10 +119,12 @@ private <T> Optional<FragmentAndParameters> renderColumnAndCondition(ColumnAndCo private FragmentAndParameters renderExists(ExistsCriterion criterion) { ExistsPredicate existsPredicate = criterion.existsPredicate(); - return RendererFactory.createSubQueryRenderer(existsPredicate.selectModelBuilder().build(), - existsPredicate.operator() + " (", //$NON-NLS-1$ - ")") //$NON-NLS-1$ - .render(renderingContext); + return SubQueryRenderer.withSelectModel(existsPredicate.selectModelBuilder().build()) + .withRenderingContext(renderingContext) + .withPrefix(existsPredicate.operator() + " (") //$NON-NLS-1$ + .withSuffix(")") //$NON-NLS-1$ + .build() + .render(); } private List<RenderedCriterion> renderSubCriteria(List<AndOrCriteriaGroup> subCriteria) { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java index c13633b1d..d5cdc0dd2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java @@ -29,8 +29,8 @@ import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.ConditionVisitor; import org.mybatis.dynamic.sql.render.RenderedParameterInfo; -import org.mybatis.dynamic.sql.render.RendererFactory; import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.select.render.SubQueryRenderer; import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.FragmentCollector; @@ -95,10 +95,12 @@ public FragmentAndParameters visit(AbstractTwoValueCondition<T> condition) { @Override public FragmentAndParameters visit(AbstractSubselectCondition<T> condition) { - return RendererFactory.createSubQueryRenderer(condition.selectModel(), - condition.operator() + " (", //$NON-NLS-1$ - ")") //$NON-NLS-1$ - .render(renderingContext); + return SubQueryRenderer.withSelectModel(condition.selectModel()) + .withRenderingContext(renderingContext) + .withPrefix(condition.operator() + " (") //$NON-NLS-1$ + .withSuffix(")") //$NON-NLS-1$ + .build() + .render(); } @Override From 1a374f81b4f139d2e5b3894e271918f1d299a60b Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 25 Nov 2024 13:31:36 -0500 Subject: [PATCH 125/260] Save some garbage in the providers --- .../DefaultDeleteStatementProvider.java | 2 +- ...DefaultGeneralInsertStatementProvider.java | 4 +- .../DefaultUpdateStatementProvider.java | 4 +- .../sql/util/FragmentAndParameters.java | 3 +- .../mybatis/dynamic/sql/where/WhereModel.java | 3 +- .../render/DefaultWhereClauseProvider.java | 63 +++++++++++++++++++ .../sql/where/render/WhereClauseProvider.java | 44 +------------ 7 files changed, 75 insertions(+), 48 deletions(-) create mode 100644 src/main/java/org/mybatis/dynamic/sql/where/render/DefaultWhereClauseProvider.java diff --git a/src/main/java/org/mybatis/dynamic/sql/delete/render/DefaultDeleteStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/delete/render/DefaultDeleteStatementProvider.java index 89b72333b..ef2ade7f0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/render/DefaultDeleteStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/render/DefaultDeleteStatementProvider.java @@ -25,7 +25,7 @@ public class DefaultDeleteStatementProvider implements DeleteStatementProvider { private DefaultDeleteStatementProvider(Builder builder) { deleteStatement = Objects.requireNonNull(builder.deleteStatement); - parameters = Objects.requireNonNull(builder.parameters); + parameters = builder.parameters; } @Override diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultGeneralInsertStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultGeneralInsertStatementProvider.java index de1c41266..5cd4144d6 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultGeneralInsertStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultGeneralInsertStatementProvider.java @@ -22,11 +22,11 @@ public class DefaultGeneralInsertStatementProvider implements GeneralInsertStatementProvider, InsertSelectStatementProvider { private final String insertStatement; - private final Map<String, Object> parameters = new HashMap<>(); + private final Map<String, Object> parameters; private DefaultGeneralInsertStatementProvider(Builder builder) { insertStatement = Objects.requireNonNull(builder.insertStatement); - parameters.putAll(builder.parameters); + parameters = builder.parameters; } @Override diff --git a/src/main/java/org/mybatis/dynamic/sql/update/render/DefaultUpdateStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/update/render/DefaultUpdateStatementProvider.java index a103bd604..c2f14fbd6 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/render/DefaultUpdateStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/render/DefaultUpdateStatementProvider.java @@ -21,11 +21,11 @@ public class DefaultUpdateStatementProvider implements UpdateStatementProvider { private final String updateStatement; - private final Map<String, Object> parameters = new HashMap<>(); + private final Map<String, Object> parameters; private DefaultUpdateStatementProvider(Builder builder) { updateStatement = Objects.requireNonNull(builder.updateStatement); - parameters.putAll(builder.parameters); + parameters = builder.parameters; } @Override diff --git a/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java b/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java index 4c240120c..8f2b58aae 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java @@ -15,6 +15,7 @@ */ package org.mybatis.dynamic.sql.util; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Objects; @@ -28,7 +29,7 @@ public class FragmentAndParameters { private FragmentAndParameters(Builder builder) { fragment = Objects.requireNonNull(builder.fragment); - parameters = Objects.requireNonNull(builder.parameters); + parameters = Collections.unmodifiableMap(builder.parameters); } public String fragment() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/WhereModel.java b/src/main/java/org/mybatis/dynamic/sql/where/WhereModel.java index 8db761223..5c99d68ff 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/WhereModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/WhereModel.java @@ -24,6 +24,7 @@ import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.render.TableAliasCalculator; import org.mybatis.dynamic.sql.util.FragmentAndParameters; +import org.mybatis.dynamic.sql.where.render.DefaultWhereClauseProvider; import org.mybatis.dynamic.sql.where.render.WhereClauseProvider; import org.mybatis.dynamic.sql.where.render.WhereRenderer; @@ -92,7 +93,7 @@ private Optional<WhereClauseProvider> render(RenderingContext renderingContext) } private WhereClauseProvider toWhereClauseProvider(FragmentAndParameters fragmentAndParameters) { - return WhereClauseProvider.withWhereClause(fragmentAndParameters.fragment()) + return DefaultWhereClauseProvider.withWhereClause(fragmentAndParameters.fragment()) .withParameters(fragmentAndParameters.parameters()) .build(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultWhereClauseProvider.java b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultWhereClauseProvider.java new file mode 100644 index 000000000..bf68eb7cf --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultWhereClauseProvider.java @@ -0,0 +1,63 @@ +/* + * Copyright 2016-2024 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 + * + * https://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.where.render; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public class DefaultWhereClauseProvider implements WhereClauseProvider { + private final String whereClause; + private final Map<String, Object> parameters; + + private DefaultWhereClauseProvider(Builder builder) { + whereClause = Objects.requireNonNull(builder.whereClause); + parameters = builder.parameters; + } + + @Override + public Map<String, Object> getParameters() { + return parameters; + } + + @Override + public String getWhereClause() { + return whereClause; + } + + public static Builder withWhereClause(String whereClause) { + return new Builder().withWhereClause(whereClause); + } + + public static class Builder { + private String whereClause; + private final Map<String, Object> parameters = new HashMap<>(); + + public Builder withWhereClause(String whereClause) { + this.whereClause = whereClause; + return this; + } + + public Builder withParameters(Map<String, Object> parameters) { + this.parameters.putAll(parameters); + return this; + } + + public DefaultWhereClauseProvider build() { + return new DefaultWhereClauseProvider(this); + } + } +} diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/WhereClauseProvider.java b/src/main/java/org/mybatis/dynamic/sql/where/render/WhereClauseProvider.java index 37d051e81..1e8d16be5 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/WhereClauseProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/WhereClauseProvider.java @@ -15,48 +15,10 @@ */ package org.mybatis.dynamic.sql.where.render; -import java.util.Collections; -import java.util.HashMap; import java.util.Map; -import java.util.Objects; -public class WhereClauseProvider { - private final String whereClause; - private final Map<String, Object> parameters; +public interface WhereClauseProvider { + Map<String, Object> getParameters(); - private WhereClauseProvider(Builder builder) { - whereClause = Objects.requireNonNull(builder.whereClause); - parameters = Objects.requireNonNull(builder.parameters); - } - - public Map<String, Object> getParameters() { - return Collections.unmodifiableMap(parameters); - } - - public String getWhereClause() { - return whereClause; - } - - public static Builder withWhereClause(String whereClause) { - return new Builder().withWhereClause(whereClause); - } - - public static class Builder { - private String whereClause; - private final Map<String, Object> parameters = new HashMap<>(); - - public Builder withWhereClause(String whereClause) { - this.whereClause = whereClause; - return this; - } - - public Builder withParameters(Map<String, Object> parameters) { - this.parameters.putAll(parameters); - return this; - } - - public WhereClauseProvider build() { - return new WhereClauseProvider(this); - } - } + String getWhereClause(); } From 42d5a4318f0e92d8772c3c0622863de7e08debb5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Nov 2024 13:30:19 +0000 Subject: [PATCH 126/260] Update dependency org.mybatis:mybatis to v3.5.17 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d914073b2..e35633113 100644 --- a/pom.xml +++ b/pom.xml @@ -103,7 +103,7 @@ <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> - <version>3.5.16</version> + <version>3.5.17</version> <scope>provided</scope> <optional>true</optional> </dependency> From 38f264c913453a5d7a60952455f423e56c074023 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 27 Nov 2024 15:10:00 +0000 Subject: [PATCH 127/260] Update dependency org.jetbrains.kotlin:kotlin-stdlib-jdk8 to v2.1.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d914073b2..fa76960a3 100644 --- a/pom.xml +++ b/pom.xml @@ -69,7 +69,7 @@ <module.name>org.mybatis.dynamic.sql</module.name> - <kotlin.version>2.0.21</kotlin.version> + <kotlin.version>2.1.0</kotlin.version> <kotlin.compiler.jvmTarget>17</kotlin.compiler.jvmTarget> <kotlin.compiler.languageVersion>2.0</kotlin.compiler.languageVersion> <kotlin.compiler.apiVersion>2.0</kotlin.compiler.apiVersion> From 1c4c5b68515f211e18fc4404ab911487c769abfa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Dec 2024 01:25:47 +0000 Subject: [PATCH 128/260] Update dependency org.mybatis:mybatis-parent to v46 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index abf481499..9ca71d163 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ <parent> <groupId>org.mybatis</groupId> <artifactId>mybatis-parent</artifactId> - <version>45</version> + <version>46</version> </parent> <groupId>org.mybatis.dynamic-sql</groupId> From 621dd7354da03320c208490efe136a8362a32d49 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 12 Dec 2024 11:52:17 +0000 Subject: [PATCH 129/260] Update dependency org.springframework:spring-jdbc to v6.2.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9ca71d163..7ced7af99 100644 --- a/pom.xml +++ b/pom.xml @@ -96,7 +96,7 @@ <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> - <version>6.2.0</version> + <version>6.2.1</version> <scope>provided</scope> <optional>true</optional> </dependency> From df22341467ebb54c6279301e1a49957ed878d8dd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 15:20:10 +0000 Subject: [PATCH 130/260] Update junit5 monorepo to v5.11.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7ced7af99..ccdf57319 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ <java.release.version>17</java.release.version> <java.test.version>17</java.test.version> <java.test.release.version>17</java.test.release.version> - <junit.jupiter.version>5.11.3</junit.jupiter.version> + <junit.jupiter.version>5.11.4</junit.jupiter.version> <spring.batch.version>5.2.0</spring.batch.version> <checkstyle.config>checkstyle-override.xml</checkstyle.config> From 2182ef4c07e9f8c82dec72de303ab18c954ea2fa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:11:29 +0000 Subject: [PATCH 131/260] Update dependency ch.qos.logback:logback-classic to v1.5.13 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ccdf57319..fc9d6dc18 100644 --- a/pom.xml +++ b/pom.xml @@ -165,7 +165,7 @@ <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> - <version>1.5.12</version> + <version>1.5.13</version> <scope>test</scope> </dependency> <dependency> From 072d705215fd5d840c58520b56bb4934c3f03521 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 18 Dec 2024 21:35:33 +0000 Subject: [PATCH 132/260] Update dependency org.springframework.batch:spring-batch-test to v5.2.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ccdf57319..e0cc3e5f5 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ <java.test.version>17</java.test.version> <java.test.release.version>17</java.test.release.version> <junit.jupiter.version>5.11.4</junit.jupiter.version> - <spring.batch.version>5.2.0</spring.batch.version> + <spring.batch.version>5.2.1</spring.batch.version> <checkstyle.config>checkstyle-override.xml</checkstyle.config> From 3ae60d76b4c0f2dcc0cc30d214cd4216c3769aa5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:22:26 +0000 Subject: [PATCH 133/260] Update dependency ch.qos.logback:logback-classic to v1.5.14 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4bb813b97..d94583b26 100644 --- a/pom.xml +++ b/pom.xml @@ -165,7 +165,7 @@ <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> - <version>1.5.13</version> + <version>1.5.14</version> <scope>test</scope> </dependency> <dependency> From b17ad1585815c1bed9ce50821d6f7293106fd0d8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 19 Dec 2024 20:55:07 +0000 Subject: [PATCH 134/260] Update dependency org.assertj:assertj-core to v3.27.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d94583b26..d21f27850 100644 --- a/pom.xml +++ b/pom.xml @@ -129,7 +129,7 @@ <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> - <version>3.26.3</version> + <version>3.27.0</version> <scope>test</scope> </dependency> <dependency> From 9c192a14fa1b87753a0b5a4d9417f2ad8afc2192 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 21 Dec 2024 19:40:19 +0000 Subject: [PATCH 135/260] Update dependency ch.qos.logback:logback-classic to v1.5.15 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d21f27850..23bd4575a 100644 --- a/pom.xml +++ b/pom.xml @@ -165,7 +165,7 @@ <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> - <version>1.5.14</version> + <version>1.5.15</version> <scope>test</scope> </dependency> <dependency> From 7dd495f0cc40f3a5fe03fd9a1d493b6aa0e6db0d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Dec 2024 21:44:39 +0000 Subject: [PATCH 136/260] Update dependency org.mybatis:mybatis-parent to v48 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 23bd4575a..e57313231 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ <parent> <groupId>org.mybatis</groupId> <artifactId>mybatis-parent</artifactId> - <version>46</version> + <version>48</version> </parent> <groupId>org.mybatis.dynamic-sql</groupId> From 961e37b0aa1b67ba259a4ae8a6c421213b5bf41b Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Sat, 28 Dec 2024 09:20:47 -0500 Subject: [PATCH 137/260] Update Java Matrix --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5a6947c02..7f41206e9 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -9,7 +9,7 @@ jobs: matrix: cache: [maven] distribution: [temurin] - java: [17, 21, 22, 23-ea] + java: [17, 21, 23, 24-ea, 25-ea] os: [ubuntu-latest] fail-fast: false max-parallel: 4 From 17ac0c06d3885967ebb039417566c6d2aa850c60 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Sat, 28 Dec 2024 09:29:26 -0500 Subject: [PATCH 138/260] Update Java Matrix and test containers versions --- .github/workflows/ci.yaml | 2 +- src/test/java/config/TestContainersConfiguration.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 7f41206e9..e89bd81b6 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -9,7 +9,7 @@ jobs: matrix: cache: [maven] distribution: [temurin] - java: [17, 21, 23, 24-ea, 25-ea] + java: [17, 21, 23, 24-ea] os: [ubuntu-latest] fail-fast: false max-parallel: 4 diff --git a/src/test/java/config/TestContainersConfiguration.java b/src/test/java/config/TestContainersConfiguration.java index fc6607dbb..1919fc0f9 100644 --- a/src/test/java/config/TestContainersConfiguration.java +++ b/src/test/java/config/TestContainersConfiguration.java @@ -21,6 +21,6 @@ * Utility interface to hold Docker image tags for the test containers we use */ public interface TestContainersConfiguration { - DockerImageName POSTGRES_LATEST = DockerImageName.parse("postgres:17.0"); - DockerImageName MARIADB_LATEST = DockerImageName.parse("mariadb:11.5.2"); + DockerImageName POSTGRES_LATEST = DockerImageName.parse("postgres:17.2"); + DockerImageName MARIADB_LATEST = DockerImageName.parse("mariadb:11.6.2"); } From d9093f95156dfae23d06ccf371aa7f89a674c7b7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Jan 2025 06:04:55 +0000 Subject: [PATCH 139/260] Update dependency org.mybatis:mybatis to v3.5.18 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e57313231..dafe341c8 100644 --- a/pom.xml +++ b/pom.xml @@ -103,7 +103,7 @@ <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> - <version>3.5.17</version> + <version>3.5.18</version> <scope>provided</scope> <optional>true</optional> </dependency> From 876201b0deb33642a9b6c2686fcd508c293a981b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 1 Jan 2025 19:17:27 +0000 Subject: [PATCH 140/260] Update dependency org.assertj:assertj-core to v3.27.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dafe341c8..9ffb9a9cc 100644 --- a/pom.xml +++ b/pom.xml @@ -129,7 +129,7 @@ <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> - <version>3.27.0</version> + <version>3.27.1</version> <scope>test</scope> </dependency> <dependency> From 1994eaaed7ffd3b001ee0a202e909c7eccb305b2 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 1 Jan 2025 14:17:36 -0500 Subject: [PATCH 141/260] Update Copyright for 2025 --- .mvn/extensions.xml | 2 +- .mvn/settings.xml | 2 +- checkstyle-override.xml | 2 +- pom.xml | 2 +- .../mybatis/dynamic/sql/AbstractColumnComparisonCondition.java | 2 +- .../org/mybatis/dynamic/sql/AbstractListValueCondition.java | 2 +- .../java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java | 2 +- .../org/mybatis/dynamic/sql/AbstractSingleValueCondition.java | 2 +- .../org/mybatis/dynamic/sql/AbstractSubselectCondition.java | 2 +- .../java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java | 2 +- src/main/java/org/mybatis/dynamic/sql/AliasableSqlTable.java | 2 +- src/main/java/org/mybatis/dynamic/sql/AndOrCriteriaGroup.java | 2 +- src/main/java/org/mybatis/dynamic/sql/BasicColumn.java | 2 +- src/main/java/org/mybatis/dynamic/sql/BindableColumn.java | 2 +- src/main/java/org/mybatis/dynamic/sql/BoundValue.java | 2 +- .../org/mybatis/dynamic/sql/ColumnAndConditionCriterion.java | 2 +- src/main/java/org/mybatis/dynamic/sql/ConditionVisitor.java | 2 +- src/main/java/org/mybatis/dynamic/sql/Constant.java | 2 +- src/main/java/org/mybatis/dynamic/sql/CriteriaGroup.java | 2 +- src/main/java/org/mybatis/dynamic/sql/DerivedColumn.java | 2 +- src/main/java/org/mybatis/dynamic/sql/ExistsCriterion.java | 2 +- src/main/java/org/mybatis/dynamic/sql/ExistsPredicate.java | 2 +- src/main/java/org/mybatis/dynamic/sql/NotCriterion.java | 2 +- .../java/org/mybatis/dynamic/sql/ParameterTypeConverter.java | 2 +- src/main/java/org/mybatis/dynamic/sql/SortSpecification.java | 2 +- src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java | 2 +- src/main/java/org/mybatis/dynamic/sql/SqlColumn.java | 2 +- src/main/java/org/mybatis/dynamic/sql/SqlCriterion.java | 2 +- src/main/java/org/mybatis/dynamic/sql/SqlCriterionVisitor.java | 2 +- src/main/java/org/mybatis/dynamic/sql/SqlTable.java | 2 +- src/main/java/org/mybatis/dynamic/sql/StringConstant.java | 2 +- src/main/java/org/mybatis/dynamic/sql/TableExpression.java | 2 +- .../java/org/mybatis/dynamic/sql/TableExpressionVisitor.java | 2 +- src/main/java/org/mybatis/dynamic/sql/VisitableCondition.java | 2 +- .../dynamic/sql/common/AbstractBooleanExpressionDSL.java | 2 +- .../dynamic/sql/common/AbstractBooleanExpressionModel.java | 2 +- .../dynamic/sql/common/AbstractBooleanExpressionRenderer.java | 2 +- src/main/java/org/mybatis/dynamic/sql/common/CommonBuilder.java | 2 +- src/main/java/org/mybatis/dynamic/sql/common/OrderByModel.java | 2 +- .../java/org/mybatis/dynamic/sql/common/OrderByRenderer.java | 2 +- .../mybatis/dynamic/sql/configuration/GlobalConfiguration.java | 2 +- .../org/mybatis/dynamic/sql/configuration/GlobalContext.java | 2 +- .../dynamic/sql/configuration/StatementConfiguration.java | 2 +- src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java | 2 +- .../java/org/mybatis/dynamic/sql/delete/DeleteDSLCompleter.java | 2 +- src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java | 2 +- .../sql/delete/render/DefaultDeleteStatementProvider.java | 2 +- .../org/mybatis/dynamic/sql/delete/render/DeleteRenderer.java | 2 +- .../dynamic/sql/delete/render/DeleteStatementProvider.java | 2 +- .../dynamic/sql/exception/DuplicateTableAliasException.java | 2 +- .../org/mybatis/dynamic/sql/exception/DynamicSqlException.java | 2 +- .../org/mybatis/dynamic/sql/exception/InvalidSqlException.java | 2 +- .../dynamic/sql/exception/NonRenderingWhereClauseException.java | 2 +- .../mybatis/dynamic/sql/insert/AbstractMultiRowInsertModel.java | 2 +- .../java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java | 2 +- .../java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java | 2 +- .../java/org/mybatis/dynamic/sql/insert/GeneralInsertDSL.java | 2 +- .../java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java | 2 +- .../org/mybatis/dynamic/sql/insert/InsertColumnListModel.java | 2 +- src/main/java/org/mybatis/dynamic/sql/insert/InsertDSL.java | 2 +- src/main/java/org/mybatis/dynamic/sql/insert/InsertModel.java | 2 +- .../java/org/mybatis/dynamic/sql/insert/InsertSelectDSL.java | 2 +- .../java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java | 2 +- .../java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java | 2 +- .../org/mybatis/dynamic/sql/insert/MultiRowInsertModel.java | 2 +- .../java/org/mybatis/dynamic/sql/insert/render/BatchInsert.java | 2 +- .../mybatis/dynamic/sql/insert/render/BatchInsertRenderer.java | 2 +- .../insert/render/DefaultGeneralInsertStatementProvider.java | 2 +- .../sql/insert/render/DefaultInsertStatementProvider.java | 2 +- .../insert/render/DefaultMultiRowInsertStatementProvider.java | 2 +- .../dynamic/sql/insert/render/FieldAndValueAndParameters.java | 2 +- .../dynamic/sql/insert/render/FieldAndValueCollector.java | 2 +- .../dynamic/sql/insert/render/GeneralInsertRenderer.java | 2 +- .../sql/insert/render/GeneralInsertStatementProvider.java | 2 +- .../sql/insert/render/GeneralInsertValuePhraseVisitor.java | 2 +- .../org/mybatis/dynamic/sql/insert/render/InsertRenderer.java | 2 +- .../dynamic/sql/insert/render/InsertRenderingUtilities.java | 2 +- .../mybatis/dynamic/sql/insert/render/InsertSelectRenderer.java | 2 +- .../sql/insert/render/InsertSelectStatementProvider.java | 2 +- .../dynamic/sql/insert/render/InsertStatementProvider.java | 2 +- .../dynamic/sql/insert/render/MultiRowInsertRenderer.java | 2 +- .../sql/insert/render/MultiRowInsertStatementProvider.java | 2 +- .../dynamic/sql/insert/render/MultiRowValuePhraseVisitor.java | 2 +- .../mybatis/dynamic/sql/insert/render/ValuePhraseVisitor.java | 2 +- .../dynamic/sql/render/ExplicitTableAliasCalculator.java | 2 +- .../dynamic/sql/render/GuaranteedTableAliasCalculator.java | 2 +- .../mybatis/dynamic/sql/render/MyBatis3RenderingStrategy.java | 2 +- .../org/mybatis/dynamic/sql/render/RenderedParameterInfo.java | 2 +- .../java/org/mybatis/dynamic/sql/render/RenderingContext.java | 2 +- .../org/mybatis/dynamic/sql/render/RenderingStrategies.java | 2 +- .../java/org/mybatis/dynamic/sql/render/RenderingStrategy.java | 2 +- .../sql/render/SpringNamedParameterRenderingStrategy.java | 2 +- .../org/mybatis/dynamic/sql/render/TableAliasCalculator.java | 2 +- .../dynamic/sql/render/TableAliasCalculatorWithParent.java | 2 +- .../org/mybatis/dynamic/sql/select/AbstractHavingFinisher.java | 2 +- .../org/mybatis/dynamic/sql/select/AbstractHavingStarter.java | 2 +- .../mybatis/dynamic/sql/select/AbstractQueryExpressionDSL.java | 2 +- .../org/mybatis/dynamic/sql/select/AbstractSelectModel.java | 2 +- .../org/mybatis/dynamic/sql/select/ColumnSortSpecification.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/CountDSL.java | 2 +- .../java/org/mybatis/dynamic/sql/select/CountDSLCompleter.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/GroupByModel.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/HavingApplier.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/HavingDSL.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/HavingModel.java | 2 +- .../java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java | 2 +- .../java/org/mybatis/dynamic/sql/select/MultiSelectModel.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/PagingDSL.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/PagingModel.java | 2 +- .../java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java | 2 +- .../org/mybatis/dynamic/sql/select/QueryExpressionModel.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java | 2 +- .../java/org/mybatis/dynamic/sql/select/SelectDSLCompleter.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java | 2 +- .../org/mybatis/dynamic/sql/select/SimpleSortSpecification.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/SubQuery.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/UnionQuery.java | 2 +- .../org/mybatis/dynamic/sql/select/aggregate/AbstractCount.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/aggregate/Avg.java | 2 +- .../java/org/mybatis/dynamic/sql/select/aggregate/Count.java | 2 +- .../java/org/mybatis/dynamic/sql/select/aggregate/CountAll.java | 2 +- .../org/mybatis/dynamic/sql/select/aggregate/CountDistinct.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/aggregate/Max.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/aggregate/Min.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/aggregate/Sum.java | 2 +- .../dynamic/sql/select/caseexpression/BasicWhenCondition.java | 2 +- .../sql/select/caseexpression/ConditionBasedWhenCondition.java | 2 +- .../org/mybatis/dynamic/sql/select/caseexpression/ElseDSL.java | 2 +- .../dynamic/sql/select/caseexpression/SearchedCaseDSL.java | 2 +- .../dynamic/sql/select/caseexpression/SearchedCaseModel.java | 2 +- .../sql/select/caseexpression/SearchedCaseWhenCondition.java | 2 +- .../dynamic/sql/select/caseexpression/SimpleCaseDSL.java | 2 +- .../dynamic/sql/select/caseexpression/SimpleCaseModel.java | 2 +- .../sql/select/caseexpression/SimpleCaseWhenCondition.java | 2 +- .../select/caseexpression/SimpleCaseWhenConditionVisitor.java | 2 +- .../org/mybatis/dynamic/sql/select/caseexpression/ThenDSL.java | 2 +- .../sql/select/function/AbstractTypeConvertingFunction.java | 2 +- .../dynamic/sql/select/function/AbstractUniTypeFunction.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/function/Add.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/function/Cast.java | 2 +- .../java/org/mybatis/dynamic/sql/select/function/Concat.java | 2 +- .../org/mybatis/dynamic/sql/select/function/Concatenate.java | 2 +- .../java/org/mybatis/dynamic/sql/select/function/Divide.java | 2 +- .../java/org/mybatis/dynamic/sql/select/function/Lower.java | 2 +- .../java/org/mybatis/dynamic/sql/select/function/Multiply.java | 2 +- .../mybatis/dynamic/sql/select/function/OperatorFunction.java | 2 +- .../java/org/mybatis/dynamic/sql/select/function/Substring.java | 2 +- .../java/org/mybatis/dynamic/sql/select/function/Subtract.java | 2 +- .../java/org/mybatis/dynamic/sql/select/function/Upper.java | 2 +- .../java/org/mybatis/dynamic/sql/select/join/JoinModel.java | 2 +- .../org/mybatis/dynamic/sql/select/join/JoinSpecification.java | 2 +- src/main/java/org/mybatis/dynamic/sql/select/join/JoinType.java | 2 +- .../sql/select/render/DefaultSelectStatementProvider.java | 2 +- .../sql/select/render/FetchFirstPagingModelRenderer.java | 2 +- .../org/mybatis/dynamic/sql/select/render/HavingRenderer.java | 2 +- .../org/mybatis/dynamic/sql/select/render/JoinRenderer.java | 2 +- .../dynamic/sql/select/render/JoinSpecificationRenderer.java | 2 +- .../sql/select/render/LimitAndOffsetPagingModelRenderer.java | 2 +- .../mybatis/dynamic/sql/select/render/MultiSelectRenderer.java | 2 +- .../mybatis/dynamic/sql/select/render/PagingModelRenderer.java | 2 +- .../dynamic/sql/select/render/QueryExpressionRenderer.java | 2 +- .../mybatis/dynamic/sql/select/render/SearchedCaseRenderer.java | 2 +- .../sql/select/render/SearchedCaseWhenConditionRenderer.java | 2 +- .../org/mybatis/dynamic/sql/select/render/SelectRenderer.java | 2 +- .../dynamic/sql/select/render/SelectStatementProvider.java | 2 +- .../mybatis/dynamic/sql/select/render/SimpleCaseRenderer.java | 2 +- .../sql/select/render/SimpleCaseWhenConditionRenderer.java | 2 +- .../org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java | 2 +- .../dynamic/sql/select/render/TableExpressionRenderer.java | 2 +- src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java | 2 +- .../java/org/mybatis/dynamic/sql/update/UpdateDSLCompleter.java | 2 +- src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java | 2 +- .../sql/update/render/DefaultUpdateStatementProvider.java | 2 +- .../org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java | 2 +- .../org/mybatis/dynamic/sql/update/render/UpdateRenderer.java | 2 +- .../dynamic/sql/update/render/UpdateStatementProvider.java | 2 +- .../org/mybatis/dynamic/sql/util/AbstractColumnMapping.java | 2 +- src/main/java/org/mybatis/dynamic/sql/util/Buildable.java | 2 +- .../java/org/mybatis/dynamic/sql/util/ColumnMappingVisitor.java | 2 +- .../org/mybatis/dynamic/sql/util/ColumnToColumnMapping.java | 2 +- .../org/mybatis/dynamic/sql/util/ConfigurableStatement.java | 2 +- src/main/java/org/mybatis/dynamic/sql/util/ConstantMapping.java | 2 +- .../org/mybatis/dynamic/sql/util/FragmentAndParameters.java | 2 +- .../java/org/mybatis/dynamic/sql/util/FragmentCollector.java | 2 +- .../mybatis/dynamic/sql/util/GeneralInsertMappingVisitor.java | 2 +- .../java/org/mybatis/dynamic/sql/util/InsertMappingVisitor.java | 2 +- src/main/java/org/mybatis/dynamic/sql/util/InternalError.java | 2 +- src/main/java/org/mybatis/dynamic/sql/util/Messages.java | 2 +- .../mybatis/dynamic/sql/util/MultiRowInsertMappingVisitor.java | 2 +- src/main/java/org/mybatis/dynamic/sql/util/NullMapping.java | 2 +- src/main/java/org/mybatis/dynamic/sql/util/Predicates.java | 2 +- src/main/java/org/mybatis/dynamic/sql/util/PropertyMapping.java | 2 +- .../mybatis/dynamic/sql/util/PropertyWhenPresentMapping.java | 2 +- src/main/java/org/mybatis/dynamic/sql/util/RowMapping.java | 2 +- src/main/java/org/mybatis/dynamic/sql/util/SelectMapping.java | 2 +- .../java/org/mybatis/dynamic/sql/util/SqlProviderAdapter.java | 2 +- .../org/mybatis/dynamic/sql/util/StringConstantMapping.java | 2 +- src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java | 2 +- .../java/org/mybatis/dynamic/sql/util/UpdateMappingVisitor.java | 2 +- src/main/java/org/mybatis/dynamic/sql/util/Utilities.java | 2 +- src/main/java/org/mybatis/dynamic/sql/util/Validator.java | 2 +- src/main/java/org/mybatis/dynamic/sql/util/ValueMapping.java | 2 +- .../java/org/mybatis/dynamic/sql/util/ValueOrNullMapping.java | 2 +- .../org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java | 2 +- .../mybatis/dynamic/sql/util/mybatis3/CommonCountMapper.java | 2 +- .../mybatis/dynamic/sql/util/mybatis3/CommonDeleteMapper.java | 2 +- .../dynamic/sql/util/mybatis3/CommonGeneralInsertMapper.java | 2 +- .../mybatis/dynamic/sql/util/mybatis3/CommonInsertMapper.java | 2 +- .../mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java | 2 +- .../mybatis/dynamic/sql/util/mybatis3/CommonUpdateMapper.java | 2 +- .../org/mybatis/dynamic/sql/util/mybatis3/MyBatis3Utils.java | 2 +- .../org/mybatis/dynamic/sql/util/spring/BatchInsertUtility.java | 2 +- .../sql/util/spring/NamedParameterJdbcTemplateExtensions.java | 2 +- .../SpringBatchPagingItemReaderRenderingStrategy.java | 2 +- .../sql/util/springbatch/SpringBatchProviderAdapter.java | 2 +- .../dynamic/sql/util/springbatch/SpringBatchUtility.java | 2 +- .../org/mybatis/dynamic/sql/where/AbstractWhereFinisher.java | 2 +- .../org/mybatis/dynamic/sql/where/AbstractWhereStarter.java | 2 +- .../java/org/mybatis/dynamic/sql/where/EmbeddedWhereModel.java | 2 +- src/main/java/org/mybatis/dynamic/sql/where/WhereApplier.java | 2 +- src/main/java/org/mybatis/dynamic/sql/where/WhereDSL.java | 2 +- src/main/java/org/mybatis/dynamic/sql/where/WhereModel.java | 2 +- .../org/mybatis/dynamic/sql/where/condition/AndGatherer.java | 2 +- .../sql/where/condition/CaseInsensitiveVisitableCondition.java | 2 +- .../java/org/mybatis/dynamic/sql/where/condition/IsBetween.java | 2 +- .../java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java | 2 +- .../mybatis/dynamic/sql/where/condition/IsEqualToColumn.java | 2 +- .../dynamic/sql/where/condition/IsEqualToWithSubselect.java | 2 +- .../org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java | 2 +- .../dynamic/sql/where/condition/IsGreaterThanColumn.java | 2 +- .../dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java | 2 +- .../sql/where/condition/IsGreaterThanOrEqualToColumn.java | 2 +- .../where/condition/IsGreaterThanOrEqualToWithSubselect.java | 2 +- .../dynamic/sql/where/condition/IsGreaterThanWithSubselect.java | 2 +- src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java | 2 +- .../dynamic/sql/where/condition/IsInCaseInsensitive.java | 2 +- .../sql/where/condition/IsInCaseInsensitiveWhenPresent.java | 2 +- .../mybatis/dynamic/sql/where/condition/IsInWhenPresent.java | 2 +- .../mybatis/dynamic/sql/where/condition/IsInWithSubselect.java | 2 +- .../org/mybatis/dynamic/sql/where/condition/IsLessThan.java | 2 +- .../mybatis/dynamic/sql/where/condition/IsLessThanColumn.java | 2 +- .../dynamic/sql/where/condition/IsLessThanOrEqualTo.java | 2 +- .../dynamic/sql/where/condition/IsLessThanOrEqualToColumn.java | 2 +- .../sql/where/condition/IsLessThanOrEqualToWithSubselect.java | 2 +- .../dynamic/sql/where/condition/IsLessThanWithSubselect.java | 2 +- .../java/org/mybatis/dynamic/sql/where/condition/IsLike.java | 2 +- .../dynamic/sql/where/condition/IsLikeCaseInsensitive.java | 2 +- .../org/mybatis/dynamic/sql/where/condition/IsNotBetween.java | 2 +- .../org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java | 2 +- .../mybatis/dynamic/sql/where/condition/IsNotEqualToColumn.java | 2 +- .../dynamic/sql/where/condition/IsNotEqualToWithSubselect.java | 2 +- .../java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java | 2 +- .../dynamic/sql/where/condition/IsNotInCaseInsensitive.java | 2 +- .../sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java | 2 +- .../mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java | 2 +- .../dynamic/sql/where/condition/IsNotInWithSubselect.java | 2 +- .../java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java | 2 +- .../dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java | 2 +- .../java/org/mybatis/dynamic/sql/where/condition/IsNotNull.java | 2 +- .../java/org/mybatis/dynamic/sql/where/condition/IsNull.java | 2 +- .../dynamic/sql/where/render/ColumnAndConditionRenderer.java | 2 +- .../org/mybatis/dynamic/sql/where/render/CriterionRenderer.java | 2 +- .../dynamic/sql/where/render/DefaultConditionVisitor.java | 2 +- .../dynamic/sql/where/render/DefaultWhereClauseProvider.java | 2 +- .../org/mybatis/dynamic/sql/where/render/RenderedCriterion.java | 2 +- .../mybatis/dynamic/sql/where/render/WhereClauseProvider.java | 2 +- .../org/mybatis/dynamic/sql/where/render/WhereRenderer.java | 2 +- .../dynamic/sql/util/kotlin/GroupingCriteriaCollector.kt | 2 +- .../kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt | 2 +- .../org/mybatis/dynamic/sql/util/kotlin/KInvalidSQLException.kt | 2 +- .../kotlin/org/mybatis/dynamic/sql/util/kotlin/KValidator.kt | 2 +- .../org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt | 2 +- .../mybatis/dynamic/sql/util/kotlin/KotlinBatchInsertBuilder.kt | 2 +- .../org/mybatis/dynamic/sql/util/kotlin/KotlinCountBuilder.kt | 2 +- .../org/mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt | 2 +- .../dynamic/sql/util/kotlin/KotlinGeneralInsertBuilder.kt | 2 +- .../org/mybatis/dynamic/sql/util/kotlin/KotlinInsertBuilder.kt | 2 +- .../dynamic/sql/util/kotlin/KotlinInsertColumnMapCompleters.kt | 2 +- .../dynamic/sql/util/kotlin/KotlinMultiRowInsertBuilder.kt | 2 +- .../mybatis/dynamic/sql/util/kotlin/KotlinMultiSelectBuilder.kt | 2 +- .../org/mybatis/dynamic/sql/util/kotlin/KotlinPagingDSL.kt | 2 +- .../org/mybatis/dynamic/sql/util/kotlin/KotlinSelectBuilder.kt | 2 +- .../mybatis/dynamic/sql/util/kotlin/KotlinSubQueryBuilders.kt | 2 +- .../org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilder.kt | 2 +- .../org/mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt | 2 +- .../org/mybatis/dynamic/sql/util/kotlin/elements/CaseDSLs.kt | 2 +- .../org/mybatis/dynamic/sql/util/kotlin/elements/CastDSL.kt | 2 +- .../dynamic/sql/util/kotlin/elements/ColumnExtensions.kt | 2 +- .../org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt | 2 +- .../dynamic/sql/util/kotlin/elements/SqlTableExtensions.kt | 2 +- .../dynamic/sql/util/kotlin/model/ModelBuilderFunctions.kt | 2 +- .../dynamic/sql/util/kotlin/mybatis3/MapperSupportFunctions.kt | 2 +- .../sql/util/kotlin/mybatis3/ProviderBuilderFunctions.kt | 2 +- .../util/kotlin/spring/NamedParameterJdbcTemplateExtensions.kt | 2 +- .../dynamic/sql/util/kotlin/spring/ProviderBuilderFunctions.kt | 2 +- .../resources/org/mybatis/dynamic/sql/util/messages.properties | 2 +- src/site/resources/css/site.css | 2 +- src/site/site.xml | 2 +- src/test/java/config/TestContainersConfiguration.java | 2 +- src/test/java/examples/animal/data/AnimalData.java | 2 +- .../java/examples/animal/data/AnimalDataDynamicSqlSupport.java | 2 +- src/test/java/examples/animal/data/AnimalDataMapper.java | 2 +- src/test/java/examples/animal/data/AnimalDataTest.java | 2 +- src/test/java/examples/animal/data/BindingTest.java | 2 +- src/test/java/examples/animal/data/CaseExpressionTest.java | 2 +- src/test/java/examples/animal/data/CommonSelectMapperTest.java | 2 +- src/test/java/examples/animal/data/FetchFirstTest.java | 2 +- src/test/java/examples/animal/data/Length.java | 2 +- src/test/java/examples/animal/data/LimitAndOffsetTest.java | 2 +- src/test/java/examples/animal/data/MyInCondition.java | 2 +- .../examples/animal/data/OptionalConditionsAnimalDataTest.java | 2 +- .../data/OptionalConditionsWithPredicatesAnimalDataTest.java | 2 +- src/test/java/examples/animal/data/SubQueryTest.java | 2 +- .../java/examples/animal/data/VariousListConditionsTest.java | 2 +- .../animal/data/VariousPagingAndLimitScenariosTest.java | 2 +- src/test/java/examples/array/ArrayTest.java | 2 +- src/test/java/examples/array/NamesRecord.java | 2 +- src/test/java/examples/array/NamesTableDynamicSqlSupport.java | 2 +- src/test/java/examples/array/NamesTableMapper.java | 2 +- src/test/java/examples/array/StringArrayTypeHandler.java | 2 +- .../column/comparison/ColumnComparisonConfiguration.java | 2 +- .../column/comparison/ColumnComparisonDynamicSqlSupport.java | 2 +- .../java/examples/column/comparison/ColumnComparisonMapper.java | 2 +- .../java/examples/column/comparison/ColumnComparisonRecord.java | 2 +- .../java/examples/column/comparison/ColumnComparisonTest.java | 2 +- src/test/java/examples/complexquery/ComplexQueryTest.java | 2 +- src/test/java/examples/complexquery/GroupingTest.java | 2 +- .../java/examples/complexquery/PersonDynamicSqlSupport.java | 2 +- src/test/java/examples/complexquery/SearchUtils.java | 2 +- src/test/java/examples/custom_render/CustomRenderingTest.java | 2 +- src/test/java/examples/custom_render/JsonRenderingStrategy.java | 2 +- .../java/examples/custom_render/JsonTestDynamicSqlSupport.java | 2 +- src/test/java/examples/custom_render/JsonTestMapper.java | 2 +- src/test/java/examples/custom_render/JsonTestRecord.java | 2 +- src/test/java/examples/emptywhere/EmptyWhereTest.java | 2 +- src/test/java/examples/emptywhere/OrderDynamicSqlSupport.java | 2 +- src/test/java/examples/emptywhere/PersonDynamicSqlSupport.java | 2 +- .../java/examples/generated/always/GeneratedAlwaysRecord.java | 2 +- src/test/java/examples/generated/always/PersonRecord.java | 2 +- .../always/mybatis/GeneratedAlwaysDynamicSqlSupport.java | 2 +- .../generated/always/mybatis/GeneratedAlwaysMapper.java | 2 +- .../generated/always/mybatis/GeneratedAlwaysMapperTest.java | 2 +- .../java/examples/generated/always/mybatis/GeneratedKey.java | 2 +- .../examples/generated/always/mybatis/GeneratedKeyList.java | 2 +- .../generated/always/mybatis/PersonDynamicSqlSupport.java | 2 +- .../java/examples/generated/always/mybatis/PersonMapper.java | 2 +- .../examples/generated/always/mybatis/PersonMapperTest.java | 2 +- .../always/spring/GeneratedAlwaysDynamicSqlSupport.java | 2 +- src/test/java/examples/generated/always/spring/SpringTest.java | 2 +- src/test/java/examples/groupby/AddressDynamicSqlSupport.java | 2 +- src/test/java/examples/groupby/GroupByTest.java | 2 +- src/test/java/examples/groupby/Person2DynamicSqlSupport.java | 2 +- src/test/java/examples/groupby/PersonDynamicSqlSupport.java | 2 +- src/test/java/examples/joins/ExistsTest.java | 2 +- src/test/java/examples/joins/ItemMasterDynamicSQLSupport.java | 2 +- src/test/java/examples/joins/JoinMapper.java | 2 +- src/test/java/examples/joins/JoinMapperTest.java | 2 +- src/test/java/examples/joins/JoinSubQueryTest.java | 2 +- src/test/java/examples/joins/OrderDetail.java | 2 +- src/test/java/examples/joins/OrderDetailDynamicSQLSupport.java | 2 +- src/test/java/examples/joins/OrderLineDynamicSQLSupport.java | 2 +- src/test/java/examples/joins/OrderMaster.java | 2 +- src/test/java/examples/joins/OrderMasterDynamicSQLSupport.java | 2 +- src/test/java/examples/joins/User.java | 2 +- src/test/java/examples/joins/UserDynamicSQLSupport.java | 2 +- src/test/java/examples/mariadb/ItemsDynamicSQLSupport.java | 2 +- src/test/java/examples/mariadb/MariaDBTest.java | 2 +- src/test/java/examples/mariadb/NumbersDynamicSQLSupport.java | 2 +- src/test/java/examples/mariadb/OrderByCaseTest.java | 2 +- src/test/java/examples/paging/LimitAndOffsetAdapter.java | 2 +- src/test/java/examples/paging/LimitAndOffsetMapper.java | 2 +- src/test/java/examples/paging/LimitAndOffsetTest.java | 2 +- src/test/java/examples/sharding/ShardedMapper.java | 2 +- src/test/java/examples/sharding/ShardingTest.java | 2 +- .../java/examples/sharding/TableCodesDynamicSqlSupport.java | 2 +- src/test/java/examples/simple/AddressDynamicSqlSupport.java | 2 +- src/test/java/examples/simple/AddressMapper.java | 2 +- src/test/java/examples/simple/AddressRecord.java | 2 +- src/test/java/examples/simple/CompoundKeyDynamicSqlSupport.java | 2 +- src/test/java/examples/simple/CompoundKeyMapper.java | 2 +- src/test/java/examples/simple/CompoundKeyRow.java | 2 +- src/test/java/examples/simple/LastName.java | 2 +- src/test/java/examples/simple/LastNameTypeHandler.java | 2 +- src/test/java/examples/simple/MyBatisMapToRowTest.java | 2 +- src/test/java/examples/simple/PersonDynamicSqlSupport.java | 2 +- src/test/java/examples/simple/PersonMapper.java | 2 +- src/test/java/examples/simple/PersonMapperTest.java | 2 +- src/test/java/examples/simple/PersonRecord.java | 2 +- src/test/java/examples/simple/PersonWithAddress.java | 2 +- src/test/java/examples/simple/PersonWithAddressMapper.java | 2 +- src/test/java/examples/simple/ReusableWhereTest.java | 2 +- src/test/java/examples/simple/YesNoTypeHandler.java | 2 +- src/test/java/examples/spring/AddressDynamicSqlSupport.java | 2 +- src/test/java/examples/spring/AddressRecord.java | 2 +- src/test/java/examples/spring/CompoundKeyDynamicSqlSupport.java | 2 +- src/test/java/examples/spring/CompoundKeyRow.java | 2 +- src/test/java/examples/spring/LastName.java | 2 +- src/test/java/examples/spring/LastNameParameterConverter.java | 2 +- src/test/java/examples/spring/PersonDynamicSqlSupport.java | 2 +- src/test/java/examples/spring/PersonRecord.java | 2 +- src/test/java/examples/spring/PersonTemplateTest.java | 2 +- src/test/java/examples/spring/PersonWithAddress.java | 2 +- src/test/java/examples/spring/ReusableWhereTest.java | 2 +- src/test/java/examples/spring/SpringConfiguration.java | 2 +- src/test/java/examples/spring/SpringMapToRowTest.java | 2 +- src/test/java/examples/spring/YesNoParameterConverter.java | 2 +- .../java/examples/springbatch/SpringBatchRenderingTest.java | 2 +- .../springbatch/bulkinsert/BulkInsertConfiguration.java | 2 +- .../springbatch/bulkinsert/SpringBatchBulkInsertTest.java | 2 +- .../examples/springbatch/bulkinsert/TestRecordGenerator.java | 2 +- src/test/java/examples/springbatch/common/PersonProcessor.java | 2 +- src/test/java/examples/springbatch/common/PersonRecord.java | 2 +- .../examples/springbatch/common/UpdateStatementConvertor.java | 2 +- .../springbatch/cursor/CursorReaderBatchConfiguration.java | 2 +- .../java/examples/springbatch/cursor/SpringBatchCursorTest.java | 2 +- .../examples/springbatch/mapper/PersonDynamicSqlSupport.java | 2 +- src/test/java/examples/springbatch/mapper/PersonMapper.java | 2 +- .../springbatch/paging/PagingReaderBatchConfiguration.java | 2 +- .../java/examples/springbatch/paging/SpringBatchPagingTest.java | 2 +- .../java/examples/type_conversion/MyFilesDynamicSqlSupport.java | 2 +- src/test/java/examples/type_conversion/MyFilesMapper.java | 2 +- src/test/java/examples/type_conversion/ToBase64.java | 2 +- src/test/java/examples/type_conversion/TypeConversionTest.java | 2 +- src/test/java/issues/gh100/FromGroupByTest.java | 2 +- src/test/java/issues/gh100/FromJoinWhereTest.java | 2 +- src/test/java/issues/gh100/Issue100StartAfterJoinTest.java | 2 +- src/test/java/issues/gh100/Issue100Test.java | 2 +- src/test/java/issues/gh100/StudentDynamicSqlSupport.java | 2 +- src/test/java/issues/gh100/StudentRegDynamicSqlSupport.java | 2 +- src/test/java/issues/gh105/Issue105Test.java | 2 +- src/test/java/issues/gh105/PersonDynamicSqlSupport.java | 2 +- src/test/java/issues/gh105/SearchUtils.java | 2 +- src/test/java/issues/gh324/Issue324Test.java | 2 +- src/test/java/issues/gh324/NameRecord.java | 2 +- src/test/java/issues/gh324/NameService.java | 2 +- src/test/java/issues/gh324/NameTableDynamicSqlSupport.java | 2 +- src/test/java/issues/gh324/NameTableMapper.java | 2 +- src/test/java/issues/gh324/ObservableCache.java | 2 +- src/test/java/issues/gh324/TestUtils.java | 2 +- src/test/java/issues/gh324/spring/SpringNameService.java | 2 +- src/test/java/issues/gh324/spring/SpringTransactionTest.java | 2 +- src/test/java/issues/gh324/spring/TestConfiguration.java | 2 +- src/test/java/issues/gh430/NoInitialConditionTest.java | 2 +- src/test/java/issues/gh655/Gh655Test.java | 2 +- src/test/java/issues/lhg142/Issue142Test.java | 2 +- src/test/java/issues/lhg142/MyMarkDynamicSqlSupport.java | 2 +- src/test/java/issues/lhg142/Page.java | 2 +- src/test/java/org/mybatis/dynamic/sql/BindableColumnTest.java | 2 +- src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java | 2 +- .../org/mybatis/dynamic/sql/StatementConfigurationTest.java | 2 +- .../dynamic/sql/configuration/GlobalConfigurationTest.java | 2 +- .../org/mybatis/dynamic/sql/delete/DeleteStatementTest.java | 2 +- .../mybatis/dynamic/sql/insert/GeneralInsertStatementTest.java | 2 +- .../org/mybatis/dynamic/sql/insert/InsertStatementTest.java | 2 +- src/test/java/org/mybatis/dynamic/sql/insert/MapToRowTest.java | 2 +- .../dynamic/sql/insert/render/FieldAndValueCollectorTest.java | 2 +- .../org/mybatis/dynamic/sql/mybatis3/CriterionRendererTest.java | 2 +- .../org/mybatis/dynamic/sql/mybatis3/InsertStatementTest.java | 2 +- .../org/mybatis/dynamic/sql/mybatis3/SelectStatementTest.java | 2 +- .../org/mybatis/dynamic/sql/mybatis3/UpdateStatementTest.java | 2 +- .../java/org/mybatis/dynamic/sql/select/HavingModelTest.java | 2 +- .../org/mybatis/dynamic/sql/select/SelectStatementTest.java | 2 +- .../org/mybatis/dynamic/sql/subselect/FooDynamicSqlSupport.java | 2 +- .../java/org/mybatis/dynamic/sql/subselect/SubSelectTest.java | 2 +- .../org/mybatis/dynamic/sql/update/UpdateStatementTest.java | 2 +- .../org/mybatis/dynamic/sql/util/ColumnMappingVisitorTest.java | 2 +- .../org/mybatis/dynamic/sql/util/FragmentCollectorTest.java | 2 +- .../org/mybatis/dynamic/sql/util/SqlProviderAdapterTest.java | 2 +- .../java/org/mybatis/dynamic/sql/util/StringUtilitiesTest.java | 2 +- src/test/java/org/mybatis/dynamic/sql/util/UtilitiesTest.java | 2 +- src/test/java/org/mybatis/dynamic/sql/where/WhereModelTest.java | 2 +- .../mybatis/dynamic/sql/where/condition/FilterAndMapTest.java | 2 +- .../org/mybatis/dynamic/sql/where/condition/SupplierTest.java | 2 +- .../mybatis/dynamic/sql/where/render/CriterionRendererTest.java | 2 +- .../dynamic/sql/where/render/OptionalCriterionRenderTest.java | 2 +- .../mybatis/dynamic/sql/where/render/RenderedCriterionTest.java | 2 +- .../examples/kotlin/animal/data/AnimalDataDynamicSqlSupport.kt | 2 +- .../kotlin/examples/kotlin/animal/data/KCaseExpressionTest.kt | 2 +- src/test/kotlin/examples/kotlin/mybatis3/TestUtils.kt | 2 +- .../kotlin/mybatis3/canonical/AddressDynamicSqlSupport.kt | 2 +- .../kotlin/examples/kotlin/mybatis3/canonical/AddressMapper.kt | 2 +- .../kotlin/examples/kotlin/mybatis3/canonical/AddressRecord.kt | 2 +- .../mybatis3/canonical/GeneratedAlwaysDynamicSqlSupport.kt | 2 +- .../examples/kotlin/mybatis3/canonical/GeneratedAlwaysMapper.kt | 2 +- .../examples/kotlin/mybatis3/canonical/GeneratedAlwaysRecord.kt | 2 +- .../examples/kotlin/mybatis3/canonical/GeneratedAlwaysTest.kt | 2 +- src/test/kotlin/examples/kotlin/mybatis3/canonical/LastName.kt | 2 +- .../examples/kotlin/mybatis3/canonical/LastNameTypeHandler.kt | 2 +- .../kotlin/mybatis3/canonical/PersonDynamicSqlSupport.kt | 2 +- .../kotlin/examples/kotlin/mybatis3/canonical/PersonMapper.kt | 2 +- .../kotlin/mybatis3/canonical/PersonMapperExtensions.kt | 2 +- .../examples/kotlin/mybatis3/canonical/PersonMapperTest.kt | 2 +- .../kotlin/examples/kotlin/mybatis3/canonical/PersonRecord.kt | 2 +- .../examples/kotlin/mybatis3/canonical/PersonWithAddress.kt | 2 +- .../kotlin/mybatis3/canonical/PersonWithAddressMapper.kt | 2 +- .../mybatis3/canonical/PersonWithAddressMapperExtensions.kt | 2 +- .../examples/kotlin/mybatis3/canonical/ReusableWhereTest.kt | 2 +- .../examples/kotlin/mybatis3/canonical/YesNoTypeHandler.kt | 2 +- .../mybatis3/column/comparison/ColumnComparisonConfiguration.kt | 2 +- .../column/comparison/ColumnComparisonDynamicSqlSupport.kt | 2 +- .../kotlin/mybatis3/column/comparison/ColumnComparisonMapper.kt | 2 +- .../kotlin/mybatis3/column/comparison/ColumnComparisonRecord.kt | 2 +- .../kotlin/mybatis3/column/comparison/ColumnComparisonTest.kt | 2 +- .../kotlin/mybatis3/custom/render/KCustomRenderingTest.kt | 2 +- .../kotlin/mybatis3/custom/render/KJsonRenderingStrategy.kt | 2 +- .../kotlin/mybatis3/custom/render/KJsonTestDynamicSqlSupport.kt | 2 +- .../examples/kotlin/mybatis3/custom/render/KJsonTestMapper.kt | 2 +- .../examples/kotlin/mybatis3/custom/render/KJsonTestRecord.kt | 2 +- .../examples/kotlin/mybatis3/general/GeneralKotlinTest.kt | 2 +- .../kotlin/examples/kotlin/mybatis3/general/KGroupingTest.kt | 2 +- .../examples/kotlin/mybatis3/joins/DeprecatedJoinMapperTest.kt | 2 +- src/test/kotlin/examples/kotlin/mybatis3/joins/Domain.kt | 2 +- src/test/kotlin/examples/kotlin/mybatis3/joins/ExistsTest.kt | 2 +- .../kotlin/mybatis3/joins/ItemMasterDynamicSQLSupport.kt | 2 +- src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapper.kt | 2 +- .../examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt | 2 +- .../kotlin/mybatis3/joins/OrderDetailDynamicSQLSupport.kt | 2 +- .../kotlin/mybatis3/joins/OrderLineDynamicSQLSupport.kt | 2 +- .../kotlin/mybatis3/joins/OrderMasterDynamicSQLSupport.kt | 2 +- .../examples/kotlin/mybatis3/joins/UserDynamicSQLSupport.kt | 2 +- .../examples/kotlin/mybatis3/mariadb/KItemsDynamicSQLSupport.kt | 2 +- .../kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt | 2 +- .../kotlin/examples/kotlin/mybatis3/sharding/KShardedMapper.kt | 2 +- .../kotlin/examples/kotlin/mybatis3/sharding/KShardingTest.kt | 2 +- .../mybatis3/sharding/KTableCodesTableDynamicSQLSupport.kt | 2 +- .../kotlin/spring/canonical/AddressDynamicSqlSupport.kt | 2 +- .../spring/canonical/CanonicalSpringKotlinTemplateDirectTest.kt | 2 +- .../kotlin/spring/canonical/CanonicalSpringKotlinTest.kt | 2 +- .../kotlin/spring/canonical/CompoundKeyDynamicSqlSupport.kt | 2 +- .../examples/kotlin/spring/canonical/DomainAndConverters.kt | 2 +- .../kotlin/spring/canonical/GeneratedAlwaysDynamicSqlSupport.kt | 2 +- .../examples/kotlin/spring/canonical/InfixElementsTest.kt | 2 +- .../examples/kotlin/spring/canonical/InfixSubQueriesTest.kt | 2 +- .../examples/kotlin/spring/canonical/KotlinElementsTest.kt | 2 +- .../examples/kotlin/spring/canonical/PersonDynamicSqlSupport.kt | 2 +- src/test/kotlin/examples/kotlin/spring/canonical/RowMappers.kt | 2 +- .../examples/kotlin/spring/canonical/SpringConfiguration.kt | 2 +- .../kotlin/spring/canonical/SpringKotlinMapToRowTest.kt | 2 +- .../kotlin/spring/canonical/SpringKotlinSubQueryTest.kt | 2 +- src/test/kotlin/issues/kotlin/gh430/KNoInitialConditionsTest.kt | 2 +- src/test/kotlin/nullability/test/BetweenTest.kt | 2 +- src/test/kotlin/nullability/test/BetweenWhenPresentTest.kt | 2 +- src/test/kotlin/nullability/test/ComparisonTest.kt | 2 +- src/test/kotlin/nullability/test/CompilerUtilities.kt | 2 +- src/test/kotlin/nullability/test/EqualNotEqualTest.kt | 2 +- src/test/kotlin/nullability/test/InTest.kt | 2 +- src/test/kotlin/nullability/test/InWhenPresentTest.kt | 2 +- src/test/kotlin/nullability/test/LikeNotLikeTest.kt | 2 +- src/test/kotlin/nullability/test/NotBetweenTest.kt | 2 +- src/test/kotlin/nullability/test/NotBetweenWhenPresentTest.kt | 2 +- src/test/kotlin/nullability/test/NotInTest.kt | 2 +- src/test/kotlin/nullability/test/NotInWhenPresentTest.kt | 2 +- .../mybatis/dynamic/sql/util/kotlin/model/ModelBuilderTest.kt | 2 +- src/test/resources/defaultTrue.properties | 2 +- src/test/resources/empty.properties | 2 +- src/test/resources/examples/animal/data/CreateAnimalData.sql | 2 +- src/test/resources/examples/array/CreateDB.sql | 2 +- src/test/resources/examples/column/comparison/CreateDB.sql | 2 +- src/test/resources/examples/custom_render/dbInit.sql | 2 +- .../examples/generated/always/CreateGeneratedAlwaysDB.sql | 2 +- src/test/resources/examples/groupby/CreateGroupByDB.sql | 2 +- src/test/resources/examples/joins/CreateJoinDB.sql | 2 +- src/test/resources/examples/joins/JoinMapper.xml | 2 +- src/test/resources/examples/kotlin/mybatis3/CreateSimpleDB.sql | 2 +- .../resources/examples/kotlin/mybatis3/joins/CreateJoinDB.sql | 2 +- .../resources/examples/kotlin/mybatis3/joins/JoinMapper.xml | 2 +- .../examples/kotlin/spring/CreateGeneratedAlwaysDB.sql | 2 +- src/test/resources/examples/kotlin/spring/CreateSimpleDB.sql | 2 +- src/test/resources/examples/mariadb/CreateDB.sql | 2 +- src/test/resources/examples/schema_supplier/CreateDB.sql | 2 +- src/test/resources/examples/sharding/ShardingDB.sql | 2 +- src/test/resources/examples/simple/CreateSimpleDB.sql | 2 +- src/test/resources/examples/springbatch/data.sql | 2 +- src/test/resources/examples/springbatch/schema.sql | 2 +- src/test/resources/examples/type_conversion/CreateDB.sql | 2 +- src/test/resources/issues/gh324/CreateDB.sql | 2 +- src/test/resources/logback.xml | 2 +- src/test/resources/mybatis-dynamic-sql.properties | 2 +- 578 files changed, 578 insertions(+), 578 deletions(-) diff --git a/.mvn/extensions.xml b/.mvn/extensions.xml index 2f7f4c3a1..93acda146 100644 --- a/.mvn/extensions.xml +++ b/.mvn/extensions.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright 2016-2024 the original author or authors. + Copyright 2016-2025 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/.mvn/settings.xml b/.mvn/settings.xml index 9987bedc4..af6e63413 100644 --- a/.mvn/settings.xml +++ b/.mvn/settings.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright 2016-2024 the original author or authors. + Copyright 2016-2025 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/checkstyle-override.xml b/checkstyle-override.xml index 1e54f5578..17355d976 100644 --- a/checkstyle-override.xml +++ b/checkstyle-override.xml @@ -1,7 +1,7 @@ <?xml version="1.0"?> <!-- - Copyright 2016-2024 the original author or authors. + Copyright 2016-2025 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/pom.xml b/pom.xml index e57313231..e4e68292a 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright 2016-2024 the original author or authors. + Copyright 2016-2025 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/AbstractColumnComparisonCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractColumnComparisonCondition.java index 4e419d968..ff6923ecb 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractColumnComparisonCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractColumnComparisonCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/AbstractListValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java index dc287e842..21230c821 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/AbstractNoValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java index d6b1c384b..a60f2a843 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/AbstractSingleValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java index 1e70adb31..13d4dc8e1 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/AbstractSubselectCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractSubselectCondition.java index f17e29066..4408f279c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractSubselectCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractSubselectCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/AbstractTwoValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java index ee8b3c577..c36fe186d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/AliasableSqlTable.java b/src/main/java/org/mybatis/dynamic/sql/AliasableSqlTable.java index 7474b00ba..fb0c065bf 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AliasableSqlTable.java +++ b/src/main/java/org/mybatis/dynamic/sql/AliasableSqlTable.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/AndOrCriteriaGroup.java b/src/main/java/org/mybatis/dynamic/sql/AndOrCriteriaGroup.java index a85861904..45ef362f7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AndOrCriteriaGroup.java +++ b/src/main/java/org/mybatis/dynamic/sql/AndOrCriteriaGroup.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/BasicColumn.java b/src/main/java/org/mybatis/dynamic/sql/BasicColumn.java index a583ba4ff..2573b4529 100644 --- a/src/main/java/org/mybatis/dynamic/sql/BasicColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/BasicColumn.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/BindableColumn.java b/src/main/java/org/mybatis/dynamic/sql/BindableColumn.java index 77e6e5bc1..88d146b2c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/BindableColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/BindableColumn.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/BoundValue.java b/src/main/java/org/mybatis/dynamic/sql/BoundValue.java index 7ac0bd26a..5151a5dad 100644 --- a/src/main/java/org/mybatis/dynamic/sql/BoundValue.java +++ b/src/main/java/org/mybatis/dynamic/sql/BoundValue.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/ColumnAndConditionCriterion.java b/src/main/java/org/mybatis/dynamic/sql/ColumnAndConditionCriterion.java index 9c0f47151..ca8fc8f3c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/ColumnAndConditionCriterion.java +++ b/src/main/java/org/mybatis/dynamic/sql/ColumnAndConditionCriterion.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/ConditionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/ConditionVisitor.java index c8e95a9bd..99a4fd36c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/ConditionVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/ConditionVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/Constant.java b/src/main/java/org/mybatis/dynamic/sql/Constant.java index d424f6391..0f5f2cff5 100644 --- a/src/main/java/org/mybatis/dynamic/sql/Constant.java +++ b/src/main/java/org/mybatis/dynamic/sql/Constant.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/CriteriaGroup.java b/src/main/java/org/mybatis/dynamic/sql/CriteriaGroup.java index 931b55722..b82ac296c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/CriteriaGroup.java +++ b/src/main/java/org/mybatis/dynamic/sql/CriteriaGroup.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/DerivedColumn.java b/src/main/java/org/mybatis/dynamic/sql/DerivedColumn.java index 73ca62526..93294efc2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/DerivedColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/DerivedColumn.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/ExistsCriterion.java b/src/main/java/org/mybatis/dynamic/sql/ExistsCriterion.java index 711b85ffd..b91b20036 100644 --- a/src/main/java/org/mybatis/dynamic/sql/ExistsCriterion.java +++ b/src/main/java/org/mybatis/dynamic/sql/ExistsCriterion.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/ExistsPredicate.java b/src/main/java/org/mybatis/dynamic/sql/ExistsPredicate.java index 8d68a3ac9..139d7e379 100644 --- a/src/main/java/org/mybatis/dynamic/sql/ExistsPredicate.java +++ b/src/main/java/org/mybatis/dynamic/sql/ExistsPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/NotCriterion.java b/src/main/java/org/mybatis/dynamic/sql/NotCriterion.java index cd9f5e980..f0a0010f8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/NotCriterion.java +++ b/src/main/java/org/mybatis/dynamic/sql/NotCriterion.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/ParameterTypeConverter.java b/src/main/java/org/mybatis/dynamic/sql/ParameterTypeConverter.java index 7df7572b1..3b053b154 100644 --- a/src/main/java/org/mybatis/dynamic/sql/ParameterTypeConverter.java +++ b/src/main/java/org/mybatis/dynamic/sql/ParameterTypeConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/SortSpecification.java b/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java index 0fd0da18f..13cfdee55 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java +++ b/src/main/java/org/mybatis/dynamic/sql/SortSpecification.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/SqlBuilder.java b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java index 2cf6ac277..f118136e6 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/SqlColumn.java b/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java index 0c8475d33..01eb235a3 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/SqlCriterion.java b/src/main/java/org/mybatis/dynamic/sql/SqlCriterion.java index ee3ddf414..2989f3125 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlCriterion.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlCriterion.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/SqlCriterionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/SqlCriterionVisitor.java index d6ef389ec..8431568b1 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlCriterionVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlCriterionVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/SqlTable.java b/src/main/java/org/mybatis/dynamic/sql/SqlTable.java index 40b6ccf17..ac3665532 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-2024 the original author or authors. + * Copyright 2016-2025 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/StringConstant.java b/src/main/java/org/mybatis/dynamic/sql/StringConstant.java index bced8b446..0187bb1fa 100644 --- a/src/main/java/org/mybatis/dynamic/sql/StringConstant.java +++ b/src/main/java/org/mybatis/dynamic/sql/StringConstant.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/TableExpression.java b/src/main/java/org/mybatis/dynamic/sql/TableExpression.java index 06699f93f..75ee1e8d4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/TableExpression.java +++ b/src/main/java/org/mybatis/dynamic/sql/TableExpression.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/TableExpressionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/TableExpressionVisitor.java index bf232f325..407d7ebbb 100644 --- a/src/main/java/org/mybatis/dynamic/sql/TableExpressionVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/TableExpressionVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/VisitableCondition.java b/src/main/java/org/mybatis/dynamic/sql/VisitableCondition.java index f13076bfe..fc974b932 100644 --- a/src/main/java/org/mybatis/dynamic/sql/VisitableCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/VisitableCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/common/AbstractBooleanExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionDSL.java index 40f9cc0f7..d2acdde2e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/common/AbstractBooleanExpressionModel.java b/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionModel.java index 0913fe17c..0112c4555 100644 --- a/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/common/AbstractBooleanExpressionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionRenderer.java index 910e20bd3..8ba9d7dce 100644 --- a/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/common/CommonBuilder.java b/src/main/java/org/mybatis/dynamic/sql/common/CommonBuilder.java index f25457398..b8a9a9a52 100644 --- a/src/main/java/org/mybatis/dynamic/sql/common/CommonBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/common/CommonBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/common/OrderByModel.java b/src/main/java/org/mybatis/dynamic/sql/common/OrderByModel.java index 3a05f49d9..42d2de4fb 100644 --- a/src/main/java/org/mybatis/dynamic/sql/common/OrderByModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/common/OrderByModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/common/OrderByRenderer.java b/src/main/java/org/mybatis/dynamic/sql/common/OrderByRenderer.java index 206c1a297..851bf73ea 100644 --- a/src/main/java/org/mybatis/dynamic/sql/common/OrderByRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/common/OrderByRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/configuration/GlobalConfiguration.java b/src/main/java/org/mybatis/dynamic/sql/configuration/GlobalConfiguration.java index 8e7054d78..8e7fd2eba 100644 --- a/src/main/java/org/mybatis/dynamic/sql/configuration/GlobalConfiguration.java +++ b/src/main/java/org/mybatis/dynamic/sql/configuration/GlobalConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/configuration/GlobalContext.java b/src/main/java/org/mybatis/dynamic/sql/configuration/GlobalContext.java index 0cdc5d902..6963374b6 100644 --- a/src/main/java/org/mybatis/dynamic/sql/configuration/GlobalContext.java +++ b/src/main/java/org/mybatis/dynamic/sql/configuration/GlobalContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/configuration/StatementConfiguration.java b/src/main/java/org/mybatis/dynamic/sql/configuration/StatementConfiguration.java index bb5641f3f..ed187fe92 100644 --- a/src/main/java/org/mybatis/dynamic/sql/configuration/StatementConfiguration.java +++ b/src/main/java/org/mybatis/dynamic/sql/configuration/StatementConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/delete/DeleteDSL.java b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java index a0423de08..2ea176c53 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/delete/DeleteDSLCompleter.java b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSLCompleter.java index 799ea7e5e..b1aeee392 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSLCompleter.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSLCompleter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/delete/DeleteModel.java b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java index 4519b1002..d8f4d0e07 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/delete/render/DefaultDeleteStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/delete/render/DefaultDeleteStatementProvider.java index ef2ade7f0..31ffc53f0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/render/DefaultDeleteStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/render/DefaultDeleteStatementProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/delete/render/DeleteRenderer.java b/src/main/java/org/mybatis/dynamic/sql/delete/render/DeleteRenderer.java index 7b3dbfc97..4671e4d79 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 @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/delete/render/DeleteStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/delete/render/DeleteStatementProvider.java index 9ccf16c98..743c84e2d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/render/DeleteStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/render/DeleteStatementProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/exception/DuplicateTableAliasException.java b/src/main/java/org/mybatis/dynamic/sql/exception/DuplicateTableAliasException.java index 89ad51fdb..21d43a927 100644 --- a/src/main/java/org/mybatis/dynamic/sql/exception/DuplicateTableAliasException.java +++ b/src/main/java/org/mybatis/dynamic/sql/exception/DuplicateTableAliasException.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/exception/DynamicSqlException.java b/src/main/java/org/mybatis/dynamic/sql/exception/DynamicSqlException.java index df7d61ce0..f1836b990 100644 --- a/src/main/java/org/mybatis/dynamic/sql/exception/DynamicSqlException.java +++ b/src/main/java/org/mybatis/dynamic/sql/exception/DynamicSqlException.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/exception/InvalidSqlException.java b/src/main/java/org/mybatis/dynamic/sql/exception/InvalidSqlException.java index ee1a13a9d..44d407ea1 100644 --- a/src/main/java/org/mybatis/dynamic/sql/exception/InvalidSqlException.java +++ b/src/main/java/org/mybatis/dynamic/sql/exception/InvalidSqlException.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/exception/NonRenderingWhereClauseException.java b/src/main/java/org/mybatis/dynamic/sql/exception/NonRenderingWhereClauseException.java index bcdcbf9a0..0561f2d42 100644 --- a/src/main/java/org/mybatis/dynamic/sql/exception/NonRenderingWhereClauseException.java +++ b/src/main/java/org/mybatis/dynamic/sql/exception/NonRenderingWhereClauseException.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/AbstractMultiRowInsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/AbstractMultiRowInsertModel.java index 01056f60f..b4bdb7eab 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/AbstractMultiRowInsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/AbstractMultiRowInsertModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/BatchInsertDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java index ba912e5a6..8c8344929 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/BatchInsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java index b591753a2..4e85d5951 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/GeneralInsertDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertDSL.java index f36fd6544..18e05a1d1 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/GeneralInsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java index 1fe845090..4a9de2270 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/InsertColumnListModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/InsertColumnListModel.java index 818868573..c1c0669c9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/InsertColumnListModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/InsertColumnListModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/InsertDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/InsertDSL.java index 73ac1e71a..e2fbb49b5 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/InsertDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/InsertDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/InsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/InsertModel.java index 7f740051e..a0d451358 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/InsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/InsertModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/InsertSelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectDSL.java index 20fad06ad..5e071d169 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/InsertSelectModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java index 3d9580942..25d01b7de 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/MultiRowInsertDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java index 7c0530a2a..b29684a4f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/MultiRowInsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertModel.java index 406c02b7a..3b380ca66 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/BatchInsert.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsert.java index 5a3c22893..5272a0ba0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsert.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsert.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/BatchInsertRenderer.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsertRenderer.java index 5242b459b..48d5f5eea 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 @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/DefaultGeneralInsertStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultGeneralInsertStatementProvider.java index 5cd4144d6..94b3eac7a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultGeneralInsertStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultGeneralInsertStatementProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/DefaultInsertStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultInsertStatementProvider.java index d75e90e27..d45f9f956 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultInsertStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultInsertStatementProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/DefaultMultiRowInsertStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultMultiRowInsertStatementProvider.java index 2bb031e60..f1395ecd9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultMultiRowInsertStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultMultiRowInsertStatementProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/FieldAndValueAndParameters.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueAndParameters.java index 5c13aa9f6..1ec27d5a5 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueAndParameters.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueAndParameters.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/FieldAndValueCollector.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueCollector.java index c6692b2c8..7af466766 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueCollector.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueCollector.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/GeneralInsertRenderer.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertRenderer.java index de91037a6..8dfe89d4e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/GeneralInsertStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertStatementProvider.java index a3534059a..394a88ac2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertStatementProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/GeneralInsertValuePhraseVisitor.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertValuePhraseVisitor.java index 7a7bcf25c..30897e86f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertValuePhraseVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertValuePhraseVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/InsertRenderer.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertRenderer.java index 443695c50..f3f67c062 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 @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/InsertRenderingUtilities.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertRenderingUtilities.java index e22143109..de529a2b4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertRenderingUtilities.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertRenderingUtilities.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/InsertSelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertSelectRenderer.java index cd052f45d..909f1c418 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 @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/InsertSelectStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertSelectStatementProvider.java index bb25ab835..5545da79a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertSelectStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertSelectStatementProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/InsertStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertStatementProvider.java index ea0d0db18..f68fb1db3 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertStatementProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/MultiRowInsertRenderer.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowInsertRenderer.java index 10479ec4b..21da95cca 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowInsertRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowInsertRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/MultiRowInsertStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowInsertStatementProvider.java index 6b520d617..de5d87797 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowInsertStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowInsertStatementProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/MultiRowValuePhraseVisitor.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowValuePhraseVisitor.java index 9a9bbc3ce..639248c3e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowValuePhraseVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowValuePhraseVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/insert/render/ValuePhraseVisitor.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/ValuePhraseVisitor.java index f11909c10..dccf0f14a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/ValuePhraseVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/ValuePhraseVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/ExplicitTableAliasCalculator.java b/src/main/java/org/mybatis/dynamic/sql/render/ExplicitTableAliasCalculator.java index 70c5287c7..1cb388f85 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/ExplicitTableAliasCalculator.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/ExplicitTableAliasCalculator.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/GuaranteedTableAliasCalculator.java b/src/main/java/org/mybatis/dynamic/sql/render/GuaranteedTableAliasCalculator.java index 4d4a3b883..80e4bfbb3 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-2024 the original author or authors. + * Copyright 2016-2025 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/render/MyBatis3RenderingStrategy.java b/src/main/java/org/mybatis/dynamic/sql/render/MyBatis3RenderingStrategy.java index d104b1186..1d5563c2a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/MyBatis3RenderingStrategy.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/MyBatis3RenderingStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/RenderedParameterInfo.java b/src/main/java/org/mybatis/dynamic/sql/render/RenderedParameterInfo.java index 909f36c3c..c1be974f5 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RenderedParameterInfo.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RenderedParameterInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/RenderingContext.java b/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java index 553ecd090..5b31d0654 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/RenderingStrategies.java b/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategies.java index 4b7837a46..d3c17af78 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategies.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategies.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/RenderingStrategy.java b/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java index 6beb7bc24..adf66115c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RenderingStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/SpringNamedParameterRenderingStrategy.java b/src/main/java/org/mybatis/dynamic/sql/render/SpringNamedParameterRenderingStrategy.java index e11ead4e2..ccdbae51f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/SpringNamedParameterRenderingStrategy.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/SpringNamedParameterRenderingStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/TableAliasCalculator.java b/src/main/java/org/mybatis/dynamic/sql/render/TableAliasCalculator.java index faf7fc9a4..a90d337f2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/TableAliasCalculator.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/TableAliasCalculator.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/TableAliasCalculatorWithParent.java b/src/main/java/org/mybatis/dynamic/sql/render/TableAliasCalculatorWithParent.java index 3aa75e98b..73d102d76 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/TableAliasCalculatorWithParent.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/TableAliasCalculatorWithParent.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/AbstractHavingFinisher.java b/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingFinisher.java index 2a668c72c..bcf21b23a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingFinisher.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingFinisher.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/AbstractHavingStarter.java b/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingStarter.java index 4eccfc2f6..264e8046e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingStarter.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingStarter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/AbstractQueryExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/AbstractQueryExpressionDSL.java index a1a44d2ab..bee032a30 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/AbstractQueryExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/AbstractQueryExpressionDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/AbstractSelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/AbstractSelectModel.java index 8fc3fb898..d19f45c55 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/AbstractSelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/AbstractSelectModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/ColumnSortSpecification.java b/src/main/java/org/mybatis/dynamic/sql/select/ColumnSortSpecification.java index 4420affc9..aa74099b5 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/ColumnSortSpecification.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/ColumnSortSpecification.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/CountDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/CountDSL.java index a684bae66..069249072 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/CountDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/CountDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/CountDSLCompleter.java b/src/main/java/org/mybatis/dynamic/sql/select/CountDSLCompleter.java index ac93878fa..d2972d26f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/CountDSLCompleter.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/CountDSLCompleter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/GroupByModel.java b/src/main/java/org/mybatis/dynamic/sql/select/GroupByModel.java index 8123bb4b4..4c85dcd45 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/GroupByModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/GroupByModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/HavingApplier.java b/src/main/java/org/mybatis/dynamic/sql/select/HavingApplier.java index 24ce28a28..d0a61a7fb 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/HavingApplier.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/HavingApplier.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/HavingDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/HavingDSL.java index 648ddda16..2f5a7e5fa 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/HavingDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/HavingDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/HavingModel.java b/src/main/java/org/mybatis/dynamic/sql/select/HavingModel.java index 5f773cf3b..5f8cd38c8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/HavingModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/HavingModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/MultiSelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java index 0c244481c..2eb3c8b89 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/MultiSelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java index 60539c660..c61188d80 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/PagingDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/PagingDSL.java index 0d86e5e9a..7c6f004fd 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/PagingDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/PagingDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/PagingModel.java b/src/main/java/org/mybatis/dynamic/sql/select/PagingModel.java index 603f40001..59b4a8bf2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/PagingModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/PagingModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/QueryExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java index c4e2b5d9a..90156cea7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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 f67060aad..4d5e948ea 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-2024 the original author or authors. + * Copyright 2016-2025 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/SelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java index 525e3282d..eed99b218 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/SelectDSLCompleter.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSLCompleter.java index 4252dfc8d..a38d2d3cf 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSLCompleter.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSLCompleter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/SelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java index da01d09b5..cb7d135dd 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/SimpleSortSpecification.java b/src/main/java/org/mybatis/dynamic/sql/select/SimpleSortSpecification.java index 2c363ccc4..0a2c4918e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SimpleSortSpecification.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SimpleSortSpecification.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/SubQuery.java b/src/main/java/org/mybatis/dynamic/sql/select/SubQuery.java index 27bca6fca..271682870 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SubQuery.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SubQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/UnionQuery.java b/src/main/java/org/mybatis/dynamic/sql/select/UnionQuery.java index 8d8f07be6..9beb85b46 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/UnionQuery.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/UnionQuery.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/aggregate/AbstractCount.java b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/AbstractCount.java index f0431f026..ae91015ae 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/AbstractCount.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/AbstractCount.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/aggregate/Avg.java b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Avg.java index 6fcb1f3b5..0e04d78ea 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Avg.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Avg.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/aggregate/Count.java b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Count.java index 4c0240d24..9d2a791cf 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Count.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Count.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/aggregate/CountAll.java b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/CountAll.java index 78fbca6e5..306c14f54 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/CountAll.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/CountAll.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/aggregate/CountDistinct.java b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/CountDistinct.java index 79d9b874a..4acba9db9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/CountDistinct.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/CountDistinct.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/aggregate/Max.java b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Max.java index 2e3e0fec0..5d20594ea 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Max.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Max.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/aggregate/Min.java b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Min.java index b376d00a2..e838c2f3a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Min.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Min.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/aggregate/Sum.java b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Sum.java index e86a0d5b4..6b9cd657e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Sum.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Sum.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/caseexpression/BasicWhenCondition.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/BasicWhenCondition.java index 8fe46e5fd..dcfaddc43 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/BasicWhenCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/BasicWhenCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/caseexpression/ConditionBasedWhenCondition.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/ConditionBasedWhenCondition.java index 16af8f891..fe3178bff 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/ConditionBasedWhenCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/ConditionBasedWhenCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/caseexpression/ElseDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/ElseDSL.java index abe51d763..39d0bc740 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/ElseDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/ElseDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/caseexpression/SearchedCaseDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseDSL.java index 360fc344d..1dbd663a3 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/caseexpression/SearchedCaseModel.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseModel.java index 15fd864f8..8ca95513c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/caseexpression/SearchedCaseWhenCondition.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseWhenCondition.java index e6d57e32c..21fab5010 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseWhenCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseWhenCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/caseexpression/SimpleCaseDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseDSL.java index 6b3f41338..8fc7a8360 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/caseexpression/SimpleCaseModel.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseModel.java index 3c649c3da..db666df22 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/caseexpression/SimpleCaseWhenCondition.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseWhenCondition.java index 5466f2f3f..7f6351e02 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseWhenCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseWhenCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/caseexpression/SimpleCaseWhenConditionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseWhenConditionVisitor.java index 890343265..dadef7455 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseWhenConditionVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseWhenConditionVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/caseexpression/ThenDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/ThenDSL.java index e88fb13c3..29c914731 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/ThenDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/ThenDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/function/AbstractTypeConvertingFunction.java b/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractTypeConvertingFunction.java index 98e019fa7..448b97cad 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractTypeConvertingFunction.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractTypeConvertingFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/function/AbstractUniTypeFunction.java b/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractUniTypeFunction.java index 6e59885cb..0ad9ee576 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractUniTypeFunction.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractUniTypeFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/function/Add.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Add.java index 533f5cc15..7521b9fd3 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Add.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Add.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/function/Cast.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Cast.java index 11c31e352..742ba2705 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Cast.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Cast.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/function/Concat.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Concat.java index ec1c7f93e..2dbf84b7b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Concat.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Concat.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/function/Concatenate.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Concatenate.java index fa16f4a43..16357b21f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Concatenate.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Concatenate.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/function/Divide.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Divide.java index 76d804707..0463798b5 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Divide.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Divide.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/function/Lower.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Lower.java index 6bed396c0..80cd292d9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Lower.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Lower.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/function/Multiply.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Multiply.java index de359e09c..239e0564b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Multiply.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Multiply.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/function/OperatorFunction.java b/src/main/java/org/mybatis/dynamic/sql/select/function/OperatorFunction.java index 7c9a89316..154a5f564 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/OperatorFunction.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/OperatorFunction.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/function/Substring.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Substring.java index d49263977..a987a3a1f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Substring.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Substring.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/function/Subtract.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Subtract.java index 8f011e902..ae128fc98 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Subtract.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Subtract.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/function/Upper.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Upper.java index a62e5d655..d4be9ff61 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Upper.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Upper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/join/JoinModel.java b/src/main/java/org/mybatis/dynamic/sql/select/join/JoinModel.java index ef1265467..ab6cc67db 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/join/JoinModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/join/JoinModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/join/JoinSpecification.java b/src/main/java/org/mybatis/dynamic/sql/select/join/JoinSpecification.java index 9db5243d2..5ce6677cc 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/join/JoinSpecification.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/join/JoinSpecification.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/join/JoinType.java b/src/main/java/org/mybatis/dynamic/sql/select/join/JoinType.java index a6a456a71..e797d1d1d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/join/JoinType.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/join/JoinType.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/DefaultSelectStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/select/render/DefaultSelectStatementProvider.java index 2542f80d0..e84eea978 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/DefaultSelectStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/DefaultSelectStatementProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/FetchFirstPagingModelRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/FetchFirstPagingModelRenderer.java index 0ad493620..31bbd9cb8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/FetchFirstPagingModelRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/FetchFirstPagingModelRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/HavingRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/HavingRenderer.java index 0c8292a9e..f7feb8b3f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/HavingRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/HavingRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/JoinRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/JoinRenderer.java index 6a437f010..67e84bc5a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/JoinRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/JoinRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/JoinSpecificationRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/JoinSpecificationRenderer.java index 300e416d8..97766c171 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/JoinSpecificationRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/JoinSpecificationRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/LimitAndOffsetPagingModelRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/LimitAndOffsetPagingModelRenderer.java index 609f4816a..ea6452b67 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/LimitAndOffsetPagingModelRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/LimitAndOffsetPagingModelRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/MultiSelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java index 634896ad2..6634da889 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/PagingModelRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/PagingModelRenderer.java index 583b48e4b..fecebbf92 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/PagingModelRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/PagingModelRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/QueryExpressionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/QueryExpressionRenderer.java index 618ea2f9c..d1c5baf09 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/QueryExpressionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/QueryExpressionRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/SearchedCaseRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SearchedCaseRenderer.java index d273c4c87..9fd58a591 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SearchedCaseRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SearchedCaseRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/SearchedCaseWhenConditionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SearchedCaseWhenConditionRenderer.java index b7d9bfff3..f73150f5f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SearchedCaseWhenConditionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SearchedCaseWhenConditionRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/SelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java index 6284b0b49..048a0b0e6 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/SelectStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectStatementProvider.java index 96a8b621c..42cec3f55 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectStatementProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/SimpleCaseRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseRenderer.java index 94cd071f1..036a9c909 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/SimpleCaseWhenConditionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseWhenConditionRenderer.java index e9108806e..702f1a0ad 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseWhenConditionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseWhenConditionRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/SubQueryRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java index b1d6c28ce..906adc8f9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/render/TableExpressionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java index 24dfb190f..402013623 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/update/UpdateDSL.java b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java index c104e18e6..75ccc9ac2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/update/UpdateDSLCompleter.java b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSLCompleter.java index 70abc3a5e..30512c46a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSLCompleter.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSLCompleter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/update/UpdateModel.java b/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java index 2c828da91..813ad51f8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/update/render/DefaultUpdateStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/update/render/DefaultUpdateStatementProvider.java index c2f14fbd6..5e2d5d355 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/render/DefaultUpdateStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/render/DefaultUpdateStatementProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/update/render/SetPhraseVisitor.java b/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java index 7bbe575fc..0e057ad47 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/update/render/UpdateRenderer.java b/src/main/java/org/mybatis/dynamic/sql/update/render/UpdateRenderer.java index 3af6aa6d2..a22b8f756 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 @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/update/render/UpdateStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/update/render/UpdateStatementProvider.java index 539b41b80..087741ae2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/render/UpdateStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/render/UpdateStatementProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/AbstractColumnMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/AbstractColumnMapping.java index e86e69738..4107e9590 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/AbstractColumnMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/AbstractColumnMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/Buildable.java b/src/main/java/org/mybatis/dynamic/sql/util/Buildable.java index eab57548f..dcb9fde70 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/Buildable.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/Buildable.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/ColumnMappingVisitor.java b/src/main/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitor.java index 37c785cd2..19f949f09 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/ColumnToColumnMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/ColumnToColumnMapping.java index d72607cc2..b287ce215 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/ColumnToColumnMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/ColumnToColumnMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/ConfigurableStatement.java b/src/main/java/org/mybatis/dynamic/sql/util/ConfigurableStatement.java index d87edac4b..9fedc85a0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/ConfigurableStatement.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/ConfigurableStatement.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/ConstantMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/ConstantMapping.java index c813559f3..5396e3499 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/ConstantMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/ConstantMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/FragmentAndParameters.java b/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java index 8f2b58aae..44a679201 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/FragmentCollector.java b/src/main/java/org/mybatis/dynamic/sql/util/FragmentCollector.java index cc043572f..bdf7371ba 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/FragmentCollector.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/FragmentCollector.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/GeneralInsertMappingVisitor.java b/src/main/java/org/mybatis/dynamic/sql/util/GeneralInsertMappingVisitor.java index ac20a6faf..e55e3d100 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/GeneralInsertMappingVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/GeneralInsertMappingVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/InsertMappingVisitor.java b/src/main/java/org/mybatis/dynamic/sql/util/InsertMappingVisitor.java index 39add47a1..60770ec15 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/InsertMappingVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/InsertMappingVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/InternalError.java b/src/main/java/org/mybatis/dynamic/sql/util/InternalError.java index e437b8728..ed6b0a3cc 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/InternalError.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/InternalError.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/Messages.java b/src/main/java/org/mybatis/dynamic/sql/util/Messages.java index 1c013bb10..649dd7747 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/Messages.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/Messages.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/MultiRowInsertMappingVisitor.java b/src/main/java/org/mybatis/dynamic/sql/util/MultiRowInsertMappingVisitor.java index 6132ce90e..18a75221d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/MultiRowInsertMappingVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/MultiRowInsertMappingVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/NullMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/NullMapping.java index b30430f0f..ccd95d52f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/NullMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/NullMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/Predicates.java b/src/main/java/org/mybatis/dynamic/sql/util/Predicates.java index 0c66c921d..d840a214a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/Predicates.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/Predicates.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/PropertyMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/PropertyMapping.java index e0a4f6779..87023c7e9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/PropertyMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/PropertyMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/PropertyWhenPresentMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/PropertyWhenPresentMapping.java index 3634e6244..e5f6f3e62 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/PropertyWhenPresentMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/PropertyWhenPresentMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/RowMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/RowMapping.java index 20f99940c..9ece580ca 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/RowMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/RowMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/SelectMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/SelectMapping.java index 5a24c9956..b588ece67 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/SelectMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/SelectMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/SqlProviderAdapter.java b/src/main/java/org/mybatis/dynamic/sql/util/SqlProviderAdapter.java index 2e129b611..102a54a75 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/SqlProviderAdapter.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/SqlProviderAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/StringConstantMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/StringConstantMapping.java index 8c2cf8ccc..c462bd93c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/StringConstantMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/StringConstantMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/StringUtilities.java b/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java index 3ef16be5e..ea993d420 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/UpdateMappingVisitor.java b/src/main/java/org/mybatis/dynamic/sql/util/UpdateMappingVisitor.java index 9dde23da1..8d06585ab 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/UpdateMappingVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/UpdateMappingVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/Utilities.java b/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java index 780369175..4a70597da 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/Validator.java b/src/main/java/org/mybatis/dynamic/sql/util/Validator.java index 47814c7a2..588f6e372 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/Validator.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/Validator.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/ValueMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/ValueMapping.java index 9028c9c4e..424970f19 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/ValueMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/ValueMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/ValueOrNullMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/ValueOrNullMapping.java index 85690db59..f1198c14d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/ValueOrNullMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/ValueOrNullMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/ValueWhenPresentMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java index 5bee7afd5..eb28e8a81 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/mybatis3/CommonCountMapper.java b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonCountMapper.java index f9319ac3e..d0b6c580d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonCountMapper.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonCountMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/mybatis3/CommonDeleteMapper.java b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonDeleteMapper.java index b8a827fcf..bd7cb06dd 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonDeleteMapper.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonDeleteMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/mybatis3/CommonGeneralInsertMapper.java b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonGeneralInsertMapper.java index 8ec6e889e..4dda5cc11 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonGeneralInsertMapper.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonGeneralInsertMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/mybatis3/CommonInsertMapper.java b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonInsertMapper.java index 0a834f604..bd864b610 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonInsertMapper.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonInsertMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/mybatis3/CommonSelectMapper.java b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java index f0cfb72c0..1faa0bd05 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/mybatis3/CommonUpdateMapper.java b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonUpdateMapper.java index c7e4e40ce..0f25b575d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonUpdateMapper.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonUpdateMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/mybatis3/MyBatis3Utils.java b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/MyBatis3Utils.java index 5b1906429..2e2bb279d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/MyBatis3Utils.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/MyBatis3Utils.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/spring/BatchInsertUtility.java b/src/main/java/org/mybatis/dynamic/sql/util/spring/BatchInsertUtility.java index 01b76b9a0..81f5a5ed6 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/spring/BatchInsertUtility.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/spring/BatchInsertUtility.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/spring/NamedParameterJdbcTemplateExtensions.java b/src/main/java/org/mybatis/dynamic/sql/util/spring/NamedParameterJdbcTemplateExtensions.java index 56fac7d5c..4e630e1d2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/spring/NamedParameterJdbcTemplateExtensions.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/spring/NamedParameterJdbcTemplateExtensions.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java index c87c4a03e..f56063d95 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchPagingItemReaderRenderingStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/springbatch/SpringBatchProviderAdapter.java b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchProviderAdapter.java index ce75697cd..2000c02bf 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchProviderAdapter.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchProviderAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/util/springbatch/SpringBatchUtility.java b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchUtility.java index 01cae8964..9b84ee499 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchUtility.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/SpringBatchUtility.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/AbstractWhereFinisher.java b/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereFinisher.java index edad1cccc..cf1604307 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereFinisher.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereFinisher.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/AbstractWhereStarter.java b/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereStarter.java index e94f0a8a1..3070bde18 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereStarter.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereStarter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/EmbeddedWhereModel.java b/src/main/java/org/mybatis/dynamic/sql/where/EmbeddedWhereModel.java index acede2590..7cd42e73e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/EmbeddedWhereModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/EmbeddedWhereModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/WhereApplier.java b/src/main/java/org/mybatis/dynamic/sql/where/WhereApplier.java index ce2289695..d708aa065 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/WhereApplier.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/WhereApplier.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/WhereDSL.java b/src/main/java/org/mybatis/dynamic/sql/where/WhereDSL.java index a4adc2967..418ed9fde 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/WhereDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/WhereDSL.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/WhereModel.java b/src/main/java/org/mybatis/dynamic/sql/where/WhereModel.java index 5c99d68ff..1901d1163 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/WhereModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/WhereModel.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/AndGatherer.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java index ddd272f40..6a91f8e88 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/CaseInsensitiveVisitableCondition.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveVisitableCondition.java index 18b21a136..c0eef325a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveVisitableCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveVisitableCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java index ff21433d0..c252abb09 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java index 2682dd602..0d1ee2ba0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsEqualToColumn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToColumn.java index 80fa86094..6f12ea99f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToColumn.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsEqualToWithSubselect.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToWithSubselect.java index 6b4def2ce..0c11774be 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToWithSubselect.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToWithSubselect.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsGreaterThan.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java index 3e45574ad..673042b89 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsGreaterThanColumn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanColumn.java index dc0bb513e..446ab6377 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanColumn.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsGreaterThanOrEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java index 8212a3b5b..3b1e970c9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsGreaterThanOrEqualToColumn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToColumn.java index 413d0b206..3b8d4a05e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToColumn.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsGreaterThanOrEqualToWithSubselect.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWithSubselect.java index 9a7e9385f..7f5e0fb7a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWithSubselect.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWithSubselect.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsGreaterThanWithSubselect.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanWithSubselect.java index 9f5ff92dc..5774fc5ec 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanWithSubselect.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanWithSubselect.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsIn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java index ef6979b67..6ce403717 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java index 274226158..80ad63b44 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java index 356fb034a..c65062323 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsInWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java index 6e12a0437..458bab590 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsInWithSubselect.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWithSubselect.java index 51012cfa2..60b936305 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWithSubselect.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWithSubselect.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsLessThan.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java index 516331e0b..764e92c1c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsLessThanColumn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanColumn.java index 8d1c200dd..d8fc2b0e7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanColumn.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsLessThanOrEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java index 83c45cca2..a853838c3 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsLessThanOrEqualToColumn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToColumn.java index 6c3bd8b65..858f86c1f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToColumn.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsLessThanOrEqualToWithSubselect.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToWithSubselect.java index 07d2b67d7..58895b8bc 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToWithSubselect.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToWithSubselect.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsLessThanWithSubselect.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanWithSubselect.java index 21a96e6d1..efc62b982 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanWithSubselect.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanWithSubselect.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsLike.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java index 864ddb432..233485ff4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java index 3b13d1748..430eb41df 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsNotBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java index f380449fd..b449571bb 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsNotEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java index f35516e56..6af567f9d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsNotEqualToColumn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToColumn.java index 7dc52aa26..c8721b035 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToColumn.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsNotEqualToWithSubselect.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToWithSubselect.java index a9095e0c0..f9651646d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToWithSubselect.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToWithSubselect.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsNotIn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java index 9c621f00b..e1ca07abf 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsNotInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java index e91e893c6..2045c8096 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsNotInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java index 7f254eedd..65a1311e8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsNotInWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java index 6917128ab..1c4b570a9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsNotInWithSubselect.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWithSubselect.java index 587994bf8..0892afd96 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWithSubselect.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWithSubselect.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsNotLike.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java index 79d97ca15..f1b6c6ee6 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsNotLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java index eb0450135..b2ba76951 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsNotNull.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotNull.java index 59b4052f8..d4e4cf56a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotNull.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotNull.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/condition/IsNull.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNull.java index 61fe53da2..eae093f10 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNull.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNull.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/render/ColumnAndConditionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java index da1050ed8..879c4f54d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/render/CriterionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java index 7e29a10d3..09e8091c8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/CriterionRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/render/DefaultConditionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java index d5cdc0dd2..3b2852f31 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/render/DefaultWhereClauseProvider.java b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultWhereClauseProvider.java index bf68eb7cf..fa8968c16 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultWhereClauseProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultWhereClauseProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/render/RenderedCriterion.java b/src/main/java/org/mybatis/dynamic/sql/where/render/RenderedCriterion.java index 6d1a2de25..690b72eae 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/RenderedCriterion.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/RenderedCriterion.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/render/WhereClauseProvider.java b/src/main/java/org/mybatis/dynamic/sql/where/render/WhereClauseProvider.java index 1e8d16be5..6fab1f340 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/WhereClauseProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/WhereClauseProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/where/render/WhereRenderer.java b/src/main/java/org/mybatis/dynamic/sql/where/render/WhereRenderer.java index 244dcfa1b..0db5f2dc0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/WhereRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/WhereRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/GroupingCriteriaCollector.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/GroupingCriteriaCollector.kt index 4fe8d3091..32e78b5ff 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/GroupingCriteriaCollector.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/GroupingCriteriaCollector.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt index 078ea2a34..e724e3146 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/KInvalidSQLException.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KInvalidSQLException.kt index fee58915a..1203b555a 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KInvalidSQLException.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KInvalidSQLException.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/KValidator.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KValidator.kt index c50b856e1..f9b6aa323 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KValidator.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KValidator.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt index 059792b2c..ea0d29f36 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBaseBuilders.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBatchInsertBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBatchInsertBuilder.kt index 65ae006da..2d2d798c7 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBatchInsertBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBatchInsertBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinCountBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinCountBuilder.kt index 78f1f880e..c1aadfbe9 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinCountBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinCountBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt index 3146d5e11..aac282b9b 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinDeleteBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinGeneralInsertBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinGeneralInsertBuilder.kt index 152aace24..296d7aa28 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinGeneralInsertBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinGeneralInsertBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertBuilder.kt index cb0730575..e161b5c6e 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertColumnMapCompleters.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertColumnMapCompleters.kt index dd995e23c..ab49f086a 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertColumnMapCompleters.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertColumnMapCompleters.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiRowInsertBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiRowInsertBuilder.kt index e8049c4ef..f97ca8510 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiRowInsertBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiRowInsertBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiSelectBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiSelectBuilder.kt index b0512ed1f..618909cd2 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiSelectBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiSelectBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinPagingDSL.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinPagingDSL.kt index f0b898dd1..03dd8082f 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinPagingDSL.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinPagingDSL.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSelectBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSelectBuilder.kt index abaefebdc..bd115230d 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSelectBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSelectBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSubQueryBuilders.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSubQueryBuilders.kt index cf5a12d8a..3ae99d435 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSubQueryBuilders.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSubQueryBuilders.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilder.kt index 817dba6e8..b403d675f 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUnionBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt index 93dbfaa8a..91d14cf58 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CaseDSLs.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CaseDSLs.kt index 639a981fe..683ac0872 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CaseDSLs.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CaseDSLs.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CastDSL.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CastDSL.kt index cebf26ee9..836c61443 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CastDSL.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CastDSL.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/ColumnExtensions.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/ColumnExtensions.kt index fc4e2a104..59e24a82b 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/ColumnExtensions.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/ColumnExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt index 8a249279a..8be26db50 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlTableExtensions.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlTableExtensions.kt index a59b74874..bbd79dcd7 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlTableExtensions.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlTableExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/model/ModelBuilderFunctions.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/model/ModelBuilderFunctions.kt index 1dd687443..bd25cfab6 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/model/ModelBuilderFunctions.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/model/ModelBuilderFunctions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/mybatis3/MapperSupportFunctions.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/mybatis3/MapperSupportFunctions.kt index 42386e013..e43ed38ee 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/mybatis3/MapperSupportFunctions.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/mybatis3/MapperSupportFunctions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/mybatis3/ProviderBuilderFunctions.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/mybatis3/ProviderBuilderFunctions.kt index 49a1133fd..8324597bc 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/mybatis3/ProviderBuilderFunctions.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/mybatis3/ProviderBuilderFunctions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/spring/NamedParameterJdbcTemplateExtensions.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/spring/NamedParameterJdbcTemplateExtensions.kt index 881c3d9d0..8654abe44 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/spring/NamedParameterJdbcTemplateExtensions.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/spring/NamedParameterJdbcTemplateExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/kotlin/org/mybatis/dynamic/sql/util/kotlin/spring/ProviderBuilderFunctions.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/spring/ProviderBuilderFunctions.kt index 30749c0de..895bbaa20 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/spring/ProviderBuilderFunctions.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/spring/ProviderBuilderFunctions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/resources/org/mybatis/dynamic/sql/util/messages.properties b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties index 05ecfcfe8..92ed4f799 100644 --- a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties +++ b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties @@ -1,5 +1,5 @@ # -# Copyright 2016-2024 the original author or authors. +# Copyright 2016-2025 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/site/resources/css/site.css b/src/site/resources/css/site.css index 9012c031a..54e023e50 100644 --- a/src/site/resources/css/site.css +++ b/src/site/resources/css/site.css @@ -1,5 +1,5 @@ /** - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/site/site.xml b/src/site/site.xml index 2a02c4a79..86b32feac 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright 2016-2024 the original author or authors. + Copyright 2016-2025 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/test/java/config/TestContainersConfiguration.java b/src/test/java/config/TestContainersConfiguration.java index 1919fc0f9..7a4e39450 100644 --- a/src/test/java/config/TestContainersConfiguration.java +++ b/src/test/java/config/TestContainersConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/animal/data/AnimalData.java b/src/test/java/examples/animal/data/AnimalData.java index b9755ac30..aff740d2f 100644 --- a/src/test/java/examples/animal/data/AnimalData.java +++ b/src/test/java/examples/animal/data/AnimalData.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/animal/data/AnimalDataDynamicSqlSupport.java b/src/test/java/examples/animal/data/AnimalDataDynamicSqlSupport.java index 3a2949419..1d8696358 100644 --- a/src/test/java/examples/animal/data/AnimalDataDynamicSqlSupport.java +++ b/src/test/java/examples/animal/data/AnimalDataDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/animal/data/AnimalDataMapper.java b/src/test/java/examples/animal/data/AnimalDataMapper.java index 026a55363..39fcd1875 100644 --- a/src/test/java/examples/animal/data/AnimalDataMapper.java +++ b/src/test/java/examples/animal/data/AnimalDataMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/animal/data/AnimalDataTest.java b/src/test/java/examples/animal/data/AnimalDataTest.java index 12a21e3f6..a883b4bd2 100644 --- a/src/test/java/examples/animal/data/AnimalDataTest.java +++ b/src/test/java/examples/animal/data/AnimalDataTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/animal/data/BindingTest.java b/src/test/java/examples/animal/data/BindingTest.java index 44952965d..33efef5f0 100644 --- a/src/test/java/examples/animal/data/BindingTest.java +++ b/src/test/java/examples/animal/data/BindingTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/animal/data/CaseExpressionTest.java b/src/test/java/examples/animal/data/CaseExpressionTest.java index 322d9504b..84a293a46 100644 --- a/src/test/java/examples/animal/data/CaseExpressionTest.java +++ b/src/test/java/examples/animal/data/CaseExpressionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/animal/data/CommonSelectMapperTest.java b/src/test/java/examples/animal/data/CommonSelectMapperTest.java index cd20d88fa..863df85e6 100644 --- a/src/test/java/examples/animal/data/CommonSelectMapperTest.java +++ b/src/test/java/examples/animal/data/CommonSelectMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/animal/data/FetchFirstTest.java b/src/test/java/examples/animal/data/FetchFirstTest.java index 4466f152f..1c73532f1 100644 --- a/src/test/java/examples/animal/data/FetchFirstTest.java +++ b/src/test/java/examples/animal/data/FetchFirstTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/animal/data/Length.java b/src/test/java/examples/animal/data/Length.java index 34bb7f3c9..a7a8abcb5 100644 --- a/src/test/java/examples/animal/data/Length.java +++ b/src/test/java/examples/animal/data/Length.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/animal/data/LimitAndOffsetTest.java b/src/test/java/examples/animal/data/LimitAndOffsetTest.java index 5267adde3..a5ffc67e5 100644 --- a/src/test/java/examples/animal/data/LimitAndOffsetTest.java +++ b/src/test/java/examples/animal/data/LimitAndOffsetTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/animal/data/MyInCondition.java b/src/test/java/examples/animal/data/MyInCondition.java index 65453997f..e31782dbc 100644 --- a/src/test/java/examples/animal/data/MyInCondition.java +++ b/src/test/java/examples/animal/data/MyInCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/animal/data/OptionalConditionsAnimalDataTest.java b/src/test/java/examples/animal/data/OptionalConditionsAnimalDataTest.java index acf2cd2a3..f09c2544e 100644 --- a/src/test/java/examples/animal/data/OptionalConditionsAnimalDataTest.java +++ b/src/test/java/examples/animal/data/OptionalConditionsAnimalDataTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java b/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java index cff21a348..a967052d2 100644 --- a/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java +++ b/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/animal/data/SubQueryTest.java b/src/test/java/examples/animal/data/SubQueryTest.java index 5a683c6af..808478094 100644 --- a/src/test/java/examples/animal/data/SubQueryTest.java +++ b/src/test/java/examples/animal/data/SubQueryTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/animal/data/VariousListConditionsTest.java b/src/test/java/examples/animal/data/VariousListConditionsTest.java index 4e71ef668..c3cc8777e 100644 --- a/src/test/java/examples/animal/data/VariousListConditionsTest.java +++ b/src/test/java/examples/animal/data/VariousListConditionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/animal/data/VariousPagingAndLimitScenariosTest.java b/src/test/java/examples/animal/data/VariousPagingAndLimitScenariosTest.java index 1fde45c49..8f368994a 100644 --- a/src/test/java/examples/animal/data/VariousPagingAndLimitScenariosTest.java +++ b/src/test/java/examples/animal/data/VariousPagingAndLimitScenariosTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/array/ArrayTest.java b/src/test/java/examples/array/ArrayTest.java index 1890c1821..623221e41 100644 --- a/src/test/java/examples/array/ArrayTest.java +++ b/src/test/java/examples/array/ArrayTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/array/NamesRecord.java b/src/test/java/examples/array/NamesRecord.java index 752999f86..65765ccfe 100644 --- a/src/test/java/examples/array/NamesRecord.java +++ b/src/test/java/examples/array/NamesRecord.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/array/NamesTableDynamicSqlSupport.java b/src/test/java/examples/array/NamesTableDynamicSqlSupport.java index cd40201f6..ce3cfbb8f 100644 --- a/src/test/java/examples/array/NamesTableDynamicSqlSupport.java +++ b/src/test/java/examples/array/NamesTableDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/array/NamesTableMapper.java b/src/test/java/examples/array/NamesTableMapper.java index b8fcc0e80..a42509d42 100644 --- a/src/test/java/examples/array/NamesTableMapper.java +++ b/src/test/java/examples/array/NamesTableMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/array/StringArrayTypeHandler.java b/src/test/java/examples/array/StringArrayTypeHandler.java index 238124a58..555542091 100644 --- a/src/test/java/examples/array/StringArrayTypeHandler.java +++ b/src/test/java/examples/array/StringArrayTypeHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/column/comparison/ColumnComparisonConfiguration.java b/src/test/java/examples/column/comparison/ColumnComparisonConfiguration.java index 1a216bf0d..12bb66cf3 100644 --- a/src/test/java/examples/column/comparison/ColumnComparisonConfiguration.java +++ b/src/test/java/examples/column/comparison/ColumnComparisonConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/column/comparison/ColumnComparisonDynamicSqlSupport.java b/src/test/java/examples/column/comparison/ColumnComparisonDynamicSqlSupport.java index efc8cf83d..f1289b000 100644 --- a/src/test/java/examples/column/comparison/ColumnComparisonDynamicSqlSupport.java +++ b/src/test/java/examples/column/comparison/ColumnComparisonDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/column/comparison/ColumnComparisonMapper.java b/src/test/java/examples/column/comparison/ColumnComparisonMapper.java index 6d2860bc2..f20fc9a84 100644 --- a/src/test/java/examples/column/comparison/ColumnComparisonMapper.java +++ b/src/test/java/examples/column/comparison/ColumnComparisonMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/column/comparison/ColumnComparisonRecord.java b/src/test/java/examples/column/comparison/ColumnComparisonRecord.java index 4ad85d81b..b783d61b4 100644 --- a/src/test/java/examples/column/comparison/ColumnComparisonRecord.java +++ b/src/test/java/examples/column/comparison/ColumnComparisonRecord.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/column/comparison/ColumnComparisonTest.java b/src/test/java/examples/column/comparison/ColumnComparisonTest.java index e70e4211b..91a6036c5 100644 --- a/src/test/java/examples/column/comparison/ColumnComparisonTest.java +++ b/src/test/java/examples/column/comparison/ColumnComparisonTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/complexquery/ComplexQueryTest.java b/src/test/java/examples/complexquery/ComplexQueryTest.java index 2b46b6845..fca43c133 100644 --- a/src/test/java/examples/complexquery/ComplexQueryTest.java +++ b/src/test/java/examples/complexquery/ComplexQueryTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/complexquery/GroupingTest.java b/src/test/java/examples/complexquery/GroupingTest.java index 683fa9d11..1d3f631f6 100644 --- a/src/test/java/examples/complexquery/GroupingTest.java +++ b/src/test/java/examples/complexquery/GroupingTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/complexquery/PersonDynamicSqlSupport.java b/src/test/java/examples/complexquery/PersonDynamicSqlSupport.java index e206d739b..900593419 100644 --- a/src/test/java/examples/complexquery/PersonDynamicSqlSupport.java +++ b/src/test/java/examples/complexquery/PersonDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/complexquery/SearchUtils.java b/src/test/java/examples/complexquery/SearchUtils.java index 773520437..92b40d88b 100644 --- a/src/test/java/examples/complexquery/SearchUtils.java +++ b/src/test/java/examples/complexquery/SearchUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/custom_render/CustomRenderingTest.java b/src/test/java/examples/custom_render/CustomRenderingTest.java index 8ca34bbc2..11d7e331c 100644 --- a/src/test/java/examples/custom_render/CustomRenderingTest.java +++ b/src/test/java/examples/custom_render/CustomRenderingTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/custom_render/JsonRenderingStrategy.java b/src/test/java/examples/custom_render/JsonRenderingStrategy.java index 10f2d3c88..62c822e93 100644 --- a/src/test/java/examples/custom_render/JsonRenderingStrategy.java +++ b/src/test/java/examples/custom_render/JsonRenderingStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/custom_render/JsonTestDynamicSqlSupport.java b/src/test/java/examples/custom_render/JsonTestDynamicSqlSupport.java index b0edba9ff..cbdf85ce0 100644 --- a/src/test/java/examples/custom_render/JsonTestDynamicSqlSupport.java +++ b/src/test/java/examples/custom_render/JsonTestDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/custom_render/JsonTestMapper.java b/src/test/java/examples/custom_render/JsonTestMapper.java index bb3a8f6ac..d928c8a11 100644 --- a/src/test/java/examples/custom_render/JsonTestMapper.java +++ b/src/test/java/examples/custom_render/JsonTestMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/custom_render/JsonTestRecord.java b/src/test/java/examples/custom_render/JsonTestRecord.java index c12d888d4..2d0da5331 100644 --- a/src/test/java/examples/custom_render/JsonTestRecord.java +++ b/src/test/java/examples/custom_render/JsonTestRecord.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/emptywhere/EmptyWhereTest.java b/src/test/java/examples/emptywhere/EmptyWhereTest.java index eca321cd9..4c02f4f66 100644 --- a/src/test/java/examples/emptywhere/EmptyWhereTest.java +++ b/src/test/java/examples/emptywhere/EmptyWhereTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/emptywhere/OrderDynamicSqlSupport.java b/src/test/java/examples/emptywhere/OrderDynamicSqlSupport.java index 1e152ecdb..4664e2b21 100644 --- a/src/test/java/examples/emptywhere/OrderDynamicSqlSupport.java +++ b/src/test/java/examples/emptywhere/OrderDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/emptywhere/PersonDynamicSqlSupport.java b/src/test/java/examples/emptywhere/PersonDynamicSqlSupport.java index 0719edcd0..0a8d791fe 100644 --- a/src/test/java/examples/emptywhere/PersonDynamicSqlSupport.java +++ b/src/test/java/examples/emptywhere/PersonDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/generated/always/GeneratedAlwaysRecord.java b/src/test/java/examples/generated/always/GeneratedAlwaysRecord.java index c539f0f10..9717893e8 100644 --- a/src/test/java/examples/generated/always/GeneratedAlwaysRecord.java +++ b/src/test/java/examples/generated/always/GeneratedAlwaysRecord.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/generated/always/PersonRecord.java b/src/test/java/examples/generated/always/PersonRecord.java index 01a440d87..e38c18527 100644 --- a/src/test/java/examples/generated/always/PersonRecord.java +++ b/src/test/java/examples/generated/always/PersonRecord.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/generated/always/mybatis/GeneratedAlwaysDynamicSqlSupport.java b/src/test/java/examples/generated/always/mybatis/GeneratedAlwaysDynamicSqlSupport.java index 57f125e7e..6a7faf8bc 100644 --- a/src/test/java/examples/generated/always/mybatis/GeneratedAlwaysDynamicSqlSupport.java +++ b/src/test/java/examples/generated/always/mybatis/GeneratedAlwaysDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/generated/always/mybatis/GeneratedAlwaysMapper.java b/src/test/java/examples/generated/always/mybatis/GeneratedAlwaysMapper.java index 38521f063..eb18c1020 100644 --- a/src/test/java/examples/generated/always/mybatis/GeneratedAlwaysMapper.java +++ b/src/test/java/examples/generated/always/mybatis/GeneratedAlwaysMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/generated/always/mybatis/GeneratedAlwaysMapperTest.java b/src/test/java/examples/generated/always/mybatis/GeneratedAlwaysMapperTest.java index 7313e6871..ff70701fd 100644 --- a/src/test/java/examples/generated/always/mybatis/GeneratedAlwaysMapperTest.java +++ b/src/test/java/examples/generated/always/mybatis/GeneratedAlwaysMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/generated/always/mybatis/GeneratedKey.java b/src/test/java/examples/generated/always/mybatis/GeneratedKey.java index f97a0f37e..8a65ac7ec 100644 --- a/src/test/java/examples/generated/always/mybatis/GeneratedKey.java +++ b/src/test/java/examples/generated/always/mybatis/GeneratedKey.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/generated/always/mybatis/GeneratedKeyList.java b/src/test/java/examples/generated/always/mybatis/GeneratedKeyList.java index e1d196fde..d172d238d 100644 --- a/src/test/java/examples/generated/always/mybatis/GeneratedKeyList.java +++ b/src/test/java/examples/generated/always/mybatis/GeneratedKeyList.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/generated/always/mybatis/PersonDynamicSqlSupport.java b/src/test/java/examples/generated/always/mybatis/PersonDynamicSqlSupport.java index 53c1340f6..47a7cd3a3 100644 --- a/src/test/java/examples/generated/always/mybatis/PersonDynamicSqlSupport.java +++ b/src/test/java/examples/generated/always/mybatis/PersonDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/generated/always/mybatis/PersonMapper.java b/src/test/java/examples/generated/always/mybatis/PersonMapper.java index 08058d17d..05d2177de 100644 --- a/src/test/java/examples/generated/always/mybatis/PersonMapper.java +++ b/src/test/java/examples/generated/always/mybatis/PersonMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/generated/always/mybatis/PersonMapperTest.java b/src/test/java/examples/generated/always/mybatis/PersonMapperTest.java index 5687b12ea..4be1c0fcd 100644 --- a/src/test/java/examples/generated/always/mybatis/PersonMapperTest.java +++ b/src/test/java/examples/generated/always/mybatis/PersonMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/generated/always/spring/GeneratedAlwaysDynamicSqlSupport.java b/src/test/java/examples/generated/always/spring/GeneratedAlwaysDynamicSqlSupport.java index fa22c9f00..9a96f8bc2 100644 --- a/src/test/java/examples/generated/always/spring/GeneratedAlwaysDynamicSqlSupport.java +++ b/src/test/java/examples/generated/always/spring/GeneratedAlwaysDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/generated/always/spring/SpringTest.java b/src/test/java/examples/generated/always/spring/SpringTest.java index a84a31bbf..59a241368 100644 --- a/src/test/java/examples/generated/always/spring/SpringTest.java +++ b/src/test/java/examples/generated/always/spring/SpringTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/groupby/AddressDynamicSqlSupport.java b/src/test/java/examples/groupby/AddressDynamicSqlSupport.java index defe42d65..b20ef6f72 100644 --- a/src/test/java/examples/groupby/AddressDynamicSqlSupport.java +++ b/src/test/java/examples/groupby/AddressDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/groupby/GroupByTest.java b/src/test/java/examples/groupby/GroupByTest.java index 793fe2429..13a9a7adc 100644 --- a/src/test/java/examples/groupby/GroupByTest.java +++ b/src/test/java/examples/groupby/GroupByTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/groupby/Person2DynamicSqlSupport.java b/src/test/java/examples/groupby/Person2DynamicSqlSupport.java index 49d784b15..a65813b37 100644 --- a/src/test/java/examples/groupby/Person2DynamicSqlSupport.java +++ b/src/test/java/examples/groupby/Person2DynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/groupby/PersonDynamicSqlSupport.java b/src/test/java/examples/groupby/PersonDynamicSqlSupport.java index 679a6c2bc..9549eb6fd 100644 --- a/src/test/java/examples/groupby/PersonDynamicSqlSupport.java +++ b/src/test/java/examples/groupby/PersonDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/joins/ExistsTest.java b/src/test/java/examples/joins/ExistsTest.java index a742efecb..4161f5448 100644 --- a/src/test/java/examples/joins/ExistsTest.java +++ b/src/test/java/examples/joins/ExistsTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/joins/ItemMasterDynamicSQLSupport.java b/src/test/java/examples/joins/ItemMasterDynamicSQLSupport.java index 834330aac..15bf72505 100644 --- a/src/test/java/examples/joins/ItemMasterDynamicSQLSupport.java +++ b/src/test/java/examples/joins/ItemMasterDynamicSQLSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/joins/JoinMapper.java b/src/test/java/examples/joins/JoinMapper.java index 08c83ff38..447546035 100644 --- a/src/test/java/examples/joins/JoinMapper.java +++ b/src/test/java/examples/joins/JoinMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/joins/JoinMapperTest.java b/src/test/java/examples/joins/JoinMapperTest.java index 1b22697e1..ace7b2115 100644 --- a/src/test/java/examples/joins/JoinMapperTest.java +++ b/src/test/java/examples/joins/JoinMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/joins/JoinSubQueryTest.java b/src/test/java/examples/joins/JoinSubQueryTest.java index 1bda4983e..11b4ce192 100644 --- a/src/test/java/examples/joins/JoinSubQueryTest.java +++ b/src/test/java/examples/joins/JoinSubQueryTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/joins/OrderDetail.java b/src/test/java/examples/joins/OrderDetail.java index 171619444..6c9cdd8c5 100644 --- a/src/test/java/examples/joins/OrderDetail.java +++ b/src/test/java/examples/joins/OrderDetail.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/joins/OrderDetailDynamicSQLSupport.java b/src/test/java/examples/joins/OrderDetailDynamicSQLSupport.java index fe72cc8ac..22a391acf 100644 --- a/src/test/java/examples/joins/OrderDetailDynamicSQLSupport.java +++ b/src/test/java/examples/joins/OrderDetailDynamicSQLSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/joins/OrderLineDynamicSQLSupport.java b/src/test/java/examples/joins/OrderLineDynamicSQLSupport.java index d79d2c799..0ed3e749b 100644 --- a/src/test/java/examples/joins/OrderLineDynamicSQLSupport.java +++ b/src/test/java/examples/joins/OrderLineDynamicSQLSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/joins/OrderMaster.java b/src/test/java/examples/joins/OrderMaster.java index 72ada7ada..9972b6db9 100644 --- a/src/test/java/examples/joins/OrderMaster.java +++ b/src/test/java/examples/joins/OrderMaster.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/joins/OrderMasterDynamicSQLSupport.java b/src/test/java/examples/joins/OrderMasterDynamicSQLSupport.java index e92d8d566..b286971e1 100644 --- a/src/test/java/examples/joins/OrderMasterDynamicSQLSupport.java +++ b/src/test/java/examples/joins/OrderMasterDynamicSQLSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/joins/User.java b/src/test/java/examples/joins/User.java index ba1cb38fc..e8c242a25 100644 --- a/src/test/java/examples/joins/User.java +++ b/src/test/java/examples/joins/User.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/joins/UserDynamicSQLSupport.java b/src/test/java/examples/joins/UserDynamicSQLSupport.java index 45d511b3b..883cd81e9 100644 --- a/src/test/java/examples/joins/UserDynamicSQLSupport.java +++ b/src/test/java/examples/joins/UserDynamicSQLSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/mariadb/ItemsDynamicSQLSupport.java b/src/test/java/examples/mariadb/ItemsDynamicSQLSupport.java index 0ef660624..c47a1af3d 100644 --- a/src/test/java/examples/mariadb/ItemsDynamicSQLSupport.java +++ b/src/test/java/examples/mariadb/ItemsDynamicSQLSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/mariadb/MariaDBTest.java b/src/test/java/examples/mariadb/MariaDBTest.java index a7dca33e8..a98b2e326 100644 --- a/src/test/java/examples/mariadb/MariaDBTest.java +++ b/src/test/java/examples/mariadb/MariaDBTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/mariadb/NumbersDynamicSQLSupport.java b/src/test/java/examples/mariadb/NumbersDynamicSQLSupport.java index f707b91fe..b36b90ec6 100644 --- a/src/test/java/examples/mariadb/NumbersDynamicSQLSupport.java +++ b/src/test/java/examples/mariadb/NumbersDynamicSQLSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/mariadb/OrderByCaseTest.java b/src/test/java/examples/mariadb/OrderByCaseTest.java index 0e0daf251..f842ecb1b 100644 --- a/src/test/java/examples/mariadb/OrderByCaseTest.java +++ b/src/test/java/examples/mariadb/OrderByCaseTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/paging/LimitAndOffsetAdapter.java b/src/test/java/examples/paging/LimitAndOffsetAdapter.java index 02a7cf7d8..de4dafab7 100644 --- a/src/test/java/examples/paging/LimitAndOffsetAdapter.java +++ b/src/test/java/examples/paging/LimitAndOffsetAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/paging/LimitAndOffsetMapper.java b/src/test/java/examples/paging/LimitAndOffsetMapper.java index ef900e827..84146d8b9 100644 --- a/src/test/java/examples/paging/LimitAndOffsetMapper.java +++ b/src/test/java/examples/paging/LimitAndOffsetMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/paging/LimitAndOffsetTest.java b/src/test/java/examples/paging/LimitAndOffsetTest.java index f5a3ab96a..e145568d4 100644 --- a/src/test/java/examples/paging/LimitAndOffsetTest.java +++ b/src/test/java/examples/paging/LimitAndOffsetTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/sharding/ShardedMapper.java b/src/test/java/examples/sharding/ShardedMapper.java index b8bfe1e4f..0f271417c 100644 --- a/src/test/java/examples/sharding/ShardedMapper.java +++ b/src/test/java/examples/sharding/ShardedMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/sharding/ShardingTest.java b/src/test/java/examples/sharding/ShardingTest.java index 86afdcf66..e3db9106a 100644 --- a/src/test/java/examples/sharding/ShardingTest.java +++ b/src/test/java/examples/sharding/ShardingTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/sharding/TableCodesDynamicSqlSupport.java b/src/test/java/examples/sharding/TableCodesDynamicSqlSupport.java index 00d64d0e1..6cec6e9c8 100644 --- a/src/test/java/examples/sharding/TableCodesDynamicSqlSupport.java +++ b/src/test/java/examples/sharding/TableCodesDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/simple/AddressDynamicSqlSupport.java b/src/test/java/examples/simple/AddressDynamicSqlSupport.java index 14eec218b..be0581e31 100644 --- a/src/test/java/examples/simple/AddressDynamicSqlSupport.java +++ b/src/test/java/examples/simple/AddressDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/simple/AddressMapper.java b/src/test/java/examples/simple/AddressMapper.java index 49df34aeb..534162520 100644 --- a/src/test/java/examples/simple/AddressMapper.java +++ b/src/test/java/examples/simple/AddressMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/simple/AddressRecord.java b/src/test/java/examples/simple/AddressRecord.java index f256ca1bc..5af471126 100644 --- a/src/test/java/examples/simple/AddressRecord.java +++ b/src/test/java/examples/simple/AddressRecord.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/simple/CompoundKeyDynamicSqlSupport.java b/src/test/java/examples/simple/CompoundKeyDynamicSqlSupport.java index c4e0c328d..88132049b 100644 --- a/src/test/java/examples/simple/CompoundKeyDynamicSqlSupport.java +++ b/src/test/java/examples/simple/CompoundKeyDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/simple/CompoundKeyMapper.java b/src/test/java/examples/simple/CompoundKeyMapper.java index d42d3336e..8f802860f 100644 --- a/src/test/java/examples/simple/CompoundKeyMapper.java +++ b/src/test/java/examples/simple/CompoundKeyMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/simple/CompoundKeyRow.java b/src/test/java/examples/simple/CompoundKeyRow.java index fb47ca9d5..c710d4b26 100644 --- a/src/test/java/examples/simple/CompoundKeyRow.java +++ b/src/test/java/examples/simple/CompoundKeyRow.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/simple/LastName.java b/src/test/java/examples/simple/LastName.java index f909d90df..1caaef4e2 100644 --- a/src/test/java/examples/simple/LastName.java +++ b/src/test/java/examples/simple/LastName.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/simple/LastNameTypeHandler.java b/src/test/java/examples/simple/LastNameTypeHandler.java index b9fa7cce0..e8a26486e 100644 --- a/src/test/java/examples/simple/LastNameTypeHandler.java +++ b/src/test/java/examples/simple/LastNameTypeHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/simple/MyBatisMapToRowTest.java b/src/test/java/examples/simple/MyBatisMapToRowTest.java index a542d36f6..473a4cd47 100644 --- a/src/test/java/examples/simple/MyBatisMapToRowTest.java +++ b/src/test/java/examples/simple/MyBatisMapToRowTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/simple/PersonDynamicSqlSupport.java b/src/test/java/examples/simple/PersonDynamicSqlSupport.java index 51b761be4..215f8a909 100644 --- a/src/test/java/examples/simple/PersonDynamicSqlSupport.java +++ b/src/test/java/examples/simple/PersonDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/simple/PersonMapper.java b/src/test/java/examples/simple/PersonMapper.java index d31f4af1a..dffc66ee4 100644 --- a/src/test/java/examples/simple/PersonMapper.java +++ b/src/test/java/examples/simple/PersonMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/simple/PersonMapperTest.java b/src/test/java/examples/simple/PersonMapperTest.java index cb8a424ef..7aed9182d 100644 --- a/src/test/java/examples/simple/PersonMapperTest.java +++ b/src/test/java/examples/simple/PersonMapperTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/simple/PersonRecord.java b/src/test/java/examples/simple/PersonRecord.java index 57ac78bd9..bb7702cc1 100644 --- a/src/test/java/examples/simple/PersonRecord.java +++ b/src/test/java/examples/simple/PersonRecord.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/simple/PersonWithAddress.java b/src/test/java/examples/simple/PersonWithAddress.java index a7a07b37f..ec38997e5 100644 --- a/src/test/java/examples/simple/PersonWithAddress.java +++ b/src/test/java/examples/simple/PersonWithAddress.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/simple/PersonWithAddressMapper.java b/src/test/java/examples/simple/PersonWithAddressMapper.java index dc47df896..55607a8f7 100644 --- a/src/test/java/examples/simple/PersonWithAddressMapper.java +++ b/src/test/java/examples/simple/PersonWithAddressMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/simple/ReusableWhereTest.java b/src/test/java/examples/simple/ReusableWhereTest.java index a0ca639d3..f3b6d1d4e 100644 --- a/src/test/java/examples/simple/ReusableWhereTest.java +++ b/src/test/java/examples/simple/ReusableWhereTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/simple/YesNoTypeHandler.java b/src/test/java/examples/simple/YesNoTypeHandler.java index 780538d4e..a721ccb1e 100644 --- a/src/test/java/examples/simple/YesNoTypeHandler.java +++ b/src/test/java/examples/simple/YesNoTypeHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/spring/AddressDynamicSqlSupport.java b/src/test/java/examples/spring/AddressDynamicSqlSupport.java index ec0233fa9..9e68a0c0f 100644 --- a/src/test/java/examples/spring/AddressDynamicSqlSupport.java +++ b/src/test/java/examples/spring/AddressDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/spring/AddressRecord.java b/src/test/java/examples/spring/AddressRecord.java index e691e33d8..a8f56e426 100644 --- a/src/test/java/examples/spring/AddressRecord.java +++ b/src/test/java/examples/spring/AddressRecord.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/spring/CompoundKeyDynamicSqlSupport.java b/src/test/java/examples/spring/CompoundKeyDynamicSqlSupport.java index cc02ed756..af8021eb2 100644 --- a/src/test/java/examples/spring/CompoundKeyDynamicSqlSupport.java +++ b/src/test/java/examples/spring/CompoundKeyDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/spring/CompoundKeyRow.java b/src/test/java/examples/spring/CompoundKeyRow.java index d2f00d53e..ea7162e04 100644 --- a/src/test/java/examples/spring/CompoundKeyRow.java +++ b/src/test/java/examples/spring/CompoundKeyRow.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/spring/LastName.java b/src/test/java/examples/spring/LastName.java index 389ad04c3..2bda4c7cc 100644 --- a/src/test/java/examples/spring/LastName.java +++ b/src/test/java/examples/spring/LastName.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/spring/LastNameParameterConverter.java b/src/test/java/examples/spring/LastNameParameterConverter.java index db59773c8..0914bf4e7 100644 --- a/src/test/java/examples/spring/LastNameParameterConverter.java +++ b/src/test/java/examples/spring/LastNameParameterConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/spring/PersonDynamicSqlSupport.java b/src/test/java/examples/spring/PersonDynamicSqlSupport.java index efb5103c6..ea61e6703 100644 --- a/src/test/java/examples/spring/PersonDynamicSqlSupport.java +++ b/src/test/java/examples/spring/PersonDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/spring/PersonRecord.java b/src/test/java/examples/spring/PersonRecord.java index d7a81883f..138f853d1 100644 --- a/src/test/java/examples/spring/PersonRecord.java +++ b/src/test/java/examples/spring/PersonRecord.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/spring/PersonTemplateTest.java b/src/test/java/examples/spring/PersonTemplateTest.java index 2f0e5b2dc..3934d3125 100644 --- a/src/test/java/examples/spring/PersonTemplateTest.java +++ b/src/test/java/examples/spring/PersonTemplateTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/spring/PersonWithAddress.java b/src/test/java/examples/spring/PersonWithAddress.java index e0e1269e1..7dd143e6f 100644 --- a/src/test/java/examples/spring/PersonWithAddress.java +++ b/src/test/java/examples/spring/PersonWithAddress.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/spring/ReusableWhereTest.java b/src/test/java/examples/spring/ReusableWhereTest.java index b626cf63e..821b27621 100644 --- a/src/test/java/examples/spring/ReusableWhereTest.java +++ b/src/test/java/examples/spring/ReusableWhereTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/spring/SpringConfiguration.java b/src/test/java/examples/spring/SpringConfiguration.java index edc7e4b65..f62bab71e 100644 --- a/src/test/java/examples/spring/SpringConfiguration.java +++ b/src/test/java/examples/spring/SpringConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/spring/SpringMapToRowTest.java b/src/test/java/examples/spring/SpringMapToRowTest.java index d87c67201..7c40f03d8 100644 --- a/src/test/java/examples/spring/SpringMapToRowTest.java +++ b/src/test/java/examples/spring/SpringMapToRowTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/spring/YesNoParameterConverter.java b/src/test/java/examples/spring/YesNoParameterConverter.java index d2154a359..131c0d84a 100644 --- a/src/test/java/examples/spring/YesNoParameterConverter.java +++ b/src/test/java/examples/spring/YesNoParameterConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/springbatch/SpringBatchRenderingTest.java b/src/test/java/examples/springbatch/SpringBatchRenderingTest.java index 48873b375..6cbd617cc 100644 --- a/src/test/java/examples/springbatch/SpringBatchRenderingTest.java +++ b/src/test/java/examples/springbatch/SpringBatchRenderingTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/springbatch/bulkinsert/BulkInsertConfiguration.java b/src/test/java/examples/springbatch/bulkinsert/BulkInsertConfiguration.java index 2e27d3e30..60278b02e 100644 --- a/src/test/java/examples/springbatch/bulkinsert/BulkInsertConfiguration.java +++ b/src/test/java/examples/springbatch/bulkinsert/BulkInsertConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/springbatch/bulkinsert/SpringBatchBulkInsertTest.java b/src/test/java/examples/springbatch/bulkinsert/SpringBatchBulkInsertTest.java index 5b09844f8..a5cf3e2e3 100644 --- a/src/test/java/examples/springbatch/bulkinsert/SpringBatchBulkInsertTest.java +++ b/src/test/java/examples/springbatch/bulkinsert/SpringBatchBulkInsertTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/springbatch/bulkinsert/TestRecordGenerator.java b/src/test/java/examples/springbatch/bulkinsert/TestRecordGenerator.java index 0f1fd9ff2..023e7ee4d 100644 --- a/src/test/java/examples/springbatch/bulkinsert/TestRecordGenerator.java +++ b/src/test/java/examples/springbatch/bulkinsert/TestRecordGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/springbatch/common/PersonProcessor.java b/src/test/java/examples/springbatch/common/PersonProcessor.java index c0d6c165f..ad7492f4e 100644 --- a/src/test/java/examples/springbatch/common/PersonProcessor.java +++ b/src/test/java/examples/springbatch/common/PersonProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/springbatch/common/PersonRecord.java b/src/test/java/examples/springbatch/common/PersonRecord.java index 31f9a227c..edf974f53 100644 --- a/src/test/java/examples/springbatch/common/PersonRecord.java +++ b/src/test/java/examples/springbatch/common/PersonRecord.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/springbatch/common/UpdateStatementConvertor.java b/src/test/java/examples/springbatch/common/UpdateStatementConvertor.java index d310f75bd..089486b71 100644 --- a/src/test/java/examples/springbatch/common/UpdateStatementConvertor.java +++ b/src/test/java/examples/springbatch/common/UpdateStatementConvertor.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/springbatch/cursor/CursorReaderBatchConfiguration.java b/src/test/java/examples/springbatch/cursor/CursorReaderBatchConfiguration.java index 838fe9d41..164716cd2 100644 --- a/src/test/java/examples/springbatch/cursor/CursorReaderBatchConfiguration.java +++ b/src/test/java/examples/springbatch/cursor/CursorReaderBatchConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/springbatch/cursor/SpringBatchCursorTest.java b/src/test/java/examples/springbatch/cursor/SpringBatchCursorTest.java index 544a5b30c..747df2db0 100644 --- a/src/test/java/examples/springbatch/cursor/SpringBatchCursorTest.java +++ b/src/test/java/examples/springbatch/cursor/SpringBatchCursorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/springbatch/mapper/PersonDynamicSqlSupport.java b/src/test/java/examples/springbatch/mapper/PersonDynamicSqlSupport.java index 227f6ee50..82884f29b 100644 --- a/src/test/java/examples/springbatch/mapper/PersonDynamicSqlSupport.java +++ b/src/test/java/examples/springbatch/mapper/PersonDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/springbatch/mapper/PersonMapper.java b/src/test/java/examples/springbatch/mapper/PersonMapper.java index 6fc3bea8f..12d6837ee 100644 --- a/src/test/java/examples/springbatch/mapper/PersonMapper.java +++ b/src/test/java/examples/springbatch/mapper/PersonMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/springbatch/paging/PagingReaderBatchConfiguration.java b/src/test/java/examples/springbatch/paging/PagingReaderBatchConfiguration.java index 2fa74c862..1da98bb9f 100644 --- a/src/test/java/examples/springbatch/paging/PagingReaderBatchConfiguration.java +++ b/src/test/java/examples/springbatch/paging/PagingReaderBatchConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/springbatch/paging/SpringBatchPagingTest.java b/src/test/java/examples/springbatch/paging/SpringBatchPagingTest.java index 879270488..c153c8078 100644 --- a/src/test/java/examples/springbatch/paging/SpringBatchPagingTest.java +++ b/src/test/java/examples/springbatch/paging/SpringBatchPagingTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/type_conversion/MyFilesDynamicSqlSupport.java b/src/test/java/examples/type_conversion/MyFilesDynamicSqlSupport.java index 48d951b5d..7a58cab44 100644 --- a/src/test/java/examples/type_conversion/MyFilesDynamicSqlSupport.java +++ b/src/test/java/examples/type_conversion/MyFilesDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/type_conversion/MyFilesMapper.java b/src/test/java/examples/type_conversion/MyFilesMapper.java index 87b5718b6..1d50774f3 100644 --- a/src/test/java/examples/type_conversion/MyFilesMapper.java +++ b/src/test/java/examples/type_conversion/MyFilesMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/type_conversion/ToBase64.java b/src/test/java/examples/type_conversion/ToBase64.java index 42bfe40d1..46cdb26ed 100644 --- a/src/test/java/examples/type_conversion/ToBase64.java +++ b/src/test/java/examples/type_conversion/ToBase64.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/examples/type_conversion/TypeConversionTest.java b/src/test/java/examples/type_conversion/TypeConversionTest.java index 7aa0e0f9f..90846166e 100644 --- a/src/test/java/examples/type_conversion/TypeConversionTest.java +++ b/src/test/java/examples/type_conversion/TypeConversionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh100/FromGroupByTest.java b/src/test/java/issues/gh100/FromGroupByTest.java index 64fd15a04..9c2ee51fb 100644 --- a/src/test/java/issues/gh100/FromGroupByTest.java +++ b/src/test/java/issues/gh100/FromGroupByTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh100/FromJoinWhereTest.java b/src/test/java/issues/gh100/FromJoinWhereTest.java index 6695d56a6..e36706303 100644 --- a/src/test/java/issues/gh100/FromJoinWhereTest.java +++ b/src/test/java/issues/gh100/FromJoinWhereTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh100/Issue100StartAfterJoinTest.java b/src/test/java/issues/gh100/Issue100StartAfterJoinTest.java index aff76db96..6be283173 100644 --- a/src/test/java/issues/gh100/Issue100StartAfterJoinTest.java +++ b/src/test/java/issues/gh100/Issue100StartAfterJoinTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh100/Issue100Test.java b/src/test/java/issues/gh100/Issue100Test.java index 01a8e0b0e..3f848fea5 100644 --- a/src/test/java/issues/gh100/Issue100Test.java +++ b/src/test/java/issues/gh100/Issue100Test.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh100/StudentDynamicSqlSupport.java b/src/test/java/issues/gh100/StudentDynamicSqlSupport.java index 982cdba47..e169662f8 100644 --- a/src/test/java/issues/gh100/StudentDynamicSqlSupport.java +++ b/src/test/java/issues/gh100/StudentDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh100/StudentRegDynamicSqlSupport.java b/src/test/java/issues/gh100/StudentRegDynamicSqlSupport.java index 4c715db21..e1ddc3e84 100644 --- a/src/test/java/issues/gh100/StudentRegDynamicSqlSupport.java +++ b/src/test/java/issues/gh100/StudentRegDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh105/Issue105Test.java b/src/test/java/issues/gh105/Issue105Test.java index c40127a3d..8fb16f22d 100644 --- a/src/test/java/issues/gh105/Issue105Test.java +++ b/src/test/java/issues/gh105/Issue105Test.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh105/PersonDynamicSqlSupport.java b/src/test/java/issues/gh105/PersonDynamicSqlSupport.java index 8c94a0301..3b33c6591 100644 --- a/src/test/java/issues/gh105/PersonDynamicSqlSupport.java +++ b/src/test/java/issues/gh105/PersonDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh105/SearchUtils.java b/src/test/java/issues/gh105/SearchUtils.java index 759543dc2..53dee4fdd 100644 --- a/src/test/java/issues/gh105/SearchUtils.java +++ b/src/test/java/issues/gh105/SearchUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh324/Issue324Test.java b/src/test/java/issues/gh324/Issue324Test.java index 28ec52d35..732d318c0 100644 --- a/src/test/java/issues/gh324/Issue324Test.java +++ b/src/test/java/issues/gh324/Issue324Test.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh324/NameRecord.java b/src/test/java/issues/gh324/NameRecord.java index 6f6b1b9c6..a00286095 100644 --- a/src/test/java/issues/gh324/NameRecord.java +++ b/src/test/java/issues/gh324/NameRecord.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh324/NameService.java b/src/test/java/issues/gh324/NameService.java index 564cd221b..d7de92076 100644 --- a/src/test/java/issues/gh324/NameService.java +++ b/src/test/java/issues/gh324/NameService.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh324/NameTableDynamicSqlSupport.java b/src/test/java/issues/gh324/NameTableDynamicSqlSupport.java index f838814e1..dfce9811b 100644 --- a/src/test/java/issues/gh324/NameTableDynamicSqlSupport.java +++ b/src/test/java/issues/gh324/NameTableDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh324/NameTableMapper.java b/src/test/java/issues/gh324/NameTableMapper.java index 6a71f7cc0..76723ac73 100644 --- a/src/test/java/issues/gh324/NameTableMapper.java +++ b/src/test/java/issues/gh324/NameTableMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh324/ObservableCache.java b/src/test/java/issues/gh324/ObservableCache.java index de7ac3f1c..d52a2bcd0 100644 --- a/src/test/java/issues/gh324/ObservableCache.java +++ b/src/test/java/issues/gh324/ObservableCache.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh324/TestUtils.java b/src/test/java/issues/gh324/TestUtils.java index cda71a260..23c191686 100644 --- a/src/test/java/issues/gh324/TestUtils.java +++ b/src/test/java/issues/gh324/TestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh324/spring/SpringNameService.java b/src/test/java/issues/gh324/spring/SpringNameService.java index a35af4e58..9fbfdf03f 100644 --- a/src/test/java/issues/gh324/spring/SpringNameService.java +++ b/src/test/java/issues/gh324/spring/SpringNameService.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh324/spring/SpringTransactionTest.java b/src/test/java/issues/gh324/spring/SpringTransactionTest.java index 791ce8485..20922d1d1 100644 --- a/src/test/java/issues/gh324/spring/SpringTransactionTest.java +++ b/src/test/java/issues/gh324/spring/SpringTransactionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh324/spring/TestConfiguration.java b/src/test/java/issues/gh324/spring/TestConfiguration.java index 8eaa5e0e8..8045963c4 100644 --- a/src/test/java/issues/gh324/spring/TestConfiguration.java +++ b/src/test/java/issues/gh324/spring/TestConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh430/NoInitialConditionTest.java b/src/test/java/issues/gh430/NoInitialConditionTest.java index 22f5c954c..9add2bf6e 100644 --- a/src/test/java/issues/gh430/NoInitialConditionTest.java +++ b/src/test/java/issues/gh430/NoInitialConditionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/gh655/Gh655Test.java b/src/test/java/issues/gh655/Gh655Test.java index 457936dc9..e1eb4578f 100644 --- a/src/test/java/issues/gh655/Gh655Test.java +++ b/src/test/java/issues/gh655/Gh655Test.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/lhg142/Issue142Test.java b/src/test/java/issues/lhg142/Issue142Test.java index e290e37d0..4f2ffe60c 100644 --- a/src/test/java/issues/lhg142/Issue142Test.java +++ b/src/test/java/issues/lhg142/Issue142Test.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/lhg142/MyMarkDynamicSqlSupport.java b/src/test/java/issues/lhg142/MyMarkDynamicSqlSupport.java index c543ea9f0..b4eae4a83 100644 --- a/src/test/java/issues/lhg142/MyMarkDynamicSqlSupport.java +++ b/src/test/java/issues/lhg142/MyMarkDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/issues/lhg142/Page.java b/src/test/java/issues/lhg142/Page.java index 34fe70874..dd0b72b97 100644 --- a/src/test/java/issues/lhg142/Page.java +++ b/src/test/java/issues/lhg142/Page.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/BindableColumnTest.java b/src/test/java/org/mybatis/dynamic/sql/BindableColumnTest.java index cc962986a..bc295b741 100644 --- a/src/test/java/org/mybatis/dynamic/sql/BindableColumnTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/BindableColumnTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java b/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java index cc5f16193..2464a4000 100644 --- a/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/StatementConfigurationTest.java b/src/test/java/org/mybatis/dynamic/sql/StatementConfigurationTest.java index bfc76b27f..5112d8de9 100644 --- a/src/test/java/org/mybatis/dynamic/sql/StatementConfigurationTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/StatementConfigurationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/configuration/GlobalConfigurationTest.java b/src/test/java/org/mybatis/dynamic/sql/configuration/GlobalConfigurationTest.java index 0b929f3fe..9f9998780 100644 --- a/src/test/java/org/mybatis/dynamic/sql/configuration/GlobalConfigurationTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/configuration/GlobalConfigurationTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/delete/DeleteStatementTest.java b/src/test/java/org/mybatis/dynamic/sql/delete/DeleteStatementTest.java index c247fd8f5..76edac9bb 100644 --- a/src/test/java/org/mybatis/dynamic/sql/delete/DeleteStatementTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/delete/DeleteStatementTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/insert/GeneralInsertStatementTest.java b/src/test/java/org/mybatis/dynamic/sql/insert/GeneralInsertStatementTest.java index 1063a39a7..5c470cdcc 100644 --- a/src/test/java/org/mybatis/dynamic/sql/insert/GeneralInsertStatementTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/insert/GeneralInsertStatementTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/insert/InsertStatementTest.java b/src/test/java/org/mybatis/dynamic/sql/insert/InsertStatementTest.java index e0ebe5d19..e991bef02 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-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/insert/MapToRowTest.java b/src/test/java/org/mybatis/dynamic/sql/insert/MapToRowTest.java index fc8c17ad5..eb0ff2657 100644 --- a/src/test/java/org/mybatis/dynamic/sql/insert/MapToRowTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/insert/MapToRowTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueCollectorTest.java b/src/test/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueCollectorTest.java index ffc8b7d8f..75f414d5d 100644 --- a/src/test/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueCollectorTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueCollectorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/mybatis3/CriterionRendererTest.java b/src/test/java/org/mybatis/dynamic/sql/mybatis3/CriterionRendererTest.java index ef82f3322..ca520cc91 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-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/mybatis3/InsertStatementTest.java b/src/test/java/org/mybatis/dynamic/sql/mybatis3/InsertStatementTest.java index 471c9ef3e..5e0ef7f7b 100644 --- a/src/test/java/org/mybatis/dynamic/sql/mybatis3/InsertStatementTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/mybatis3/InsertStatementTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/mybatis3/SelectStatementTest.java b/src/test/java/org/mybatis/dynamic/sql/mybatis3/SelectStatementTest.java index dae3b9585..a7cecc2f1 100644 --- a/src/test/java/org/mybatis/dynamic/sql/mybatis3/SelectStatementTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/mybatis3/SelectStatementTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/mybatis3/UpdateStatementTest.java b/src/test/java/org/mybatis/dynamic/sql/mybatis3/UpdateStatementTest.java index 6a6b92dfa..2ee506f38 100644 --- a/src/test/java/org/mybatis/dynamic/sql/mybatis3/UpdateStatementTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/mybatis3/UpdateStatementTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/select/HavingModelTest.java b/src/test/java/org/mybatis/dynamic/sql/select/HavingModelTest.java index 47d015da2..92ddb02a0 100644 --- a/src/test/java/org/mybatis/dynamic/sql/select/HavingModelTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/select/HavingModelTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/select/SelectStatementTest.java b/src/test/java/org/mybatis/dynamic/sql/select/SelectStatementTest.java index 6311403d8..fe60e6924 100644 --- a/src/test/java/org/mybatis/dynamic/sql/select/SelectStatementTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/select/SelectStatementTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/subselect/FooDynamicSqlSupport.java b/src/test/java/org/mybatis/dynamic/sql/subselect/FooDynamicSqlSupport.java index 66741d5ce..7398dce58 100644 --- a/src/test/java/org/mybatis/dynamic/sql/subselect/FooDynamicSqlSupport.java +++ b/src/test/java/org/mybatis/dynamic/sql/subselect/FooDynamicSqlSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/subselect/SubSelectTest.java b/src/test/java/org/mybatis/dynamic/sql/subselect/SubSelectTest.java index f0835b173..9e4506df8 100644 --- a/src/test/java/org/mybatis/dynamic/sql/subselect/SubSelectTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/subselect/SubSelectTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/update/UpdateStatementTest.java b/src/test/java/org/mybatis/dynamic/sql/update/UpdateStatementTest.java index 1ad1232eb..061484f2c 100644 --- a/src/test/java/org/mybatis/dynamic/sql/update/UpdateStatementTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/update/UpdateStatementTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitorTest.java b/src/test/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitorTest.java index 2af6cb3db..f75be43f6 100644 --- a/src/test/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitorTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/util/FragmentCollectorTest.java b/src/test/java/org/mybatis/dynamic/sql/util/FragmentCollectorTest.java index 8a1d1e7b9..c3f8a5dea 100644 --- a/src/test/java/org/mybatis/dynamic/sql/util/FragmentCollectorTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/util/FragmentCollectorTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/util/SqlProviderAdapterTest.java b/src/test/java/org/mybatis/dynamic/sql/util/SqlProviderAdapterTest.java index 6cf304698..80c42955b 100644 --- a/src/test/java/org/mybatis/dynamic/sql/util/SqlProviderAdapterTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/util/SqlProviderAdapterTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/util/StringUtilitiesTest.java b/src/test/java/org/mybatis/dynamic/sql/util/StringUtilitiesTest.java index df6285206..1c54cafc9 100644 --- a/src/test/java/org/mybatis/dynamic/sql/util/StringUtilitiesTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/util/StringUtilitiesTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/util/UtilitiesTest.java b/src/test/java/org/mybatis/dynamic/sql/util/UtilitiesTest.java index 3815833c5..230523a64 100644 --- a/src/test/java/org/mybatis/dynamic/sql/util/UtilitiesTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/util/UtilitiesTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/where/WhereModelTest.java b/src/test/java/org/mybatis/dynamic/sql/where/WhereModelTest.java index 2af9f8044..0b94bda96 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/WhereModelTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/WhereModelTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java index 3ab419b33..68adb5714 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java index ed8cf7c5b..86675e51d 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/where/render/CriterionRendererTest.java b/src/test/java/org/mybatis/dynamic/sql/where/render/CriterionRendererTest.java index 39d297fbd..f23f6bfc5 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-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/where/render/OptionalCriterionRenderTest.java b/src/test/java/org/mybatis/dynamic/sql/where/render/OptionalCriterionRenderTest.java index 434155513..1e6e56a92 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-2024 the original author or authors. + * Copyright 2016-2025 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/test/java/org/mybatis/dynamic/sql/where/render/RenderedCriterionTest.java b/src/test/java/org/mybatis/dynamic/sql/where/render/RenderedCriterionTest.java index b99112298..2ab3299ee 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/render/RenderedCriterionTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/render/RenderedCriterionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/animal/data/AnimalDataDynamicSqlSupport.kt b/src/test/kotlin/examples/kotlin/animal/data/AnimalDataDynamicSqlSupport.kt index e5cedd8a6..6c3e67e5a 100644 --- a/src/test/kotlin/examples/kotlin/animal/data/AnimalDataDynamicSqlSupport.kt +++ b/src/test/kotlin/examples/kotlin/animal/data/AnimalDataDynamicSqlSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/animal/data/KCaseExpressionTest.kt b/src/test/kotlin/examples/kotlin/animal/data/KCaseExpressionTest.kt index 8f6eb7aa8..4dc81706e 100644 --- a/src/test/kotlin/examples/kotlin/animal/data/KCaseExpressionTest.kt +++ b/src/test/kotlin/examples/kotlin/animal/data/KCaseExpressionTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/TestUtils.kt b/src/test/kotlin/examples/kotlin/mybatis3/TestUtils.kt index 8cd230607..d07943fb0 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/TestUtils.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/TestUtils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/AddressDynamicSqlSupport.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/AddressDynamicSqlSupport.kt index 728f5fbc0..74e7f3e3e 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/AddressDynamicSqlSupport.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/AddressDynamicSqlSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/AddressMapper.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/AddressMapper.kt index 4efc72ca5..262421dda 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/AddressMapper.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/AddressMapper.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/AddressRecord.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/AddressRecord.kt index 25976b0a0..50bbcbd4c 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/AddressRecord.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/AddressRecord.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/GeneratedAlwaysDynamicSqlSupport.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/GeneratedAlwaysDynamicSqlSupport.kt index b297e10d5..78b7fe1cc 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/GeneratedAlwaysDynamicSqlSupport.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/GeneratedAlwaysDynamicSqlSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/GeneratedAlwaysMapper.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/GeneratedAlwaysMapper.kt index 236ad4f00..2d8aaacd8 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/GeneratedAlwaysMapper.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/GeneratedAlwaysMapper.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/GeneratedAlwaysRecord.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/GeneratedAlwaysRecord.kt index 8856bcda2..8e0700d7b 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/GeneratedAlwaysRecord.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/GeneratedAlwaysRecord.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/GeneratedAlwaysTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/GeneratedAlwaysTest.kt index 39bcd2e1c..0f17275ee 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/GeneratedAlwaysTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/GeneratedAlwaysTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/LastName.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/LastName.kt index 57454f205..a5d12e6ba 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/LastName.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/LastName.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/LastNameTypeHandler.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/LastNameTypeHandler.kt index dd175cafd..a209dcb6f 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/LastNameTypeHandler.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/LastNameTypeHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/PersonDynamicSqlSupport.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonDynamicSqlSupport.kt index cac3e5461..94e60161d 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonDynamicSqlSupport.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonDynamicSqlSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapper.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapper.kt index e7df3fd61..d1b177db7 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapper.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapper.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperExtensions.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperExtensions.kt index ee86408f8..237b5ebd7 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperExtensions.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperTest.kt index 6178e0326..86af992a7 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/PersonRecord.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonRecord.kt index 3d641e8ad..3fee94072 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonRecord.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonRecord.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/PersonWithAddress.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonWithAddress.kt index a2dc9102e..546bfb795 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonWithAddress.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonWithAddress.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/PersonWithAddressMapper.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonWithAddressMapper.kt index f45e228ac..534b50336 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonWithAddressMapper.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonWithAddressMapper.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/PersonWithAddressMapperExtensions.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonWithAddressMapperExtensions.kt index df4c91da8..7c8fcf21e 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonWithAddressMapperExtensions.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/PersonWithAddressMapperExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/ReusableWhereTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/ReusableWhereTest.kt index db54364e7..9ddc5706c 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/ReusableWhereTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/ReusableWhereTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/canonical/YesNoTypeHandler.kt b/src/test/kotlin/examples/kotlin/mybatis3/canonical/YesNoTypeHandler.kt index 6b41308e0..46c264d04 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/canonical/YesNoTypeHandler.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/canonical/YesNoTypeHandler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonConfiguration.kt b/src/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonConfiguration.kt index 9491717c1..a472c4647 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonConfiguration.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonConfiguration.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonDynamicSqlSupport.kt b/src/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonDynamicSqlSupport.kt index c49f9aae6..5d00df6b2 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonDynamicSqlSupport.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonDynamicSqlSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonMapper.kt b/src/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonMapper.kt index 657bc9b66..6ad3e205f 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonMapper.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonMapper.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonRecord.kt b/src/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonRecord.kt index dcbd79661..95170c2d6 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonRecord.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonRecord.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonTest.kt index ef4208ed8..3fe95f434 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/column/comparison/ColumnComparisonTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/custom/render/KCustomRenderingTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KCustomRenderingTest.kt index 04c359fac..d0c7e7a04 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KCustomRenderingTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KCustomRenderingTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/custom/render/KJsonRenderingStrategy.kt b/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KJsonRenderingStrategy.kt index 70cfe012b..9441f7fd8 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KJsonRenderingStrategy.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KJsonRenderingStrategy.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/custom/render/KJsonTestDynamicSqlSupport.kt b/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KJsonTestDynamicSqlSupport.kt index eb9e444a0..2b12d483e 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KJsonTestDynamicSqlSupport.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KJsonTestDynamicSqlSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/custom/render/KJsonTestMapper.kt b/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KJsonTestMapper.kt index d1b2a30b6..5145e18b8 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KJsonTestMapper.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KJsonTestMapper.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/custom/render/KJsonTestRecord.kt b/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KJsonTestRecord.kt index 8256ac847..7c2dfb856 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KJsonTestRecord.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KJsonTestRecord.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/general/GeneralKotlinTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/general/GeneralKotlinTest.kt index 4f0368248..5184e3410 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/general/GeneralKotlinTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/general/GeneralKotlinTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/general/KGroupingTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/general/KGroupingTest.kt index 015859094..91bb853f1 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/general/KGroupingTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/general/KGroupingTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/joins/DeprecatedJoinMapperTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/DeprecatedJoinMapperTest.kt index 7a05b79e4..d712c46c6 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/joins/DeprecatedJoinMapperTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/DeprecatedJoinMapperTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/joins/Domain.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/Domain.kt index 39f767485..db6543a26 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/joins/Domain.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/Domain.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/joins/ExistsTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/ExistsTest.kt index c49ac3ae4..a763ce6fe 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/joins/ExistsTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/ExistsTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/joins/ItemMasterDynamicSQLSupport.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/ItemMasterDynamicSQLSupport.kt index 274542121..5a08ff9e8 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/joins/ItemMasterDynamicSQLSupport.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/ItemMasterDynamicSQLSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapper.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapper.kt index 116fc7091..053066593 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapper.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapper.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt index 1b69ba5ec..2d74a5784 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/joins/OrderDetailDynamicSQLSupport.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/OrderDetailDynamicSQLSupport.kt index 4dea828e1..1d65414f3 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/joins/OrderDetailDynamicSQLSupport.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/OrderDetailDynamicSQLSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/joins/OrderLineDynamicSQLSupport.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/OrderLineDynamicSQLSupport.kt index 6f4e0bc49..a457f7e33 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/joins/OrderLineDynamicSQLSupport.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/OrderLineDynamicSQLSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/joins/OrderMasterDynamicSQLSupport.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/OrderMasterDynamicSQLSupport.kt index 283ecea43..fc785718a 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/joins/OrderMasterDynamicSQLSupport.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/OrderMasterDynamicSQLSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/joins/UserDynamicSQLSupport.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/UserDynamicSQLSupport.kt index 78fa830b7..1d307b6c4 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/joins/UserDynamicSQLSupport.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/UserDynamicSQLSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/mariadb/KItemsDynamicSQLSupport.kt b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KItemsDynamicSQLSupport.kt index 9d306f25e..3ca4e4b8a 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KItemsDynamicSQLSupport.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KItemsDynamicSQLSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt index 5782dad97..8ce870c01 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/sharding/KShardedMapper.kt b/src/test/kotlin/examples/kotlin/mybatis3/sharding/KShardedMapper.kt index 230b7f4b5..73af69c00 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/sharding/KShardedMapper.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/sharding/KShardedMapper.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/sharding/KShardingTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/sharding/KShardingTest.kt index 19e8d23ed..3af1ca0f8 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/sharding/KShardingTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/sharding/KShardingTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/mybatis3/sharding/KTableCodesTableDynamicSQLSupport.kt b/src/test/kotlin/examples/kotlin/mybatis3/sharding/KTableCodesTableDynamicSQLSupport.kt index 7f4eda634..c3e16901e 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/sharding/KTableCodesTableDynamicSQLSupport.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/sharding/KTableCodesTableDynamicSQLSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/spring/canonical/AddressDynamicSqlSupport.kt b/src/test/kotlin/examples/kotlin/spring/canonical/AddressDynamicSqlSupport.kt index 8323960ef..355aeeae4 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/AddressDynamicSqlSupport.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/AddressDynamicSqlSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTemplateDirectTest.kt b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTemplateDirectTest.kt index 18b4f9922..6f558a346 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTemplateDirectTest.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTemplateDirectTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt index 23c6e8058..ae51e6972 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/CanonicalSpringKotlinTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/spring/canonical/CompoundKeyDynamicSqlSupport.kt b/src/test/kotlin/examples/kotlin/spring/canonical/CompoundKeyDynamicSqlSupport.kt index e44a1edef..fb18b48ce 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/CompoundKeyDynamicSqlSupport.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/CompoundKeyDynamicSqlSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/spring/canonical/DomainAndConverters.kt b/src/test/kotlin/examples/kotlin/spring/canonical/DomainAndConverters.kt index 6c6b64b5f..2aed4763e 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/DomainAndConverters.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/DomainAndConverters.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/spring/canonical/GeneratedAlwaysDynamicSqlSupport.kt b/src/test/kotlin/examples/kotlin/spring/canonical/GeneratedAlwaysDynamicSqlSupport.kt index 4740791b5..db4067c5a 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/GeneratedAlwaysDynamicSqlSupport.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/GeneratedAlwaysDynamicSqlSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/spring/canonical/InfixElementsTest.kt b/src/test/kotlin/examples/kotlin/spring/canonical/InfixElementsTest.kt index e5fb13e4f..b1b9791f2 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/InfixElementsTest.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/InfixElementsTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/spring/canonical/InfixSubQueriesTest.kt b/src/test/kotlin/examples/kotlin/spring/canonical/InfixSubQueriesTest.kt index f20ac37cb..37d0745ed 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/InfixSubQueriesTest.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/InfixSubQueriesTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/spring/canonical/KotlinElementsTest.kt b/src/test/kotlin/examples/kotlin/spring/canonical/KotlinElementsTest.kt index 98e9c7a86..74c230200 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/KotlinElementsTest.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/KotlinElementsTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/spring/canonical/PersonDynamicSqlSupport.kt b/src/test/kotlin/examples/kotlin/spring/canonical/PersonDynamicSqlSupport.kt index c0e57852a..049e276f2 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/PersonDynamicSqlSupport.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/PersonDynamicSqlSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/spring/canonical/RowMappers.kt b/src/test/kotlin/examples/kotlin/spring/canonical/RowMappers.kt index d175f49cf..e40360760 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/RowMappers.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/RowMappers.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/spring/canonical/SpringConfiguration.kt b/src/test/kotlin/examples/kotlin/spring/canonical/SpringConfiguration.kt index d225a50db..b9c89041c 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/SpringConfiguration.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/SpringConfiguration.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/spring/canonical/SpringKotlinMapToRowTest.kt b/src/test/kotlin/examples/kotlin/spring/canonical/SpringKotlinMapToRowTest.kt index cfb1d6388..a4e936787 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/SpringKotlinMapToRowTest.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/SpringKotlinMapToRowTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/examples/kotlin/spring/canonical/SpringKotlinSubQueryTest.kt b/src/test/kotlin/examples/kotlin/spring/canonical/SpringKotlinSubQueryTest.kt index d4ff965b9..439680dd4 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/SpringKotlinSubQueryTest.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/SpringKotlinSubQueryTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/issues/kotlin/gh430/KNoInitialConditionsTest.kt b/src/test/kotlin/issues/kotlin/gh430/KNoInitialConditionsTest.kt index b11b4f3aa..6bc03fe07 100644 --- a/src/test/kotlin/issues/kotlin/gh430/KNoInitialConditionsTest.kt +++ b/src/test/kotlin/issues/kotlin/gh430/KNoInitialConditionsTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/nullability/test/BetweenTest.kt b/src/test/kotlin/nullability/test/BetweenTest.kt index 51b35a49d..a6b399b69 100644 --- a/src/test/kotlin/nullability/test/BetweenTest.kt +++ b/src/test/kotlin/nullability/test/BetweenTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/nullability/test/BetweenWhenPresentTest.kt b/src/test/kotlin/nullability/test/BetweenWhenPresentTest.kt index 31cb1e8b2..9cf8509b0 100644 --- a/src/test/kotlin/nullability/test/BetweenWhenPresentTest.kt +++ b/src/test/kotlin/nullability/test/BetweenWhenPresentTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/nullability/test/ComparisonTest.kt b/src/test/kotlin/nullability/test/ComparisonTest.kt index 0df088eb2..0ce1fce32 100644 --- a/src/test/kotlin/nullability/test/ComparisonTest.kt +++ b/src/test/kotlin/nullability/test/ComparisonTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/nullability/test/CompilerUtilities.kt b/src/test/kotlin/nullability/test/CompilerUtilities.kt index 14a9d3f5a..5212de766 100644 --- a/src/test/kotlin/nullability/test/CompilerUtilities.kt +++ b/src/test/kotlin/nullability/test/CompilerUtilities.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/nullability/test/EqualNotEqualTest.kt b/src/test/kotlin/nullability/test/EqualNotEqualTest.kt index 70fd7c242..92b5df38e 100644 --- a/src/test/kotlin/nullability/test/EqualNotEqualTest.kt +++ b/src/test/kotlin/nullability/test/EqualNotEqualTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/nullability/test/InTest.kt b/src/test/kotlin/nullability/test/InTest.kt index 4ea242830..c6c862373 100644 --- a/src/test/kotlin/nullability/test/InTest.kt +++ b/src/test/kotlin/nullability/test/InTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/nullability/test/InWhenPresentTest.kt b/src/test/kotlin/nullability/test/InWhenPresentTest.kt index 2d3be77b5..1ea53811c 100644 --- a/src/test/kotlin/nullability/test/InWhenPresentTest.kt +++ b/src/test/kotlin/nullability/test/InWhenPresentTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/nullability/test/LikeNotLikeTest.kt b/src/test/kotlin/nullability/test/LikeNotLikeTest.kt index 6fef483b3..7b7acce89 100644 --- a/src/test/kotlin/nullability/test/LikeNotLikeTest.kt +++ b/src/test/kotlin/nullability/test/LikeNotLikeTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/nullability/test/NotBetweenTest.kt b/src/test/kotlin/nullability/test/NotBetweenTest.kt index 7db71b41a..e45016a57 100644 --- a/src/test/kotlin/nullability/test/NotBetweenTest.kt +++ b/src/test/kotlin/nullability/test/NotBetweenTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/nullability/test/NotBetweenWhenPresentTest.kt b/src/test/kotlin/nullability/test/NotBetweenWhenPresentTest.kt index 6d83930c1..c3e2d7648 100644 --- a/src/test/kotlin/nullability/test/NotBetweenWhenPresentTest.kt +++ b/src/test/kotlin/nullability/test/NotBetweenWhenPresentTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/nullability/test/NotInTest.kt b/src/test/kotlin/nullability/test/NotInTest.kt index adbcf21bf..1194a7570 100644 --- a/src/test/kotlin/nullability/test/NotInTest.kt +++ b/src/test/kotlin/nullability/test/NotInTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/nullability/test/NotInWhenPresentTest.kt b/src/test/kotlin/nullability/test/NotInWhenPresentTest.kt index 5304b2a0b..e98ba98af 100644 --- a/src/test/kotlin/nullability/test/NotInWhenPresentTest.kt +++ b/src/test/kotlin/nullability/test/NotInWhenPresentTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/kotlin/org/mybatis/dynamic/sql/util/kotlin/model/ModelBuilderTest.kt b/src/test/kotlin/org/mybatis/dynamic/sql/util/kotlin/model/ModelBuilderTest.kt index 1d9e88675..878bad3b9 100644 --- a/src/test/kotlin/org/mybatis/dynamic/sql/util/kotlin/model/ModelBuilderTest.kt +++ b/src/test/kotlin/org/mybatis/dynamic/sql/util/kotlin/model/ModelBuilderTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 the original author or authors. + * Copyright 2016-2025 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/test/resources/defaultTrue.properties b/src/test/resources/defaultTrue.properties index 95959bf37..bca00c4b3 100644 --- a/src/test/resources/defaultTrue.properties +++ b/src/test/resources/defaultTrue.properties @@ -1,5 +1,5 @@ # -# Copyright 2016-2024 the original author or authors. +# Copyright 2016-2025 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/test/resources/empty.properties b/src/test/resources/empty.properties index 8694a62c2..c3201cfb7 100644 --- a/src/test/resources/empty.properties +++ b/src/test/resources/empty.properties @@ -1,5 +1,5 @@ # -# Copyright 2016-2024 the original author or authors. +# Copyright 2016-2025 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/test/resources/examples/animal/data/CreateAnimalData.sql b/src/test/resources/examples/animal/data/CreateAnimalData.sql index cb19f64b1..4443da73a 100644 --- a/src/test/resources/examples/animal/data/CreateAnimalData.sql +++ b/src/test/resources/examples/animal/data/CreateAnimalData.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/examples/array/CreateDB.sql b/src/test/resources/examples/array/CreateDB.sql index d03a4aadc..fd7fa4b04 100644 --- a/src/test/resources/examples/array/CreateDB.sql +++ b/src/test/resources/examples/array/CreateDB.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/examples/column/comparison/CreateDB.sql b/src/test/resources/examples/column/comparison/CreateDB.sql index 9b414e4ea..80f8d6b21 100644 --- a/src/test/resources/examples/column/comparison/CreateDB.sql +++ b/src/test/resources/examples/column/comparison/CreateDB.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/examples/custom_render/dbInit.sql b/src/test/resources/examples/custom_render/dbInit.sql index defb7f5f6..af5d17495 100644 --- a/src/test/resources/examples/custom_render/dbInit.sql +++ b/src/test/resources/examples/custom_render/dbInit.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/examples/generated/always/CreateGeneratedAlwaysDB.sql b/src/test/resources/examples/generated/always/CreateGeneratedAlwaysDB.sql index c7038b187..9bd7ad450 100644 --- a/src/test/resources/examples/generated/always/CreateGeneratedAlwaysDB.sql +++ b/src/test/resources/examples/generated/always/CreateGeneratedAlwaysDB.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/examples/groupby/CreateGroupByDB.sql b/src/test/resources/examples/groupby/CreateGroupByDB.sql index 8f5eb0c33..427c514c7 100644 --- a/src/test/resources/examples/groupby/CreateGroupByDB.sql +++ b/src/test/resources/examples/groupby/CreateGroupByDB.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/examples/joins/CreateJoinDB.sql b/src/test/resources/examples/joins/CreateJoinDB.sql index 37ed62d87..675fb9dcc 100644 --- a/src/test/resources/examples/joins/CreateJoinDB.sql +++ b/src/test/resources/examples/joins/CreateJoinDB.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/examples/joins/JoinMapper.xml b/src/test/resources/examples/joins/JoinMapper.xml index ba6ff8c7a..e70e6b242 100644 --- a/src/test/resources/examples/joins/JoinMapper.xml +++ b/src/test/resources/examples/joins/JoinMapper.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright 2016-2024 the original author or authors. + Copyright 2016-2025 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/test/resources/examples/kotlin/mybatis3/CreateSimpleDB.sql b/src/test/resources/examples/kotlin/mybatis3/CreateSimpleDB.sql index 11c516de2..769a0fed4 100644 --- a/src/test/resources/examples/kotlin/mybatis3/CreateSimpleDB.sql +++ b/src/test/resources/examples/kotlin/mybatis3/CreateSimpleDB.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/examples/kotlin/mybatis3/joins/CreateJoinDB.sql b/src/test/resources/examples/kotlin/mybatis3/joins/CreateJoinDB.sql index 5400a658a..8b14e95c0 100644 --- a/src/test/resources/examples/kotlin/mybatis3/joins/CreateJoinDB.sql +++ b/src/test/resources/examples/kotlin/mybatis3/joins/CreateJoinDB.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/examples/kotlin/mybatis3/joins/JoinMapper.xml b/src/test/resources/examples/kotlin/mybatis3/joins/JoinMapper.xml index 7f9aef6cc..bb653837f 100644 --- a/src/test/resources/examples/kotlin/mybatis3/joins/JoinMapper.xml +++ b/src/test/resources/examples/kotlin/mybatis3/joins/JoinMapper.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright 2016-2024 the original author or authors. + Copyright 2016-2025 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/test/resources/examples/kotlin/spring/CreateGeneratedAlwaysDB.sql b/src/test/resources/examples/kotlin/spring/CreateGeneratedAlwaysDB.sql index 24304f983..ef17b67b4 100644 --- a/src/test/resources/examples/kotlin/spring/CreateGeneratedAlwaysDB.sql +++ b/src/test/resources/examples/kotlin/spring/CreateGeneratedAlwaysDB.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/examples/kotlin/spring/CreateSimpleDB.sql b/src/test/resources/examples/kotlin/spring/CreateSimpleDB.sql index 38940e55e..0527b19bb 100644 --- a/src/test/resources/examples/kotlin/spring/CreateSimpleDB.sql +++ b/src/test/resources/examples/kotlin/spring/CreateSimpleDB.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/examples/mariadb/CreateDB.sql b/src/test/resources/examples/mariadb/CreateDB.sql index 3c90c396d..8ea4bab28 100644 --- a/src/test/resources/examples/mariadb/CreateDB.sql +++ b/src/test/resources/examples/mariadb/CreateDB.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/examples/schema_supplier/CreateDB.sql b/src/test/resources/examples/schema_supplier/CreateDB.sql index 7d9d57f8b..2a9f46f47 100644 --- a/src/test/resources/examples/schema_supplier/CreateDB.sql +++ b/src/test/resources/examples/schema_supplier/CreateDB.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/examples/sharding/ShardingDB.sql b/src/test/resources/examples/sharding/ShardingDB.sql index 5af3d717b..e46a0403a 100644 --- a/src/test/resources/examples/sharding/ShardingDB.sql +++ b/src/test/resources/examples/sharding/ShardingDB.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/examples/simple/CreateSimpleDB.sql b/src/test/resources/examples/simple/CreateSimpleDB.sql index e750bb6f0..a60c51ef9 100644 --- a/src/test/resources/examples/simple/CreateSimpleDB.sql +++ b/src/test/resources/examples/simple/CreateSimpleDB.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/examples/springbatch/data.sql b/src/test/resources/examples/springbatch/data.sql index 08aff9937..81cd366b2 100644 --- a/src/test/resources/examples/springbatch/data.sql +++ b/src/test/resources/examples/springbatch/data.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/examples/springbatch/schema.sql b/src/test/resources/examples/springbatch/schema.sql index 3d02988bc..63fdfd66a 100644 --- a/src/test/resources/examples/springbatch/schema.sql +++ b/src/test/resources/examples/springbatch/schema.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/examples/type_conversion/CreateDB.sql b/src/test/resources/examples/type_conversion/CreateDB.sql index a8626e6a8..61cbdb580 100644 --- a/src/test/resources/examples/type_conversion/CreateDB.sql +++ b/src/test/resources/examples/type_conversion/CreateDB.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/issues/gh324/CreateDB.sql b/src/test/resources/issues/gh324/CreateDB.sql index 84e459f70..77bb85949 100644 --- a/src/test/resources/issues/gh324/CreateDB.sql +++ b/src/test/resources/issues/gh324/CreateDB.sql @@ -1,5 +1,5 @@ -- --- Copyright 2016-2024 the original author or authors. +-- Copyright 2016-2025 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/test/resources/logback.xml b/src/test/resources/logback.xml index f760920af..0f6730638 100644 --- a/src/test/resources/logback.xml +++ b/src/test/resources/logback.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright 2016-2024 the original author or authors. + Copyright 2016-2025 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/test/resources/mybatis-dynamic-sql.properties b/src/test/resources/mybatis-dynamic-sql.properties index 8f2b0d2de..fc8f38834 100644 --- a/src/test/resources/mybatis-dynamic-sql.properties +++ b/src/test/resources/mybatis-dynamic-sql.properties @@ -1,5 +1,5 @@ # -# Copyright 2016-2024 the original author or authors. +# Copyright 2016-2025 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. From 11ef9e566978c78bf92ce91abdddf3754bb9590a Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 2 Jan 2025 14:44:28 -0500 Subject: [PATCH 142/260] Use try with resources --- src/test/java/examples/animal/data/BindingTest.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/test/java/examples/animal/data/BindingTest.java b/src/test/java/examples/animal/data/BindingTest.java index 33efef5f0..fe7b9bfe7 100644 --- a/src/test/java/examples/animal/data/BindingTest.java +++ b/src/test/java/examples/animal/data/BindingTest.java @@ -66,8 +66,7 @@ void setup() throws Exception { @Test void testBindInSelectList() { - SqlSession sqlSession = sqlSessionFactory.openSession(); - try { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { Connection connection = sqlSession.getConnection(); PreparedStatement ps = connection.prepareStatement("select brain_weight + ? as calc from AnimalData where id = ?"); @@ -86,15 +85,12 @@ void testBindInSelectList() { assertThat(calculatedWeight).isEqualTo(1.005); } catch (SQLException e) { fail("SQL Exception", e); - } finally { - sqlSession.close(); } } @Test void testBindInWeirdWhere() { - SqlSession sqlSession = sqlSessionFactory.openSession(); - try { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { Connection connection = sqlSession.getConnection(); PreparedStatement ps = connection.prepareStatement("select brain_weight from AnimalData where brain_weight + ? > ? and id = ?"); @@ -114,8 +110,6 @@ void testBindInWeirdWhere() { assertThat(calculatedWeight).isEqualTo(.005); } catch (SQLException e) { fail("SQL Exception", e); - } finally { - sqlSession.close(); } } } From d8b00718e4fbcafad65aa1341e248fe5c32bd9c6 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 2 Jan 2025 14:59:49 -0500 Subject: [PATCH 143/260] Check for invalid missing "then" in case expressions --- .../dynamic/sql/util/kotlin/elements/CaseDSLs.kt | 4 +++- .../org/mybatis/dynamic/sql/util/messages.properties | 1 + .../kotlin/animal/data/KCaseExpressionTest.kt | 11 +++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CaseDSLs.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CaseDSLs.kt index 683ac0872..bc04a992d 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CaseDSLs.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CaseDSLs.kt @@ -22,6 +22,7 @@ import org.mybatis.dynamic.sql.select.caseexpression.ConditionBasedWhenCondition import org.mybatis.dynamic.sql.select.caseexpression.SearchedCaseWhenCondition import org.mybatis.dynamic.sql.select.caseexpression.SimpleCaseWhenCondition import org.mybatis.dynamic.sql.util.kotlin.GroupingCriteriaCollector +import org.mybatis.dynamic.sql.util.kotlin.assertNotNull import org.mybatis.dynamic.sql.util.kotlin.assertNull class KSearchedCaseDSL : KElseDSL { @@ -34,9 +35,10 @@ class KSearchedCaseDSL : KElseDSL { fun `when`(dslCompleter: SearchedCaseCriteriaCollector.() -> Unit) = SearchedCaseCriteriaCollector().apply(dslCompleter).run { + assertNotNull(thenValue, "ERROR.47") //$NON-NLS-1$ whenConditions.add(SearchedCaseWhenCondition.Builder().withInitialCriterion(initialCriterion) .withSubCriteria(subCriteria) - .withThenValue(thenValue) + .withThenValue(thenValue!!) .build()) } diff --git a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties index 92ed4f799..d99bd581e 100644 --- a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties +++ b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties @@ -63,4 +63,5 @@ ERROR.43=A Kotlin cast expression must have one, and only one, `as` element ERROR.44={0} conditions must contain at least one value ERROR.45=You cannot call "on" in a Kotlin join expression more than once ERROR.46=At least one join criterion must render +ERROR.47=A Kotlin case statement must specify a "then" clause for every "when" clause INTERNAL.ERROR=Internal Error {0} diff --git a/src/test/kotlin/examples/kotlin/animal/data/KCaseExpressionTest.kt b/src/test/kotlin/examples/kotlin/animal/data/KCaseExpressionTest.kt index 4dc81706e..673265487 100644 --- a/src/test/kotlin/examples/kotlin/animal/data/KCaseExpressionTest.kt +++ b/src/test/kotlin/examples/kotlin/animal/data/KCaseExpressionTest.kt @@ -922,6 +922,17 @@ class KCaseExpressionTest { }.withMessage(Messages.getString("ERROR.41")) } + @Test + fun testInvalidMissingThen() { + assertThatExceptionOfType(KInvalidSQLException::class.java).isThrownBy { + case { + `when` { + id isEqualTo 22 + } + } + }.withMessage(Messages.getString("ERROR.47")) + } + @Test fun testInvalidSearchedMissingWhen() { assertThatExceptionOfType(InvalidSqlException::class.java).isThrownBy { From 82ae0bd7ae0ef7edd3e0556531f5eaa3c8d9f42b Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 2 Jan 2025 15:00:51 -0500 Subject: [PATCH 144/260] Check for missing resource --- src/test/java/examples/animal/data/BindingTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/java/examples/animal/data/BindingTest.java b/src/test/java/examples/animal/data/BindingTest.java index fe7b9bfe7..f71a6eb58 100644 --- a/src/test/java/examples/animal/data/BindingTest.java +++ b/src/test/java/examples/animal/data/BindingTest.java @@ -51,6 +51,7 @@ class BindingTest { void setup() throws Exception { Class.forName(JDBC_DRIVER); InputStream is = getClass().getResourceAsStream("/examples/animal/data/CreateAnimalData.sql"); + assert is != null; try (Connection connection = DriverManager.getConnection(JDBC_URL, "sa", "")) { ScriptRunner sr = new ScriptRunner(connection); sr.setLogWriter(null); From 1e54aae600e7ddd01fc421afb585b2d2ed6fc2cb Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 2 Jan 2025 15:35:01 -0500 Subject: [PATCH 145/260] Initial Updates for JSpecify --- pom.xml | 5 + .../sql/AbstractSingleValueCondition.java | 8 +- .../sql/AbstractTwoValueCondition.java | 12 +- .../dynamic/sql/AliasableSqlTable.java | 4 +- .../dynamic/sql/AndOrCriteriaGroup.java | 10 +- .../mybatis/dynamic/sql/BindableColumn.java | 4 +- .../sql/ColumnAndConditionCriterion.java | 6 +- .../org/mybatis/dynamic/sql/Constant.java | 5 +- .../mybatis/dynamic/sql/CriteriaGroup.java | 8 +- .../mybatis/dynamic/sql/DerivedColumn.java | 25 ++-- .../mybatis/dynamic/sql/ExistsCriterion.java | 4 +- .../mybatis/dynamic/sql/ExistsPredicate.java | 3 - .../dynamic/sql/ParameterTypeConverter.java | 4 +- .../org/mybatis/dynamic/sql/SqlBuilder.java | 55 +++---- .../org/mybatis/dynamic/sql/SqlColumn.java | 48 +++--- .../org/mybatis/dynamic/sql/SqlTable.java | 5 - .../mybatis/dynamic/sql/StringConstant.java | 5 +- .../common/AbstractBooleanExpressionDSL.java | 25 +--- .../AbstractBooleanExpressionModel.java | 7 +- .../AbstractBooleanExpressionRenderer.java | 3 +- .../dynamic/sql/common/CommonBuilder.java | 33 +++-- .../dynamic/sql/common/package-info.java | 19 +++ .../configuration/GlobalConfiguration.java | 7 +- .../sql/configuration/package-info.java | 19 +++ .../mybatis/dynamic/sql/delete/DeleteDSL.java | 18 +-- .../dynamic/sql/delete/DeleteModel.java | 11 +- .../dynamic/sql/delete/package-info.java | 19 +++ .../DefaultDeleteStatementProvider.java | 4 +- .../sql/delete/render/DeleteRenderer.java | 5 +- .../sql/delete/render/package-info.java | 19 +++ .../dynamic/sql/exception/package-info.java | 19 +++ .../insert/AbstractMultiRowInsertModel.java | 3 +- .../dynamic/sql/insert/BatchInsertDSL.java | 5 +- .../dynamic/sql/insert/BatchInsertModel.java | 2 - .../dynamic/sql/insert/GeneralInsertDSL.java | 5 +- .../sql/insert/GeneralInsertModel.java | 7 +- .../mybatis/dynamic/sql/insert/InsertDSL.java | 7 +- .../dynamic/sql/insert/InsertModel.java | 7 +- .../dynamic/sql/insert/InsertSelectDSL.java | 5 +- .../dynamic/sql/insert/InsertSelectModel.java | 15 +- .../dynamic/sql/insert/MultiRowInsertDSL.java | 2 - .../sql/insert/MultiRowInsertModel.java | 2 - .../dynamic/sql/insert/package-info.java | 19 +++ .../sql/insert/render/BatchInsert.java | 4 +- .../insert/render/BatchInsertRenderer.java | 8 +- ...DefaultGeneralInsertStatementProvider.java | 4 +- .../DefaultInsertStatementProvider.java | 7 +- ...efaultMultiRowInsertStatementProvider.java | 4 +- .../render/FieldAndValueAndParameters.java | 9 +- .../insert/render/GeneralInsertRenderer.java | 8 +- .../GeneralInsertValuePhraseVisitor.java | 5 +- .../sql/insert/render/InsertRenderer.java | 7 +- .../insert/render/InsertSelectRenderer.java | 7 +- .../render/InsertStatementProvider.java | 3 - .../insert/render/MultiRowInsertRenderer.java | 8 +- .../render/MultiRowValuePhraseVisitor.java | 6 +- .../sql/insert/render/package-info.java | 19 +++ .../org/mybatis/dynamic/sql/package-info.java | 19 +++ .../dynamic/sql/render/RenderingContext.java | 15 +- .../TableAliasCalculatorWithParent.java | 5 +- .../dynamic/sql/render/package-info.java | 19 +++ .../sql/select/AbstractHavingFinisher.java | 3 +- .../select/AbstractQueryExpressionDSL.java | 35 ++--- .../sql/select/AbstractSelectModel.java | 15 +- .../mybatis/dynamic/sql/select/CountDSL.java | 6 +- .../mybatis/dynamic/sql/select/HavingDSL.java | 2 - .../dynamic/sql/select/MultiSelectDSL.java | 18 +-- .../dynamic/sql/select/MultiSelectModel.java | 5 +- .../dynamic/sql/select/PagingModel.java | 20 +-- .../sql/select/QueryExpressionDSL.java | 51 +++---- .../sql/select/QueryExpressionModel.java | 33 +++-- .../mybatis/dynamic/sql/select/SelectDSL.java | 18 +-- .../dynamic/sql/select/SelectModel.java | 2 - .../mybatis/dynamic/sql/select/SubQuery.java | 9 +- .../sql/select/aggregate/AbstractCount.java | 5 +- .../sql/select/aggregate/package-info.java | 19 +++ .../caseexpression/SearchedCaseDSL.java | 3 +- .../caseexpression/SearchedCaseModel.java | 13 +- .../SearchedCaseWhenCondition.java | 3 +- .../select/caseexpression/SimpleCaseDSL.java | 3 +- .../caseexpression/SimpleCaseModel.java | 15 +- .../select/caseexpression/package-info.java | 19 +++ .../AbstractTypeConvertingFunction.java | 5 +- .../dynamic/sql/select/function/Cast.java | 9 +- .../sql/select/function/package-info.java | 19 +++ .../sql/select/join/JoinSpecification.java | 5 +- .../dynamic/sql/select/join/package-info.java | 19 +++ .../dynamic/sql/select/package-info.java | 19 +++ .../DefaultSelectStatementProvider.java | 4 +- .../sql/select/render/JoinRenderer.java | 7 +- .../select/render/MultiSelectRenderer.java | 7 +- .../select/render/PagingModelRenderer.java | 5 +- .../render/QueryExpressionRenderer.java | 8 +- .../sql/select/render/SelectRenderer.java | 5 +- .../sql/select/render/SubQueryRenderer.java | 9 +- .../render/TableExpressionRenderer.java | 3 +- .../sql/select/render/package-info.java | 19 +++ .../mybatis/dynamic/sql/update/UpdateDSL.java | 19 ++- .../dynamic/sql/update/UpdateModel.java | 11 +- .../dynamic/sql/update/package-info.java | 19 +++ .../DefaultUpdateStatementProvider.java | 4 +- .../sql/update/render/SetPhraseVisitor.java | 3 +- .../sql/update/render/UpdateRenderer.java | 5 +- .../sql/update/render/package-info.java | 19 +++ .../mybatis/dynamic/sql/util/Buildable.java | 3 - .../sql/util/FragmentAndParameters.java | 7 +- .../mybatis/dynamic/sql/util/Predicates.java | 4 +- .../dynamic/sql/util/StringUtilities.java | 6 +- .../mybatis/dynamic/sql/util/Utilities.java | 18 ++- .../dynamic/sql/util/ValueMapping.java | 3 +- .../dynamic/sql/util/ValueOrNullMapping.java | 3 +- .../sql/util/ValueWhenPresentMapping.java | 5 +- .../sql/util/mybatis3/package-info.java | 19 +++ .../dynamic/sql/util/package-info.java | 19 +++ .../dynamic/sql/util/spring/package-info.java | 19 +++ .../sql/util/springbatch/package-info.java | 19 +++ .../sql/where/AbstractWhereFinisher.java | 5 +- .../sql/where/AbstractWhereStarter.java | 3 +- .../mybatis/dynamic/sql/where/WhereDSL.java | 2 - .../mybatis/dynamic/sql/where/WhereModel.java | 3 +- .../sql/where/condition/AndGatherer.java | 10 +- .../sql/where/condition/IsBetween.java | 9 +- .../sql/where/condition/IsEqualTo.java | 7 +- .../condition/IsEqualToWithSubselect.java | 2 - .../sql/where/condition/IsGreaterThan.java | 7 +- .../condition/IsGreaterThanOrEqualTo.java | 7 +- .../IsGreaterThanOrEqualToWithSubselect.java | 2 - .../condition/IsGreaterThanWithSubselect.java | 2 - .../where/condition/IsInCaseInsensitive.java | 3 +- .../IsInCaseInsensitiveWhenPresent.java | 13 +- .../sql/where/condition/IsInWhenPresent.java | 5 +- .../where/condition/IsInWithSubselect.java | 2 - .../sql/where/condition/IsLessThan.java | 7 +- .../where/condition/IsLessThanOrEqualTo.java | 7 +- .../IsLessThanOrEqualToWithSubselect.java | 2 - .../condition/IsLessThanWithSubselect.java | 2 - .../dynamic/sql/where/condition/IsLike.java | 7 +- .../condition/IsLikeCaseInsensitive.java | 9 +- .../sql/where/condition/IsNotBetween.java | 9 +- .../sql/where/condition/IsNotEqualTo.java | 7 +- .../condition/IsNotEqualToWithSubselect.java | 2 - .../condition/IsNotInCaseInsensitive.java | 3 +- .../IsNotInCaseInsensitiveWhenPresent.java | 13 +- .../where/condition/IsNotInWithSubselect.java | 2 - .../sql/where/condition/IsNotLike.java | 7 +- .../condition/IsNotLikeCaseInsensitive.java | 9 +- .../sql/where/condition/IsNotNull.java | 2 +- .../dynamic/sql/where/condition/IsNull.java | 2 +- .../sql/where/condition/package-info.java | 19 +++ .../dynamic/sql/where/package-info.java | 19 +++ .../render/ColumnAndConditionRenderer.java | 7 +- .../where/render/DefaultConditionVisitor.java | 7 +- .../render/DefaultWhereClauseProvider.java | 4 +- .../sql/where/render/RenderedCriterion.java | 7 +- .../sql/where/render/package-info.java | 19 +++ .../util/kotlin/GroupingCriteriaCollector.kt | 70 ++++----- .../dynamic/sql/util/kotlin/JoinCollector.kt | 6 +- .../util/kotlin/KotlinBatchInsertBuilder.kt | 4 +- .../util/kotlin/KotlinGeneralInsertBuilder.kt | 2 +- .../sql/util/kotlin/KotlinInsertBuilder.kt | 4 +- .../kotlin/KotlinInsertColumnMapCompleters.kt | 12 +- .../kotlin/KotlinMultiRowInsertBuilder.kt | 4 +- .../sql/util/kotlin/KotlinSubQueryBuilders.kt | 6 +- .../sql/util/kotlin/KotlinUpdateBuilder.kt | 8 +- .../util/kotlin/elements/ColumnExtensions.kt | 8 +- .../sql/util/kotlin/elements/SqlElements.kt | 138 +++++++++--------- .../NamedParameterJdbcTemplateExtensions.kt | 10 +- 167 files changed, 1166 insertions(+), 660 deletions(-) create mode 100644 src/main/java/org/mybatis/dynamic/sql/common/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/configuration/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/delete/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/delete/render/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/exception/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/insert/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/insert/render/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/render/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/select/aggregate/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/select/caseexpression/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/select/function/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/select/join/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/select/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/select/render/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/update/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/update/render/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/util/mybatis3/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/util/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/util/spring/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/util/springbatch/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/where/condition/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/where/package-info.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/where/render/package-info.java diff --git a/pom.xml b/pom.xml index 5ca0dbf75..6110bc0e1 100644 --- a/pom.xml +++ b/pom.xml @@ -86,6 +86,11 @@ </properties> <dependencies> + <dependency> + <groupId>org.jspecify</groupId> + <artifactId>jspecify</artifactId> + <version>1.0.0</version> + </dependency> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib-jdk8</artifactId> diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java index 13d4dc8e1..073551b76 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java @@ -19,14 +19,16 @@ import java.util.function.Predicate; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; + public abstract class AbstractSingleValueCondition<T> implements VisitableCondition<T> { - protected final T value; + protected final @Nullable T value; - protected AbstractSingleValueCondition(T value) { + protected AbstractSingleValueCondition(@Nullable T value) { this.value = value; } - public T value() { + public @Nullable T value() { return value; } diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java index c36fe186d..39dd8cfd3 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java @@ -21,20 +21,22 @@ import java.util.function.Predicate; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; + public abstract class AbstractTwoValueCondition<T> implements VisitableCondition<T> { - protected final T value1; - protected final T value2; + protected final @Nullable T value1; + protected final @Nullable T value2; - protected AbstractTwoValueCondition(T value1, T value2) { + protected AbstractTwoValueCondition(@Nullable T value1, @Nullable T value2) { this.value1 = value1; this.value2 = value2; } - public T value1() { + public @Nullable T value1() { return value1; } - public T value2() { + public @Nullable T value2() { return value2; } diff --git a/src/main/java/org/mybatis/dynamic/sql/AliasableSqlTable.java b/src/main/java/org/mybatis/dynamic/sql/AliasableSqlTable.java index fb0c065bf..915b6a561 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AliasableSqlTable.java +++ b/src/main/java/org/mybatis/dynamic/sql/AliasableSqlTable.java @@ -19,9 +19,11 @@ import java.util.Optional; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; + public abstract class AliasableSqlTable<T extends AliasableSqlTable<T>> extends SqlTable { - private String tableAlias; + private @Nullable String tableAlias; private final Supplier<T> constructor; protected AliasableSqlTable(String tableName, Supplier<T> constructor) { diff --git a/src/main/java/org/mybatis/dynamic/sql/AndOrCriteriaGroup.java b/src/main/java/org/mybatis/dynamic/sql/AndOrCriteriaGroup.java index 45ef362f7..ff630a036 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AndOrCriteriaGroup.java +++ b/src/main/java/org/mybatis/dynamic/sql/AndOrCriteriaGroup.java @@ -21,6 +21,8 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; + /** * This class represents a criteria group with either an AND or an OR connector. * This class is intentionally NOT derived from SqlCriterion because we only want it to be @@ -32,7 +34,7 @@ */ public class AndOrCriteriaGroup { private final String connector; - private final SqlCriterion initialCriterion; + private final @Nullable SqlCriterion initialCriterion; private final List<AndOrCriteriaGroup> subCriteria; private AndOrCriteriaGroup(Builder builder) { @@ -54,8 +56,8 @@ public List<AndOrCriteriaGroup> subCriteria() { } public static class Builder { - private String connector; - private SqlCriterion initialCriterion; + private @Nullable String connector; + private @Nullable SqlCriterion initialCriterion; private final List<AndOrCriteriaGroup> subCriteria = new ArrayList<>(); public Builder withConnector(String connector) { @@ -63,7 +65,7 @@ public Builder withConnector(String connector) { return this; } - public Builder withInitialCriterion(SqlCriterion initialCriterion) { + public Builder withInitialCriterion(@Nullable SqlCriterion initialCriterion) { this.initialCriterion = initialCriterion; return this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/BindableColumn.java b/src/main/java/org/mybatis/dynamic/sql/BindableColumn.java index 88d146b2c..a7b7b6697 100644 --- a/src/main/java/org/mybatis/dynamic/sql/BindableColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/BindableColumn.java @@ -17,6 +17,8 @@ import java.util.Optional; +import org.jspecify.annotations.Nullable; + /** * Describes a column with a known data type. The type is only used by the compiler to assure type safety * when building clauses with conditions. @@ -34,7 +36,7 @@ public interface BindableColumn<T> extends BasicColumn { @Override BindableColumn<T> as(String alias); - default Object convertParameterType(T value) { + default @Nullable Object convertParameterType(@Nullable T value) { return value; } diff --git a/src/main/java/org/mybatis/dynamic/sql/ColumnAndConditionCriterion.java b/src/main/java/org/mybatis/dynamic/sql/ColumnAndConditionCriterion.java index ca8fc8f3c..646e695c2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/ColumnAndConditionCriterion.java +++ b/src/main/java/org/mybatis/dynamic/sql/ColumnAndConditionCriterion.java @@ -17,6 +17,8 @@ import java.util.Objects; +import org.jspecify.annotations.Nullable; + public class ColumnAndConditionCriterion<T> extends SqlCriterion { private final BindableColumn<T> column; private final VisitableCondition<T> condition; @@ -45,8 +47,8 @@ public static <T> Builder<T> withColumn(BindableColumn<T> column) { } public static class Builder<T> extends AbstractBuilder<Builder<T>> { - private BindableColumn<T> column; - private VisitableCondition<T> condition; + private @Nullable BindableColumn<T> column; + private @Nullable VisitableCondition<T> condition; public Builder<T> withColumn(BindableColumn<T> column) { this.column = column; diff --git a/src/main/java/org/mybatis/dynamic/sql/Constant.java b/src/main/java/org/mybatis/dynamic/sql/Constant.java index 0f5f2cff5..90547765f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/Constant.java +++ b/src/main/java/org/mybatis/dynamic/sql/Constant.java @@ -18,19 +18,20 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; public class Constant<T> implements BindableColumn<T> { - private final String alias; + private final @Nullable String alias; private final String value; private Constant(String value) { this(value, null); } - private Constant(String value, String alias) { + private Constant(String value, @Nullable String alias) { this.value = Objects.requireNonNull(value); this.alias = alias; } diff --git a/src/main/java/org/mybatis/dynamic/sql/CriteriaGroup.java b/src/main/java/org/mybatis/dynamic/sql/CriteriaGroup.java index b82ac296c..476cb6b3f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/CriteriaGroup.java +++ b/src/main/java/org/mybatis/dynamic/sql/CriteriaGroup.java @@ -17,6 +17,8 @@ import java.util.Optional; +import org.jspecify.annotations.Nullable; + /** * This class represents a criteria group without an AND or an OR connector. This is useful * in situations where the initial SqlCriterion in a list should be further grouped @@ -27,7 +29,7 @@ * @since 1.4.0 */ public class CriteriaGroup extends SqlCriterion { - private final SqlCriterion initialCriterion; + private final @Nullable SqlCriterion initialCriterion; protected CriteriaGroup(AbstractGroupBuilder<?> builder) { super(builder); @@ -44,9 +46,9 @@ public <R> R accept(SqlCriterionVisitor<R> visitor) { } public abstract static class AbstractGroupBuilder<T extends AbstractGroupBuilder<T>> extends AbstractBuilder<T> { - private SqlCriterion initialCriterion; + private @Nullable SqlCriterion initialCriterion; - public T withInitialCriterion(SqlCriterion initialCriterion) { + public T withInitialCriterion(@Nullable SqlCriterion initialCriterion) { this.initialCriterion = initialCriterion; return getThis(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/DerivedColumn.java b/src/main/java/org/mybatis/dynamic/sql/DerivedColumn.java index 93294efc2..df19b8d6b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/DerivedColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/DerivedColumn.java @@ -19,6 +19,7 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; @@ -34,10 +35,10 @@ */ public class DerivedColumn<T> implements BindableColumn<T> { private final String name; - private final String tableQualifier; - private final String columnAlias; - private final JDBCType jdbcType; - private final String typeHandler; + private final @Nullable String tableQualifier; + private final @Nullable String columnAlias; + private final @Nullable JDBCType jdbcType; + private final @Nullable String typeHandler; protected DerivedColumn(Builder<T> builder) { this.name = Objects.requireNonNull(builder.name); @@ -93,18 +94,18 @@ public static <T> DerivedColumn<T> of(String name, String tableQualifier) { } public static class Builder<T> { - private String name; - private String tableQualifier; - private String columnAlias; - private JDBCType jdbcType; - private String typeHandler; + private @Nullable String name; + private @Nullable String tableQualifier; + private @Nullable String columnAlias; + private @Nullable JDBCType jdbcType; + private @Nullable String typeHandler; public Builder<T> withName(String name) { this.name = name; return this; } - public Builder<T> withTableQualifier(String tableQualifier) { + public Builder<T> withTableQualifier(@Nullable String tableQualifier) { this.tableQualifier = tableQualifier; return this; } @@ -114,12 +115,12 @@ public Builder<T> withColumnAlias(String columnAlias) { return this; } - public Builder<T> withJdbcType(JDBCType jdbcType) { + public Builder<T> withJdbcType(@Nullable JDBCType jdbcType) { this.jdbcType = jdbcType; return this; } - public Builder<T> withTypeHandler(String typeHandler) { + public Builder<T> withTypeHandler(@Nullable String typeHandler) { this.typeHandler = typeHandler; return this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/ExistsCriterion.java b/src/main/java/org/mybatis/dynamic/sql/ExistsCriterion.java index b91b20036..17cecdaa6 100644 --- a/src/main/java/org/mybatis/dynamic/sql/ExistsCriterion.java +++ b/src/main/java/org/mybatis/dynamic/sql/ExistsCriterion.java @@ -17,6 +17,8 @@ import java.util.Objects; +import org.jspecify.annotations.Nullable; + public class ExistsCriterion extends SqlCriterion { private final ExistsPredicate existsPredicate; @@ -35,7 +37,7 @@ public <R> R accept(SqlCriterionVisitor<R> visitor) { } public static class Builder extends AbstractBuilder<Builder> { - private ExistsPredicate existsPredicate; + private @Nullable ExistsPredicate existsPredicate; public Builder withExistsPredicate(ExistsPredicate existsPredicate) { this.existsPredicate = existsPredicate; diff --git a/src/main/java/org/mybatis/dynamic/sql/ExistsPredicate.java b/src/main/java/org/mybatis/dynamic/sql/ExistsPredicate.java index 139d7e379..c22a84aa2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/ExistsPredicate.java +++ b/src/main/java/org/mybatis/dynamic/sql/ExistsPredicate.java @@ -17,7 +17,6 @@ import java.util.Objects; -import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.select.SelectModel; import org.mybatis.dynamic.sql.util.Buildable; @@ -38,12 +37,10 @@ public Buildable<SelectModel> selectModelBuilder() { return selectModelBuilder; } - @NotNull public static ExistsPredicate exists(Buildable<SelectModel> selectModelBuilder) { return new ExistsPredicate("exists", selectModelBuilder); //$NON-NLS-1$ } - @NotNull public static ExistsPredicate notExists(Buildable<SelectModel> selectModelBuilder) { return new ExistsPredicate("not exists", selectModelBuilder); //$NON-NLS-1$ } diff --git a/src/main/java/org/mybatis/dynamic/sql/ParameterTypeConverter.java b/src/main/java/org/mybatis/dynamic/sql/ParameterTypeConverter.java index 3b053b154..53a8afefd 100644 --- a/src/main/java/org/mybatis/dynamic/sql/ParameterTypeConverter.java +++ b/src/main/java/org/mybatis/dynamic/sql/ParameterTypeConverter.java @@ -15,6 +15,8 @@ */ package org.mybatis.dynamic.sql; +import org.jspecify.annotations.Nullable; + /** * A parameter type converter is used to change a parameter value from one type to another * during statement rendering and before the parameter is placed into the parameter map. This can be used @@ -50,5 +52,5 @@ */ @FunctionalInterface public interface ParameterTypeConverter<S, T> { - T convert(S source); + @Nullable T convert(@Nullable S source); } diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java index f118136e6..4be99f7ae 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java @@ -21,6 +21,7 @@ import java.util.Objects; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.delete.DeleteDSL; import org.mybatis.dynamic.sql.delete.DeleteModel; import org.mybatis.dynamic.sql.insert.BatchInsertDSL; @@ -617,7 +618,7 @@ static <T> IsNotNull<T> isNotNull() { return new IsNotNull<>(); } - static <T> IsEqualTo<T> isEqualTo(T value) { + static <T> IsEqualTo<T> isEqualTo(@Nullable T value) { return IsEqualTo.of(value); } @@ -633,7 +634,7 @@ static <T> IsEqualToColumn<T> isEqualTo(BasicColumn column) { return IsEqualToColumn.of(column); } - static <T> IsEqualTo<T> isEqualToWhenPresent(T value) { + static <T> IsEqualTo<T> isEqualToWhenPresent(@Nullable T value) { return IsEqualTo.of(value).filter(Objects::nonNull); } @@ -641,7 +642,7 @@ static <T> IsEqualTo<T> isEqualToWhenPresent(Supplier<T> valueSupplier) { return isEqualToWhenPresent(valueSupplier.get()); } - static <T> IsNotEqualTo<T> isNotEqualTo(T value) { + static <T> IsNotEqualTo<T> isNotEqualTo(@Nullable T value) { return IsNotEqualTo.of(value); } @@ -657,7 +658,7 @@ static <T> IsNotEqualToColumn<T> isNotEqualTo(BasicColumn column) { return IsNotEqualToColumn.of(column); } - static <T> IsNotEqualTo<T> isNotEqualToWhenPresent(T value) { + static <T> IsNotEqualTo<T> isNotEqualToWhenPresent(@Nullable T value) { return IsNotEqualTo.of(value).filter(Objects::nonNull); } @@ -665,7 +666,7 @@ static <T> IsNotEqualTo<T> isNotEqualToWhenPresent(Supplier<T> valueSupplier) { return isNotEqualToWhenPresent(valueSupplier.get()); } - static <T> IsGreaterThan<T> isGreaterThan(T value) { + static <T> IsGreaterThan<T> isGreaterThan(@Nullable T value) { return IsGreaterThan.of(value); } @@ -681,7 +682,7 @@ static <T> IsGreaterThanColumn<T> isGreaterThan(BasicColumn column) { return IsGreaterThanColumn.of(column); } - static <T> IsGreaterThan<T> isGreaterThanWhenPresent(T value) { + static <T> IsGreaterThan<T> isGreaterThanWhenPresent(@Nullable T value) { return IsGreaterThan.of(value).filter(Objects::nonNull); } @@ -689,7 +690,7 @@ static <T> IsGreaterThan<T> isGreaterThanWhenPresent(Supplier<T> valueSupplier) return isGreaterThanWhenPresent(valueSupplier.get()); } - static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualTo(T value) { + static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualTo(@Nullable T value) { return IsGreaterThanOrEqualTo.of(value); } @@ -706,7 +707,7 @@ static <T> IsGreaterThanOrEqualToColumn<T> isGreaterThanOrEqualTo(BasicColumn co return IsGreaterThanOrEqualToColumn.of(column); } - static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualToWhenPresent(T value) { + static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualToWhenPresent(@Nullable T value) { return IsGreaterThanOrEqualTo.of(value).filter(Objects::nonNull); } @@ -714,7 +715,7 @@ static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualToWhenPresent(Supplier< return isGreaterThanOrEqualToWhenPresent(valueSupplier.get()); } - static <T> IsLessThan<T> isLessThan(T value) { + static <T> IsLessThan<T> isLessThan(@Nullable T value) { return IsLessThan.of(value); } @@ -730,7 +731,7 @@ static <T> IsLessThanColumn<T> isLessThan(BasicColumn column) { return IsLessThanColumn.of(column); } - static <T> IsLessThan<T> isLessThanWhenPresent(T value) { + static <T> IsLessThan<T> isLessThanWhenPresent(@Nullable T value) { return IsLessThan.of(value).filter(Objects::nonNull); } @@ -738,7 +739,7 @@ static <T> IsLessThan<T> isLessThanWhenPresent(Supplier<T> valueSupplier) { return isLessThanWhenPresent(valueSupplier.get()); } - static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualTo(T value) { + static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualTo(@Nullable T value) { return IsLessThanOrEqualTo.of(value); } @@ -754,7 +755,7 @@ static <T> IsLessThanOrEqualToColumn<T> isLessThanOrEqualTo(BasicColumn column) return IsLessThanOrEqualToColumn.of(column); } - static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualToWhenPresent(T value) { + static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualToWhenPresent(@Nullable T value) { return IsLessThanOrEqualTo.of(value).filter(Objects::nonNull); } @@ -776,11 +777,11 @@ static <T> IsInWithSubselect<T> isIn(Buildable<SelectModel> selectModelBuilder) } @SafeVarargs - static <T> IsInWhenPresent<T> isInWhenPresent(T... values) { + static <T> IsInWhenPresent<T> isInWhenPresent(@Nullable T... values) { return IsInWhenPresent.of(values); } - static <T> IsInWhenPresent<T> isInWhenPresent(Collection<T> values) { + static <T> IsInWhenPresent<T> isInWhenPresent(@Nullable Collection<@Nullable T> values) { return values == null ? IsInWhenPresent.empty() : IsInWhenPresent.of(values); } @@ -798,11 +799,11 @@ static <T> IsNotInWithSubselect<T> isNotIn(Buildable<SelectModel> selectModelBui } @SafeVarargs - static <T> IsNotInWhenPresent<T> isNotInWhenPresent(T... values) { + static <T> IsNotInWhenPresent<T> isNotInWhenPresent(@Nullable T... values) { return IsNotInWhenPresent.of(values); } - static <T> IsNotInWhenPresent<T> isNotInWhenPresent(Collection<T> values) { + static <T> IsNotInWhenPresent<T> isNotInWhenPresent(@Nullable Collection<@Nullable T> values) { return values == null ? IsNotInWhenPresent.empty() : IsNotInWhenPresent.of(values); } @@ -814,7 +815,7 @@ static <T> IsBetween.Builder<T> isBetween(Supplier<T> valueSupplier1) { return isBetween(valueSupplier1.get()); } - static <T> IsBetween.WhenPresentBuilder<T> isBetweenWhenPresent(T value1) { + static <T> IsBetween.WhenPresentBuilder<T> isBetweenWhenPresent(@Nullable T value1) { return IsBetween.isBetweenWhenPresent(value1); } @@ -830,7 +831,7 @@ static <T> IsNotBetween.Builder<T> isNotBetween(Supplier<T> valueSupplier1) { return isNotBetween(valueSupplier1.get()); } - static <T> IsNotBetween.WhenPresentBuilder<T> isNotBetweenWhenPresent(T value1) { + static <T> IsNotBetween.WhenPresentBuilder<T> isNotBetweenWhenPresent(@Nullable T value1) { return IsNotBetween.isNotBetweenWhenPresent(value1); } @@ -847,7 +848,7 @@ static <T> IsLike<T> isLike(Supplier<T> valueSupplier) { return isLike(valueSupplier.get()); } - static <T> IsLike<T> isLikeWhenPresent(T value) { + static <T> IsLike<T> isLikeWhenPresent(@Nullable T value) { return IsLike.of(value).filter(Objects::nonNull); } @@ -863,7 +864,7 @@ static <T> IsNotLike<T> isNotLike(Supplier<T> valueSupplier) { return isNotLike(valueSupplier.get()); } - static <T> IsNotLike<T> isNotLikeWhenPresent(T value) { + static <T> IsNotLike<T> isNotLikeWhenPresent(@Nullable T value) { return IsNotLike.of(value).filter(Objects::nonNull); } @@ -889,7 +890,7 @@ static IsLikeCaseInsensitive isLikeCaseInsensitive(Supplier<String> valueSupplie return isLikeCaseInsensitive(valueSupplier.get()); } - static IsLikeCaseInsensitive isLikeCaseInsensitiveWhenPresent(String value) { + static IsLikeCaseInsensitive isLikeCaseInsensitiveWhenPresent(@Nullable String value) { return IsLikeCaseInsensitive.of(value).filter(Objects::nonNull); } @@ -905,7 +906,7 @@ static IsNotLikeCaseInsensitive isNotLikeCaseInsensitive(Supplier<String> valueS return isNotLikeCaseInsensitive(valueSupplier.get()); } - static IsNotLikeCaseInsensitive isNotLikeCaseInsensitiveWhenPresent(String value) { + static IsNotLikeCaseInsensitive isNotLikeCaseInsensitiveWhenPresent(@Nullable String value) { return IsNotLikeCaseInsensitive.of(value).filter(Objects::nonNull); } @@ -921,11 +922,12 @@ static IsInCaseInsensitive isInCaseInsensitive(Collection<String> values) { return IsInCaseInsensitive.of(values); } - static IsInCaseInsensitiveWhenPresent isInCaseInsensitiveWhenPresent(String... values) { + static IsInCaseInsensitiveWhenPresent isInCaseInsensitiveWhenPresent(@Nullable String... values) { return IsInCaseInsensitiveWhenPresent.of(values); } - static IsInCaseInsensitiveWhenPresent isInCaseInsensitiveWhenPresent(Collection<String> values) { + static IsInCaseInsensitiveWhenPresent isInCaseInsensitiveWhenPresent( + @Nullable Collection<@Nullable String> values) { return values == null ? IsInCaseInsensitiveWhenPresent.empty() : IsInCaseInsensitiveWhenPresent.of(values); } @@ -937,11 +939,12 @@ static IsNotInCaseInsensitive isNotInCaseInsensitive(Collection<String> values) return IsNotInCaseInsensitive.of(values); } - static IsNotInCaseInsensitiveWhenPresent isNotInCaseInsensitiveWhenPresent(String... values) { + static IsNotInCaseInsensitiveWhenPresent isNotInCaseInsensitiveWhenPresent(@Nullable String... values) { return IsNotInCaseInsensitiveWhenPresent.of(values); } - static IsNotInCaseInsensitiveWhenPresent isNotInCaseInsensitiveWhenPresent(Collection<String> values) { + static IsNotInCaseInsensitiveWhenPresent isNotInCaseInsensitiveWhenPresent( + @Nullable Collection<@Nullable String> values) { return values == null ? IsNotInCaseInsensitiveWhenPresent.empty() : IsNotInCaseInsensitiveWhenPresent.of(values); } diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java b/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java index 01eb235a3..5d4e5bc5b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java @@ -19,7 +19,7 @@ import java.util.Objects; import java.util.Optional; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.util.FragmentAndParameters; @@ -29,14 +29,14 @@ public class SqlColumn<T> implements BindableColumn<T>, SortSpecification { protected final String name; protected final SqlTable table; - protected final JDBCType jdbcType; + protected final @Nullable JDBCType jdbcType; protected final String descendingPhrase; - protected final String alias; - protected final String typeHandler; - protected final RenderingStrategy renderingStrategy; + protected final @Nullable String alias; + protected final @Nullable String typeHandler; + protected final @Nullable RenderingStrategy renderingStrategy; protected final ParameterTypeConverter<T, ?> parameterTypeConverter; - protected final String tableQualifier; - protected final Class<T> javaType; + protected final @Nullable String tableQualifier; + protected final @Nullable Class<T> javaType; private SqlColumn(Builder<T> builder) { name = Objects.requireNonNull(builder.name); @@ -80,7 +80,7 @@ public Optional<Class<T>> javaType() { } @Override - public Object convertParameterType(T value) { + public @Nullable Object convertParameterType(@Nullable T value) { return parameterTypeConverter.convert(value); } @@ -144,25 +144,21 @@ public Optional<RenderingStrategy> renderingStrategy() { return Optional.ofNullable(renderingStrategy); } - @NotNull public <S> SqlColumn<S> withTypeHandler(String typeHandler) { Builder<S> b = copy(); return b.withTypeHandler(typeHandler).build(); } - @NotNull public <S> SqlColumn<S> withRenderingStrategy(RenderingStrategy renderingStrategy) { Builder<S> b = copy(); return b.withRenderingStrategy(renderingStrategy).build(); } - @NotNull public <S> SqlColumn<S> withParameterTypeConverter(ParameterTypeConverter<S, ?> parameterTypeConverter) { Builder<S> b = copy(); return b.withParameterTypeConverter(parameterTypeConverter).build(); } - @NotNull public <S> SqlColumn<S> withJavaType(Class<S> javaType) { Builder<S> b = copy(); return b.withJavaType(javaType).build(); @@ -206,16 +202,16 @@ public static <T> SqlColumn<T> of(String name, SqlTable table, JDBCType jdbcType } public static class Builder<T> { - protected String name; - protected SqlTable table; - protected JDBCType jdbcType; + protected @Nullable String name; + protected @Nullable SqlTable table; + protected @Nullable JDBCType jdbcType; protected String descendingPhrase = ""; //$NON-NLS-1$ - protected String alias; - protected String typeHandler; - protected RenderingStrategy renderingStrategy; + protected @Nullable String alias; + protected @Nullable String typeHandler; + protected @Nullable RenderingStrategy renderingStrategy; protected ParameterTypeConverter<T, ?> parameterTypeConverter = v -> v; - protected String tableQualifier; - protected Class<T> javaType; + protected @Nullable String tableQualifier; + protected @Nullable Class<T> javaType; public Builder<T> withName(String name) { this.name = name; @@ -227,7 +223,7 @@ public Builder<T> withTable(SqlTable table) { return this; } - public Builder<T> withJdbcType(JDBCType jdbcType) { + public Builder<T> withJdbcType(@Nullable JDBCType jdbcType) { this.jdbcType = jdbcType; return this; } @@ -237,17 +233,17 @@ public Builder<T> withDescendingPhrase(String descendingPhrase) { return this; } - public Builder<T> withAlias(String alias) { + public Builder<T> withAlias(@Nullable String alias) { this.alias = alias; return this; } - public Builder<T> withTypeHandler(String typeHandler) { + public Builder<T> withTypeHandler(@Nullable String typeHandler) { this.typeHandler = typeHandler; return this; } - public Builder<T> withRenderingStrategy(RenderingStrategy renderingStrategy) { + public Builder<T> withRenderingStrategy(@Nullable RenderingStrategy renderingStrategy) { this.renderingStrategy = renderingStrategy; return this; } @@ -257,12 +253,12 @@ public Builder<T> withParameterTypeConverter(ParameterTypeConverter<T, ?> parame return this; } - private Builder<T> withTableQualifier(String tableQualifier) { + private Builder<T> withTableQualifier(@Nullable String tableQualifier) { this.tableQualifier = tableQualifier; return this; } - public Builder<T> withJavaType(Class<T> javaType) { + public Builder<T> withJavaType(@Nullable Class<T> javaType) { this.javaType = javaType; return this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlTable.java b/src/main/java/org/mybatis/dynamic/sql/SqlTable.java index ac3665532..fab3d8c2a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlTable.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlTable.java @@ -19,8 +19,6 @@ import java.util.Objects; import java.util.Optional; -import org.jetbrains.annotations.NotNull; - public class SqlTable implements TableExpression { protected String tableName; @@ -37,17 +35,14 @@ public BasicColumn allColumns() { return SqlColumn.of("*", this); //$NON-NLS-1$ } - @NotNull public <T> SqlColumn<T> column(String name) { return SqlColumn.of(name, this); } - @NotNull public <T> SqlColumn<T> column(String name, JDBCType jdbcType) { return SqlColumn.of(name, this, jdbcType); } - @NotNull public <T> SqlColumn<T> column(String name, JDBCType jdbcType, String typeHandler) { SqlColumn<T> column = SqlColumn.of(name, this, jdbcType); return column.withTypeHandler(typeHandler); diff --git a/src/main/java/org/mybatis/dynamic/sql/StringConstant.java b/src/main/java/org/mybatis/dynamic/sql/StringConstant.java index 0187bb1fa..ae9f0a75b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/StringConstant.java +++ b/src/main/java/org/mybatis/dynamic/sql/StringConstant.java @@ -18,20 +18,21 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.StringUtilities; public class StringConstant implements BindableColumn<String> { - private final String alias; + private final @Nullable String alias; private final String value; private StringConstant(String value) { this(value, null); } - private StringConstant(String value, String alias) { + private StringConstant(String value, @Nullable String alias) { this.value = Objects.requireNonNull(value); this.alias = alias; } diff --git a/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionDSL.java index d2acdde2e..c671b39a9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionDSL.java @@ -19,7 +19,7 @@ import java.util.Arrays; import java.util.List; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AndOrCriteriaGroup; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.ColumnAndConditionCriterion; @@ -31,86 +31,72 @@ import org.mybatis.dynamic.sql.util.Validator; public abstract class AbstractBooleanExpressionDSL<T extends AbstractBooleanExpressionDSL<T>> { - private SqlCriterion initialCriterion; // WARNING - may be null! + private @Nullable SqlCriterion initialCriterion; protected final List<AndOrCriteriaGroup> subCriteria = new ArrayList<>(); - @NotNull public <S> T and(BindableColumn<S> column, VisitableCondition<S> condition, AndOrCriteriaGroup... subCriteria) { return and(column, condition, Arrays.asList(subCriteria)); } - @NotNull public <S> T and(BindableColumn<S> column, VisitableCondition<S> condition, List<AndOrCriteriaGroup> subCriteria) { addSubCriteria("and", buildCriterion(column, condition), subCriteria); //$NON-NLS-1$ return getThis(); } - @NotNull public T and(ExistsPredicate existsPredicate, AndOrCriteriaGroup... subCriteria) { return and(existsPredicate, Arrays.asList(subCriteria)); } - @NotNull public T and(ExistsPredicate existsPredicate, List<AndOrCriteriaGroup> subCriteria) { addSubCriteria("and", buildCriterion(existsPredicate), subCriteria); //$NON-NLS-1$ return getThis(); } - @NotNull public T and(SqlCriterion initialCriterion, AndOrCriteriaGroup... subCriteria) { return and(initialCriterion, Arrays.asList(subCriteria)); } - @NotNull public T and(SqlCriterion initialCriterion, List<AndOrCriteriaGroup> subCriteria) { addSubCriteria("and", buildCriterion(initialCriterion), subCriteria); //$NON-NLS-1$ return getThis(); } - @NotNull public T and(List<AndOrCriteriaGroup> criteria) { addSubCriteria("and", criteria); //$NON-NLS-1$ return getThis(); } - @NotNull public <S> T or(BindableColumn<S> column, VisitableCondition<S> condition, AndOrCriteriaGroup... subCriteria) { return or(column, condition, Arrays.asList(subCriteria)); } - @NotNull public <S> T or(BindableColumn<S> column, VisitableCondition<S> condition, List<AndOrCriteriaGroup> subCriteria) { addSubCriteria("or", buildCriterion(column, condition), subCriteria); //$NON-NLS-1$ return getThis(); } - @NotNull public T or(ExistsPredicate existsPredicate, AndOrCriteriaGroup... subCriteria) { return or(existsPredicate, Arrays.asList(subCriteria)); } - @NotNull public T or(ExistsPredicate existsPredicate, List<AndOrCriteriaGroup> subCriteria) { addSubCriteria("or", buildCriterion(existsPredicate), subCriteria); //$NON-NLS-1$ return getThis(); } - @NotNull public T or(SqlCriterion initialCriterion, AndOrCriteriaGroup... subCriteria) { return or(initialCriterion, Arrays.asList(subCriteria)); } - @NotNull public T or(SqlCriterion initialCriterion, List<AndOrCriteriaGroup> subCriteria) { addSubCriteria("or", buildCriterion(initialCriterion), subCriteria); //$NON-NLS-1$ return getThis(); } - @NotNull public T or(List<AndOrCriteriaGroup> criteria) { addSubCriteria("or", criteria); //$NON-NLS-1$ return getThis(); @@ -144,17 +130,16 @@ private void addSubCriteria(String connector, List<AndOrCriteriaGroup> criteria) .build()); } - protected void setInitialCriterion(SqlCriterion initialCriterion) { + protected void setInitialCriterion(@Nullable SqlCriterion initialCriterion) { this.initialCriterion = initialCriterion; } - protected void setInitialCriterion(SqlCriterion initialCriterion, StatementType statementType) { + protected void setInitialCriterion(@Nullable SqlCriterion initialCriterion, StatementType statementType) { Validator.assertTrue(this.initialCriterion == null, statementType.messageNumber()); setInitialCriterion(initialCriterion); } - // may be null! - protected SqlCriterion getInitialCriterion() { + protected @Nullable SqlCriterion getInitialCriterion() { return initialCriterion; } diff --git a/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionModel.java b/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionModel.java index 0112c4555..edda8707f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionModel.java @@ -20,11 +20,12 @@ import java.util.List; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AndOrCriteriaGroup; import org.mybatis.dynamic.sql.SqlCriterion; public abstract class AbstractBooleanExpressionModel { - private final SqlCriterion initialCriterion; + private final @Nullable SqlCriterion initialCriterion; private final List<AndOrCriteriaGroup> subCriteria ; protected AbstractBooleanExpressionModel(AbstractBuilder<?> builder) { @@ -41,10 +42,10 @@ public List<AndOrCriteriaGroup> subCriteria() { } public abstract static class AbstractBuilder<T extends AbstractBuilder<T>> { - private SqlCriterion initialCriterion; + private @Nullable SqlCriterion initialCriterion; private final List<AndOrCriteriaGroup> subCriteria = new ArrayList<>(); - public T withInitialCriterion(SqlCriterion initialCriterion) { + public T withInitialCriterion(@Nullable SqlCriterion initialCriterion) { this.initialCriterion = initialCriterion; return getThis(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionRenderer.java index 8ba9d7dce..a006b1834 100644 --- a/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionRenderer.java @@ -21,6 +21,7 @@ import java.util.Optional; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlCriterion; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; @@ -84,7 +85,7 @@ private String addPrefix(String fragment) { public abstract static class AbstractBuilder<B extends AbstractBuilder<B>> { private final AbstractBooleanExpressionModel model; - private RenderingContext renderingContext; + private @Nullable RenderingContext renderingContext; protected AbstractBuilder(AbstractBooleanExpressionModel model) { this.model = model; diff --git a/src/main/java/org/mybatis/dynamic/sql/common/CommonBuilder.java b/src/main/java/org/mybatis/dynamic/sql/common/CommonBuilder.java index b8a9a9a52..269b857af 100644 --- a/src/main/java/org/mybatis/dynamic/sql/common/CommonBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/common/CommonBuilder.java @@ -15,6 +15,7 @@ */ package org.mybatis.dynamic.sql.common; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; import org.mybatis.dynamic.sql.where.EmbeddedWhereModel; @@ -25,34 +26,34 @@ * @param <T> type of the implementing builder */ public abstract class CommonBuilder<T extends CommonBuilder<T>> { - private SqlTable table; - private String tableAlias; - private EmbeddedWhereModel whereModel; - private Long limit; - private OrderByModel orderByModel; - private StatementConfiguration statementConfiguration; + private @Nullable SqlTable table; + private @Nullable String tableAlias; + private @Nullable EmbeddedWhereModel whereModel; + private @Nullable Long limit; + private @Nullable OrderByModel orderByModel; + private @Nullable StatementConfiguration statementConfiguration; - public SqlTable table() { + public @Nullable SqlTable table() { return table; } - public String tableAlias() { + public @Nullable String tableAlias() { return tableAlias; } - public EmbeddedWhereModel whereModel() { + public @Nullable EmbeddedWhereModel whereModel() { return whereModel; } - public Long limit() { + public @Nullable Long limit() { return limit; } - public OrderByModel orderByModel() { + public @Nullable OrderByModel orderByModel() { return orderByModel; } - public StatementConfiguration statementConfiguration() { + public @Nullable StatementConfiguration statementConfiguration() { return statementConfiguration; } @@ -61,22 +62,22 @@ public T withTable(SqlTable table) { return getThis(); } - public T withTableAlias(String tableAlias) { + public T withTableAlias(@Nullable String tableAlias) { this.tableAlias = tableAlias; return getThis(); } - public T withWhereModel(EmbeddedWhereModel whereModel) { + public T withWhereModel(@Nullable EmbeddedWhereModel whereModel) { this.whereModel = whereModel; return getThis(); } - public T withLimit(Long limit) { + public T withLimit(@Nullable Long limit) { this.limit = limit; return getThis(); } - public T withOrderByModel(OrderByModel orderByModel) { + public T withOrderByModel(@Nullable OrderByModel orderByModel) { this.orderByModel = orderByModel; return getThis(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/common/package-info.java b/src/main/java/org/mybatis/dynamic/sql/common/package-info.java new file mode 100644 index 000000000..f581c8034 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/common/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.common; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/configuration/GlobalConfiguration.java b/src/main/java/org/mybatis/dynamic/sql/configuration/GlobalConfiguration.java index 8e7fd2eba..670ddd935 100644 --- a/src/main/java/org/mybatis/dynamic/sql/configuration/GlobalConfiguration.java +++ b/src/main/java/org/mybatis/dynamic/sql/configuration/GlobalConfiguration.java @@ -17,6 +17,7 @@ import java.io.IOException; import java.io.InputStream; +import java.util.Objects; import java.util.Properties; import org.mybatis.dynamic.sql.exception.DynamicSqlException; @@ -47,11 +48,7 @@ private void initializeProperties() { private String getConfigurationFileName() { String property = System.getProperty(CONFIGURATION_FILE_PROPERTY); - if (property == null) { - return DEFAULT_PROPERTY_FILE; - } else { - return property; - } + return Objects.requireNonNullElse(property, DEFAULT_PROPERTY_FILE); } void loadProperties(InputStream inputStream, String propertyFile) { diff --git a/src/main/java/org/mybatis/dynamic/sql/configuration/package-info.java b/src/main/java/org/mybatis/dynamic/sql/configuration/package-info.java new file mode 100644 index 000000000..41fcac6c7 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/configuration/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.configuration; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java index 2ea176c53..8dda9b10c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java @@ -21,7 +21,7 @@ import java.util.function.Consumer; import java.util.function.Function; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SortSpecification; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.common.OrderByModel; @@ -37,13 +37,13 @@ public class DeleteDSL<R> implements AbstractWhereStarter<DeleteDSL<R>.DeleteWhe private final Function<DeleteModel, R> adapterFunction; private final SqlTable table; - private final String tableAlias; - private DeleteWhereBuilder whereBuilder; + private final @Nullable String tableAlias; + private @Nullable DeleteWhereBuilder whereBuilder; private final StatementConfiguration statementConfiguration = new StatementConfiguration(); - private Long limit; - private OrderByModel orderByModel; + private @Nullable Long limit; + private @Nullable OrderByModel orderByModel; - private DeleteDSL(SqlTable table, String tableAlias, Function<DeleteModel, R> adapterFunction) { + private DeleteDSL(SqlTable table, @Nullable String tableAlias, Function<DeleteModel, R> adapterFunction) { this.table = Objects.requireNonNull(table); this.tableAlias = tableAlias; this.adapterFunction = Objects.requireNonNull(adapterFunction); @@ -59,7 +59,7 @@ public DeleteDSL<R> limit(long limit) { return limitWhenPresent(limit); } - public DeleteDSL<R> limitWhenPresent(Long limit) { + public DeleteDSL<R> limitWhenPresent(@Nullable Long limit) { this.limit = limit; return this; } @@ -79,7 +79,6 @@ public DeleteDSL<R> orderBy(Collection<? extends SortSpecification> columns) { * * @return the model class */ - @NotNull @Override public R build() { DeleteModel deleteModel = DeleteModel.withTable(table) @@ -100,7 +99,7 @@ public DeleteDSL<R> configureStatement(Consumer<StatementConfiguration> consumer } public static <R> DeleteDSL<R> deleteFrom(Function<DeleteModel, R> adapterFunction, SqlTable table, - String tableAlias) { + @Nullable String tableAlias) { return new DeleteDSL<>(table, tableAlias, adapterFunction); } @@ -135,7 +134,6 @@ public DeleteDSL<R> orderBy(Collection<? extends SortSpecification> columns) { return DeleteDSL.this; } - @NotNull @Override public R build() { return DeleteDSL.this.build(); diff --git a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java index d8f4d0e07..1f9dc606f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteModel.java @@ -18,7 +18,7 @@ import java.util.Objects; import java.util.Optional; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.common.CommonBuilder; import org.mybatis.dynamic.sql.common.OrderByModel; @@ -30,10 +30,10 @@ public class DeleteModel { private final SqlTable table; - private final String tableAlias; - private final EmbeddedWhereModel whereModel; - private final Long limit; - private final OrderByModel orderByModel; + private final @Nullable String tableAlias; + private final @Nullable EmbeddedWhereModel whereModel; + private final @Nullable Long limit; + private final @Nullable OrderByModel orderByModel; private final StatementConfiguration statementConfiguration; private DeleteModel(Builder builder) { @@ -69,7 +69,6 @@ public StatementConfiguration statementConfiguration() { return statementConfiguration; } - @NotNull public DeleteStatementProvider render(RenderingStrategy renderingStrategy) { return DeleteRenderer.withDeleteModel(this) .withRenderingStrategy(renderingStrategy) diff --git a/src/main/java/org/mybatis/dynamic/sql/delete/package-info.java b/src/main/java/org/mybatis/dynamic/sql/delete/package-info.java new file mode 100644 index 000000000..a7bfc9d26 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/delete/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.delete; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/delete/render/DefaultDeleteStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/delete/render/DefaultDeleteStatementProvider.java index 31ffc53f0..db5feef01 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/render/DefaultDeleteStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/render/DefaultDeleteStatementProvider.java @@ -19,6 +19,8 @@ import java.util.Map; import java.util.Objects; +import org.jspecify.annotations.Nullable; + public class DefaultDeleteStatementProvider implements DeleteStatementProvider { private final String deleteStatement; private final Map<String, Object> parameters; @@ -43,7 +45,7 @@ public static Builder withDeleteStatement(String deleteStatement) { } public static class Builder { - private String deleteStatement; + private @Nullable String deleteStatement; private final Map<String, Object> parameters = new HashMap<>(); public Builder withDeleteStatement(String deleteStatement) { 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 4671e4d79..d65fcdd58 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 @@ -19,6 +19,7 @@ import java.util.Optional; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.common.OrderByRenderer; import org.mybatis.dynamic.sql.delete.DeleteModel; @@ -103,8 +104,8 @@ public static Builder withDeleteModel(DeleteModel deleteModel) { } public static class Builder { - private DeleteModel deleteModel; - private RenderingStrategy renderingStrategy; + private @Nullable DeleteModel deleteModel; + private @Nullable RenderingStrategy renderingStrategy; public Builder withDeleteModel(DeleteModel deleteModel) { this.deleteModel = deleteModel; diff --git a/src/main/java/org/mybatis/dynamic/sql/delete/render/package-info.java b/src/main/java/org/mybatis/dynamic/sql/delete/render/package-info.java new file mode 100644 index 000000000..8b25d555d --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/delete/render/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.delete.render; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/exception/package-info.java b/src/main/java/org/mybatis/dynamic/sql/exception/package-info.java new file mode 100644 index 000000000..4e802e370 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/exception/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.exception; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/AbstractMultiRowInsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/AbstractMultiRowInsertModel.java index b4bdb7eab..4fc8a3b4d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/AbstractMultiRowInsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/AbstractMultiRowInsertModel.java @@ -22,6 +22,7 @@ import java.util.Objects; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.util.AbstractColumnMapping; @@ -53,7 +54,7 @@ public int recordCount() { } public abstract static class AbstractBuilder<T, S extends AbstractBuilder<T, S>> { - private SqlTable table; + private @Nullable SqlTable table; private final List<T> records = new ArrayList<>(); private final List<AbstractColumnMapping> columnMappings = new ArrayList<>(); diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java index 8c8344929..71bc350d6 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertDSL.java @@ -21,7 +21,7 @@ import java.util.List; import java.util.Objects; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.util.AbstractColumnMapping; @@ -48,7 +48,6 @@ public <F> ColumnMappingFinisher<F> map(SqlColumn<F> column) { return new ColumnMappingFinisher<>(column); } - @NotNull @Override public BatchInsertModel<T> build() { return BatchInsertModel.withRecords(records) @@ -113,7 +112,7 @@ public BatchInsertDSL<T> toRow() { public abstract static class AbstractBuilder<T, B extends AbstractBuilder<T, B>> { final Collection<T> records = new ArrayList<>(); - SqlTable table; + @Nullable SqlTable table; final List<AbstractColumnMapping> columnMappings = new ArrayList<>(); public B withRecords(Collection<T> records) { diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java index 4e85d5951..275ce2745 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/BatchInsertModel.java @@ -17,7 +17,6 @@ import java.util.Collection; -import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.insert.render.BatchInsert; import org.mybatis.dynamic.sql.insert.render.BatchInsertRenderer; import org.mybatis.dynamic.sql.render.RenderingStrategy; @@ -31,7 +30,6 @@ private BatchInsertModel(Builder<T> builder) { Validator.assertNotEmpty(columnMappings, "ERROR.5"); //$NON-NLS-1$ } - @NotNull public BatchInsert<T> render(RenderingStrategy renderingStrategy) { return BatchInsertRenderer.withBatchInsertModel(this) .withRenderingStrategy(renderingStrategy) diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertDSL.java index 18e05a1d1..327e5d103 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertDSL.java @@ -21,7 +21,7 @@ import java.util.Objects; import java.util.function.Supplier; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; @@ -47,7 +47,6 @@ public <T> SetClauseFinisher<T> set(SqlColumn<T> column) { return new SetClauseFinisher<>(column); } - @NotNull @Override public GeneralInsertModel build() { return new GeneralInsertModel.Builder() @@ -114,7 +113,7 @@ public GeneralInsertDSL toValueWhenPresent(Supplier<T> valueSupplier) { public static class Builder { private final List<AbstractColumnMapping> columnMappings = new ArrayList<>(); - private SqlTable table; + private @Nullable SqlTable table; public Builder withTable(SqlTable table) { this.table = table; diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java index 4a9de2270..873c98f5f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertModel.java @@ -20,7 +20,7 @@ import java.util.Objects; import java.util.stream.Stream; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; import org.mybatis.dynamic.sql.insert.render.GeneralInsertRenderer; @@ -54,7 +54,6 @@ public StatementConfiguration statementConfiguration() { return statementConfiguration; } - @NotNull public GeneralInsertStatementProvider render(RenderingStrategy renderingStrategy) { return GeneralInsertRenderer.withInsertModel(this) .withRenderingStrategy(renderingStrategy) @@ -63,9 +62,9 @@ public GeneralInsertStatementProvider render(RenderingStrategy renderingStrategy } public static class Builder { - private SqlTable table; + private @Nullable SqlTable table; private final List<AbstractColumnMapping> insertMappings = new ArrayList<>(); - private StatementConfiguration statementConfiguration; + private @Nullable StatementConfiguration statementConfiguration; public Builder withTable(SqlTable table) { this.table = table; diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/InsertDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/InsertDSL.java index e2fbb49b5..d622ced8c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/InsertDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/InsertDSL.java @@ -21,7 +21,7 @@ import java.util.Objects; import java.util.function.Supplier; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.util.AbstractColumnMapping; @@ -49,7 +49,6 @@ public <F> ColumnMappingFinisher<F> map(SqlColumn<F> column) { return new ColumnMappingFinisher<>(column); } - @NotNull @Override public InsertModel<T> build() { return InsertModel.withRow(row) @@ -113,8 +112,8 @@ public InsertDSL<T> toRow() { } public static class Builder<T> { - private T row; - private SqlTable table; + private @Nullable T row; + private @Nullable SqlTable table; private final List<AbstractColumnMapping> columnMappings = new ArrayList<>(); public Builder<T> withRow(T row) { diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/InsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/InsertModel.java index a0d451358..4495e32fd 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/InsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/InsertModel.java @@ -20,7 +20,7 @@ import java.util.Objects; import java.util.stream.Stream; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.insert.render.InsertRenderer; import org.mybatis.dynamic.sql.insert.render.InsertStatementProvider; @@ -52,7 +52,6 @@ public SqlTable table() { return table; } - @NotNull public InsertStatementProvider<T> render(RenderingStrategy renderingStrategy) { return InsertRenderer.withInsertModel(this) .withRenderingStrategy(renderingStrategy) @@ -65,8 +64,8 @@ public static <T> Builder<T> withRow(T row) { } public static class Builder<T> { - private SqlTable table; - private T row; + private @Nullable SqlTable table; + private @Nullable T row; private final List<AbstractColumnMapping> columnMappings = new ArrayList<>(); public Builder<T> withTable(SqlTable table) { diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectDSL.java index 5e071d169..e7f8b5e09 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectDSL.java @@ -20,7 +20,7 @@ import java.util.Objects; import java.util.function.Consumer; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; @@ -31,7 +31,7 @@ public class InsertSelectDSL implements Buildable<InsertSelectModel>, ConfigurableStatement<InsertSelectDSL> { private final SqlTable table; - private final InsertColumnListModel columnList; + private final @Nullable InsertColumnListModel columnList; private final SelectModel selectModel; private final StatementConfiguration statementConfiguration = new StatementConfiguration(); @@ -47,7 +47,6 @@ private InsertSelectDSL(SqlTable table, SelectModel selectModel) { this.columnList = null; } - @NotNull @Override public InsertSelectModel build() { return InsertSelectModel.withTable(table) diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java index 25d01b7de..36051700c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/InsertSelectModel.java @@ -18,7 +18,7 @@ import java.util.Objects; import java.util.Optional; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; import org.mybatis.dynamic.sql.insert.render.InsertSelectRenderer; @@ -28,7 +28,7 @@ public class InsertSelectModel { private final SqlTable table; - private final InsertColumnListModel columnList; + private final @Nullable InsertColumnListModel columnList; private final SelectModel selectModel; private final StatementConfiguration statementConfiguration; @@ -55,7 +55,6 @@ public StatementConfiguration statementConfiguration() { return statementConfiguration; } - @NotNull public InsertSelectStatementProvider render(RenderingStrategy renderingStrategy) { return InsertSelectRenderer.withInsertSelectModel(this) .withRenderingStrategy(renderingStrategy) @@ -68,17 +67,17 @@ public static Builder withTable(SqlTable table) { } public static class Builder { - private SqlTable table; - private InsertColumnListModel columnList; - private SelectModel selectModel; - private StatementConfiguration statementConfiguration; + private @Nullable SqlTable table; + private @Nullable InsertColumnListModel columnList; + private @Nullable SelectModel selectModel; + private @Nullable StatementConfiguration statementConfiguration; public Builder withTable(SqlTable table) { this.table = table; return this; } - public Builder withColumnList(InsertColumnListModel columnList) { + public Builder withColumnList(@Nullable InsertColumnListModel columnList) { this.columnList = columnList; return this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java index b29684a4f..8e5f30e49 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertDSL.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.Objects; -import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.util.AbstractColumnMapping; @@ -47,7 +46,6 @@ public <F> ColumnMappingFinisher<F> map(SqlColumn<F> column) { return new ColumnMappingFinisher<>(column); } - @NotNull @Override public MultiRowInsertModel<T> build() { return MultiRowInsertModel.withRecords(records) diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertModel.java index 3b380ca66..435267652 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/MultiRowInsertModel.java @@ -17,7 +17,6 @@ import java.util.Collection; -import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.insert.render.MultiRowInsertRenderer; import org.mybatis.dynamic.sql.insert.render.MultiRowInsertStatementProvider; import org.mybatis.dynamic.sql.render.RenderingStrategy; @@ -31,7 +30,6 @@ private MultiRowInsertModel(Builder<T> builder) { Validator.assertNotEmpty(columnMappings, "ERROR.8"); //$NON-NLS-1$ } - @NotNull public MultiRowInsertStatementProvider<T> render(RenderingStrategy renderingStrategy) { return MultiRowInsertRenderer.withMultiRowInsertModel(this) .withRenderingStrategy(renderingStrategy) diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/package-info.java b/src/main/java/org/mybatis/dynamic/sql/insert/package-info.java new file mode 100644 index 000000000..5ef9f74ea --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/insert/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.insert; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsert.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsert.java index 5272a0ba0..8af9e30fe 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsert.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/BatchInsert.java @@ -20,6 +20,8 @@ import java.util.List; import java.util.Objects; +import org.jspecify.annotations.Nullable; + public class BatchInsert<T> { private final String insertStatement; private final List<T> records; @@ -64,7 +66,7 @@ public static <T> Builder<T> withRecords(List<T> records) { } public static class Builder<T> { - private String insertStatement; + private @Nullable String insertStatement; private final List<T> records = new ArrayList<>(); public Builder<T> withInsertStatement(String insertStatement) { 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 48d5f5eea..875820c02 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 @@ -17,6 +17,7 @@ import java.util.Objects; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.insert.BatchInsertModel; import org.mybatis.dynamic.sql.render.RenderingStrategy; @@ -27,7 +28,8 @@ public class BatchInsertRenderer<T> { private BatchInsertRenderer(Builder<T> builder) { model = Objects.requireNonNull(builder.model); - visitor = new MultiRowValuePhraseVisitor(builder.renderingStrategy, "row"); //$NON-NLS-1$) + visitor = new MultiRowValuePhraseVisitor(Objects.requireNonNull(builder.renderingStrategy), + "row"); //$NON-NLS-1$) } public BatchInsert<T> render() { @@ -47,8 +49,8 @@ public static <T> Builder<T> withBatchInsertModel(BatchInsertModel<T> model) { } public static class Builder<T> { - private BatchInsertModel<T> model; - private RenderingStrategy renderingStrategy; + private @Nullable BatchInsertModel<T> model; + private @Nullable RenderingStrategy renderingStrategy; public Builder<T> withBatchInsertModel(BatchInsertModel<T> model) { this.model = model; diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultGeneralInsertStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultGeneralInsertStatementProvider.java index 94b3eac7a..eaa3d0911 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultGeneralInsertStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultGeneralInsertStatementProvider.java @@ -19,6 +19,8 @@ import java.util.Map; import java.util.Objects; +import org.jspecify.annotations.Nullable; + public class DefaultGeneralInsertStatementProvider implements GeneralInsertStatementProvider, InsertSelectStatementProvider { private final String insertStatement; @@ -44,7 +46,7 @@ public static Builder withInsertStatement(String insertStatement) { } public static class Builder { - private String insertStatement; + private @Nullable String insertStatement; private final Map<String, Object> parameters = new HashMap<>(); public Builder withInsertStatement(String insertStatement) { diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultInsertStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultInsertStatementProvider.java index d45f9f956..a16967456 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultInsertStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultInsertStatementProvider.java @@ -17,7 +17,7 @@ import java.util.Objects; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; public class DefaultInsertStatementProvider<T> implements InsertStatementProvider<T> { private final String insertStatement; @@ -29,7 +29,6 @@ private DefaultInsertStatementProvider(Builder<T> builder) { } @Override - @NotNull public T getRow() { return row; } @@ -44,8 +43,8 @@ public static <T> Builder<T> withRow(T row) { } public static class Builder<T> { - private String insertStatement; - private T row; + private @Nullable String insertStatement; + private @Nullable T row; public Builder<T> withInsertStatement(String insertStatement) { this.insertStatement = insertStatement; diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultMultiRowInsertStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultMultiRowInsertStatementProvider.java index f1395ecd9..db8c9f489 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultMultiRowInsertStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/DefaultMultiRowInsertStatementProvider.java @@ -20,6 +20,8 @@ import java.util.List; import java.util.Objects; +import org.jspecify.annotations.Nullable; + public class DefaultMultiRowInsertStatementProvider<T> implements MultiRowInsertStatementProvider<T> { private final List<T> records; @@ -42,7 +44,7 @@ public List<T> getRecords() { public static class Builder<T> { private final List<T> records = new ArrayList<>(); - private String insertStatement; + private @Nullable String insertStatement; public Builder<T> withRecords(List<T> records) { this.records.addAll(records); diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueAndParameters.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueAndParameters.java index 1ec27d5a5..2f98f0c3d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueAndParameters.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueAndParameters.java @@ -20,6 +20,8 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; + public class FieldAndValueAndParameters { private final String fieldName; private final String valuePhrase; @@ -48,8 +50,8 @@ public static Builder withFieldName(String fieldName) { } public static class Builder { - private String fieldName; - private String valuePhrase; + private @Nullable String fieldName; + private @Nullable String valuePhrase; private final Map<String, Object> parameters = new HashMap<>(); public Builder withFieldName(String fieldName) { @@ -62,7 +64,8 @@ public Builder withValuePhrase(String valuePhrase) { return this; } - public Builder withParameter(String key, Object value) { + public Builder withParameter(String key, @Nullable Object value) { + //noinspection DataFlowIssue parameters.put(key, value); return this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertRenderer.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertRenderer.java index 8dfe89d4e..08eddb54f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertRenderer.java @@ -18,6 +18,7 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.insert.GeneralInsertModel; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.render.RenderingStrategy; @@ -30,7 +31,8 @@ public class GeneralInsertRenderer { private GeneralInsertRenderer(Builder builder) { model = Objects.requireNonNull(builder.model); - RenderingContext renderingContext = RenderingContext.withRenderingStrategy(builder.renderingStrategy) + RenderingContext renderingContext = RenderingContext + .withRenderingStrategy(Objects.requireNonNull(builder.renderingStrategy)) .withStatementConfiguration(model.statementConfiguration()) .build(); visitor = new GeneralInsertValuePhraseVisitor(renderingContext); @@ -56,8 +58,8 @@ public static Builder withInsertModel(GeneralInsertModel model) { } public static class Builder { - private GeneralInsertModel model; - private RenderingStrategy renderingStrategy; + private @Nullable GeneralInsertModel model; + private @Nullable RenderingStrategy renderingStrategy; public Builder withInsertModel(GeneralInsertModel model) { this.model = model; diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertValuePhraseVisitor.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertValuePhraseVisitor.java index 30897e86f..914d710cf 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertValuePhraseVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/GeneralInsertValuePhraseVisitor.java @@ -18,6 +18,7 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.render.RenderedParameterInfo; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.AbstractColumnMapping; @@ -74,7 +75,7 @@ public <T> Optional<FieldAndValueAndParameters> visit(ValueWhenPresentMapping<T> } private Optional<FieldAndValueAndParameters> buildValueFragment(AbstractColumnMapping mapping, - Object value) { + @Nullable Object value) { return buildFragment(mapping, value); } @@ -84,7 +85,7 @@ private Optional<FieldAndValueAndParameters> buildNullFragment(AbstractColumnMap .buildOptional(); } - private Optional<FieldAndValueAndParameters> buildFragment(AbstractColumnMapping mapping, Object value) { + private Optional<FieldAndValueAndParameters> buildFragment(AbstractColumnMapping mapping, @Nullable Object value) { RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo(mapping.column()); return FieldAndValueAndParameters.withFieldName(mapping.columnName()) 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 f3f67c062..9ff5858be 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 @@ -18,6 +18,7 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.insert.InsertModel; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.util.Validator; @@ -29,7 +30,7 @@ public class InsertRenderer<T> { private InsertRenderer(Builder<T> builder) { model = Objects.requireNonNull(builder.model); - visitor = new ValuePhraseVisitor(builder.renderingStrategy); + visitor = new ValuePhraseVisitor(Objects.requireNonNull(builder.renderingStrategy)); } public InsertStatementProvider<T> render() { @@ -52,8 +53,8 @@ public static <T> Builder<T> withInsertModel(InsertModel<T> model) { } public static class Builder<T> { - private InsertModel<T> model; - private RenderingStrategy renderingStrategy; + private @Nullable InsertModel<T> model; + private @Nullable RenderingStrategy renderingStrategy; public Builder<T> withInsertModel(InsertModel<T> model) { this.model = model; 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 909f1c418..7740309bd 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 @@ -20,6 +20,7 @@ import java.util.Objects; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.insert.InsertColumnListModel; import org.mybatis.dynamic.sql.insert.InsertSelectModel; @@ -35,7 +36,7 @@ public class InsertSelectRenderer { private InsertSelectRenderer(Builder builder) { model = Objects.requireNonNull(builder.model); - renderingContext = RenderingContext.withRenderingStrategy(builder.renderingStrategy) + renderingContext = RenderingContext.withRenderingStrategy(Objects.requireNonNull(builder.renderingStrategy)) .withStatementConfiguration(model.statementConfiguration()) .build(); } @@ -71,8 +72,8 @@ public static Builder withInsertSelectModel(InsertSelectModel model) { } public static class Builder { - private InsertSelectModel model; - private RenderingStrategy renderingStrategy; + private @Nullable InsertSelectModel model; + private @Nullable RenderingStrategy renderingStrategy; public Builder withInsertSelectModel(InsertSelectModel model) { this.model = model; diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertStatementProvider.java index f68fb1db3..bd40a0e1f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/InsertStatementProvider.java @@ -15,15 +15,12 @@ */ package org.mybatis.dynamic.sql.insert.render; -import org.jetbrains.annotations.NotNull; - public interface InsertStatementProvider<T> { /** * Return the row associated with this insert statement. * * @return the row associated with this insert statement. */ - @NotNull T getRow(); /** diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowInsertRenderer.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowInsertRenderer.java index 21da95cca..5f3146a77 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowInsertRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowInsertRenderer.java @@ -19,6 +19,7 @@ import java.util.Objects; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.insert.MultiRowInsertModel; import org.mybatis.dynamic.sql.render.RenderingStrategy; @@ -30,7 +31,8 @@ public class MultiRowInsertRenderer<T> { private MultiRowInsertRenderer(Builder<T> builder) { model = Objects.requireNonNull(builder.model); // the prefix is a generic format that will be resolved below with String.format(...) - visitor = new MultiRowValuePhraseVisitor(builder.renderingStrategy, "records[%s]"); //$NON-NLS-1$ + visitor = new MultiRowValuePhraseVisitor(Objects.requireNonNull(builder.renderingStrategy), + "records[%s]"); //$NON-NLS-1$ } public MultiRowInsertStatementProvider<T> render() { @@ -58,8 +60,8 @@ public static <T> Builder<T> withMultiRowInsertModel(MultiRowInsertModel<T> mode } public static class Builder<T> { - private MultiRowInsertModel<T> model; - private RenderingStrategy renderingStrategy; + private @Nullable MultiRowInsertModel<T> model; + private @Nullable RenderingStrategy renderingStrategy; public Builder<T> withMultiRowInsertModel(MultiRowInsertModel<T> model) { this.model = model; diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowValuePhraseVisitor.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowValuePhraseVisitor.java index 639248c3e..ba2d2ffa5 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowValuePhraseVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/MultiRowValuePhraseVisitor.java @@ -15,8 +15,6 @@ */ package org.mybatis.dynamic.sql.insert.render; -import java.util.Objects; - import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.util.ConstantMapping; @@ -32,8 +30,8 @@ public class MultiRowValuePhraseVisitor extends MultiRowInsertMappingVisitor<Fie protected final String prefix; protected MultiRowValuePhraseVisitor(RenderingStrategy renderingStrategy, String prefix) { - this.renderingStrategy = Objects.requireNonNull(renderingStrategy); - this.prefix = Objects.requireNonNull(prefix); + this.renderingStrategy = renderingStrategy; + this.prefix = prefix; } @Override diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/package-info.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/package-info.java new file mode 100644 index 000000000..02cfd6efa --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.insert.render; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/package-info.java b/src/main/java/org/mybatis/dynamic/sql/package-info.java new file mode 100644 index 000000000..7555e2e26 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java b/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java index 5b31d0654..4e1457067 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RenderingContext.java @@ -20,6 +20,7 @@ import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.SqlTable; @@ -37,7 +38,7 @@ public class RenderingContext { private final RenderingStrategy renderingStrategy; private final AtomicInteger sequence; private final TableAliasCalculator tableAliasCalculator; - private final String configuredParameterName; + private final @Nullable String configuredParameterName; private final String calculatedParameterName; private final StatementConfiguration statementConfiguration; @@ -134,11 +135,11 @@ public static Builder withRenderingStrategy(RenderingStrategy renderingStrategy) } public static class Builder { - private RenderingStrategy renderingStrategy; - private AtomicInteger sequence; - private TableAliasCalculator tableAliasCalculator = TableAliasCalculator.empty(); - private String parameterName; - private StatementConfiguration statementConfiguration; + private @Nullable RenderingStrategy renderingStrategy; + private @Nullable AtomicInteger sequence; + private @Nullable TableAliasCalculator tableAliasCalculator = TableAliasCalculator.empty(); + private @Nullable String parameterName; + private @Nullable StatementConfiguration statementConfiguration; public Builder withRenderingStrategy(RenderingStrategy renderingStrategy) { this.renderingStrategy = renderingStrategy; @@ -155,7 +156,7 @@ public Builder withTableAliasCalculator(TableAliasCalculator tableAliasCalculato return this; } - public Builder withParameterName(String parameterName) { + public Builder withParameterName(@Nullable String parameterName) { this.parameterName = parameterName; return this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/render/TableAliasCalculatorWithParent.java b/src/main/java/org/mybatis/dynamic/sql/render/TableAliasCalculatorWithParent.java index 73d102d76..e843751d3 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/TableAliasCalculatorWithParent.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/TableAliasCalculatorWithParent.java @@ -18,6 +18,7 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlTable; public class TableAliasCalculatorWithParent implements TableAliasCalculator { @@ -48,8 +49,8 @@ public Optional<String> aliasForTable(SqlTable table) { } public static class Builder { - private TableAliasCalculator parent; - private TableAliasCalculator child; + private @Nullable TableAliasCalculator parent; + private @Nullable TableAliasCalculator child; public Builder withParent(TableAliasCalculator parent) { this.parent = parent; diff --git a/src/main/java/org/mybatis/dynamic/sql/render/package-info.java b/src/main/java/org/mybatis/dynamic/sql/render/package-info.java new file mode 100644 index 000000000..770ff3d47 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/render/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.render; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingFinisher.java b/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingFinisher.java index bcf21b23a..872b964eb 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingFinisher.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingFinisher.java @@ -17,6 +17,7 @@ import java.util.List; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AndOrCriteriaGroup; import org.mybatis.dynamic.sql.SqlCriterion; import org.mybatis.dynamic.sql.common.AbstractBooleanExpressionDSL; @@ -27,7 +28,7 @@ void initialize(SqlCriterion sqlCriterion) { setInitialCriterion(sqlCriterion, StatementType.HAVING); } - void initialize(SqlCriterion sqlCriterion, List<AndOrCriteriaGroup> subCriteria) { + void initialize(@Nullable SqlCriterion sqlCriterion, List<AndOrCriteriaGroup> subCriteria) { setInitialCriterion(sqlCriterion, StatementType.HAVING); super.subCriteria.addAll(subCriteria); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/AbstractQueryExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/AbstractQueryExpressionDSL.java index bee032a30..f1fd826a8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/AbstractQueryExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/AbstractQueryExpressionDSL.java @@ -25,6 +25,7 @@ import java.util.Optional; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AndOrCriteriaGroup; import org.mybatis.dynamic.sql.SqlCriterion; import org.mybatis.dynamic.sql.SqlTable; @@ -65,19 +66,19 @@ public T join(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterio return join(joinTable, onJoinCriterion, andJoinCriteria); } - public T join(SqlTable joinTable, SqlCriterion onJoinCriterion, + public T join(SqlTable joinTable, @Nullable SqlCriterion onJoinCriterion, List<AndOrCriteriaGroup> andJoinCriteria) { addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.INNER, andJoinCriteria); return getThis(); } - public T join(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion, + public T join(SqlTable joinTable, String tableAlias, @Nullable SqlCriterion onJoinCriterion, List<AndOrCriteriaGroup> andJoinCriteria) { addTableAlias(joinTable, tableAlias); return join(joinTable, onJoinCriterion, andJoinCriteria); } - public T join(Buildable<SelectModel> subQuery, String tableAlias, SqlCriterion onJoinCriterion, + public T join(Buildable<SelectModel> subQuery, @Nullable String tableAlias, @Nullable SqlCriterion onJoinCriterion, List<AndOrCriteriaGroup> andJoinCriteria) { addJoinSpecificationSupplier(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.INNER, andJoinCriteria); @@ -96,20 +97,20 @@ public T leftJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCrit return leftJoin(joinTable, onJoinCriterion, andJoinCriteria); } - public T leftJoin(SqlTable joinTable, SqlCriterion onJoinCriterion, + public T leftJoin(SqlTable joinTable, @Nullable SqlCriterion onJoinCriterion, List<AndOrCriteriaGroup> andJoinCriteria) { addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.LEFT, andJoinCriteria); return getThis(); } - public T leftJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion, + public T leftJoin(SqlTable joinTable, String tableAlias, @Nullable SqlCriterion onJoinCriterion, List<AndOrCriteriaGroup> andJoinCriteria) { addTableAlias(joinTable, tableAlias); return leftJoin(joinTable, onJoinCriterion, andJoinCriteria); } - public T leftJoin(Buildable<SelectModel> subQuery, String tableAlias, SqlCriterion onJoinCriterion, - List<AndOrCriteriaGroup> andJoinCriteria) { + public T leftJoin(Buildable<SelectModel> subQuery, @Nullable String tableAlias, + @Nullable SqlCriterion onJoinCriterion, List<AndOrCriteriaGroup> andJoinCriteria) { addJoinSpecificationSupplier(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.LEFT, andJoinCriteria); return getThis(); @@ -127,20 +128,20 @@ public T rightJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCri return rightJoin(joinTable, onJoinCriterion, andJoinCriteria); } - public T rightJoin(SqlTable joinTable, SqlCriterion onJoinCriterion, + public T rightJoin(SqlTable joinTable, @Nullable SqlCriterion onJoinCriterion, List<AndOrCriteriaGroup> andJoinCriteria) { addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.RIGHT, andJoinCriteria); return getThis(); } - public T rightJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion, + public T rightJoin(SqlTable joinTable, String tableAlias, @Nullable SqlCriterion onJoinCriterion, List<AndOrCriteriaGroup> andJoinCriteria) { addTableAlias(joinTable, tableAlias); return rightJoin(joinTable, onJoinCriterion, andJoinCriteria); } - public T rightJoin(Buildable<SelectModel> subQuery, String tableAlias, SqlCriterion onJoinCriterion, - List<AndOrCriteriaGroup> andJoinCriteria) { + public T rightJoin(Buildable<SelectModel> subQuery, @Nullable String tableAlias, + @Nullable SqlCriterion onJoinCriterion, List<AndOrCriteriaGroup> andJoinCriteria) { addJoinSpecificationSupplier(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.RIGHT, andJoinCriteria); return getThis(); @@ -158,26 +159,26 @@ public T fullJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCrit return fullJoin(joinTable, onJoinCriterion, andJoinCriteria); } - public T fullJoin(SqlTable joinTable, SqlCriterion onJoinCriterion, + public T fullJoin(SqlTable joinTable, @Nullable SqlCriterion onJoinCriterion, List<AndOrCriteriaGroup> andJoinCriteria) { addJoinSpecificationSupplier(joinTable, onJoinCriterion, JoinType.FULL, andJoinCriteria); return getThis(); } - public T fullJoin(SqlTable joinTable, String tableAlias, SqlCriterion onJoinCriterion, + public T fullJoin(SqlTable joinTable, String tableAlias, @Nullable SqlCriterion onJoinCriterion, List<AndOrCriteriaGroup> andJoinCriteria) { addTableAlias(joinTable, tableAlias); return fullJoin(joinTable, onJoinCriterion, andJoinCriteria); } - public T fullJoin(Buildable<SelectModel> subQuery, String tableAlias, SqlCriterion onJoinCriterion, - List<AndOrCriteriaGroup> andJoinCriteria) { + public T fullJoin(Buildable<SelectModel> subQuery, @Nullable String tableAlias, + @Nullable SqlCriterion onJoinCriterion, List<AndOrCriteriaGroup> andJoinCriteria) { addJoinSpecificationSupplier(buildSubQuery(subQuery, tableAlias), onJoinCriterion, JoinType.FULL, andJoinCriteria); return getThis(); } - private void addJoinSpecificationSupplier(TableExpression joinTable, SqlCriterion onJoinCriterion, + private void addJoinSpecificationSupplier(TableExpression joinTable, @Nullable SqlCriterion onJoinCriterion, JoinType joinType, List<AndOrCriteriaGroup> andJoinCriteria) { joinSpecificationSuppliers.add(() -> new JoinSpecification.Builder() .withJoinTable(joinTable) @@ -218,7 +219,7 @@ protected static SubQuery buildSubQuery(Buildable<SelectModel> selectModel) { .build(); } - protected static SubQuery buildSubQuery(Buildable<SelectModel> selectModel, String alias) { + protected static SubQuery buildSubQuery(Buildable<SelectModel> selectModel, @Nullable String alias) { return new SubQuery.Builder() .withSelectModel(selectModel.build()) .withAlias(alias) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/AbstractSelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/AbstractSelectModel.java index d19f45c55..51c3d4fe7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/AbstractSelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/AbstractSelectModel.java @@ -18,12 +18,13 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; public abstract class AbstractSelectModel { - private final OrderByModel orderByModel; - private final PagingModel pagingModel; + private final @Nullable OrderByModel orderByModel; + private final @Nullable PagingModel pagingModel; protected final StatementConfiguration statementConfiguration; protected AbstractSelectModel(AbstractBuilder<?> builder) { @@ -45,16 +46,16 @@ public StatementConfiguration statementConfiguration() { } public abstract static class AbstractBuilder<T extends AbstractBuilder<T>> { - private OrderByModel orderByModel; - private PagingModel pagingModel; - private StatementConfiguration statementConfiguration; + private @Nullable OrderByModel orderByModel; + private @Nullable PagingModel pagingModel; + private @Nullable StatementConfiguration statementConfiguration; - public T withOrderByModel(OrderByModel orderByModel) { + public T withOrderByModel(@Nullable OrderByModel orderByModel) { this.orderByModel = orderByModel; return getThis(); } - public T withPagingModel(PagingModel pagingModel) { + public T withPagingModel(@Nullable PagingModel pagingModel) { this.pagingModel = pagingModel; return getThis(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/CountDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/CountDSL.java index 069249072..a867c8bf8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/CountDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/CountDSL.java @@ -19,7 +19,7 @@ import java.util.function.Consumer; import java.util.function.Function; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.SqlBuilder; import org.mybatis.dynamic.sql.SqlTable; @@ -42,7 +42,7 @@ public class CountDSL<R> extends AbstractQueryExpressionDSL<CountDSL<R>.CountWhe implements Buildable<R> { private final Function<SelectModel, R> adapterFunction; - private CountWhereBuilder whereBuilder; + private @Nullable CountWhereBuilder whereBuilder; private final BasicColumn countColumn; private final StatementConfiguration statementConfiguration = new StatementConfiguration(); @@ -58,7 +58,6 @@ public CountWhereBuilder where() { return whereBuilder; } - @NotNull @Override public R build() { return adapterFunction.apply(buildModel()); @@ -134,7 +133,6 @@ private CountWhereBuilder() { super(CountDSL.this); } - @NotNull @Override public R build() { return CountDSL.this.build(); diff --git a/src/main/java/org/mybatis/dynamic/sql/select/HavingDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/HavingDSL.java index 2f5a7e5fa..34be15f62 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/HavingDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/HavingDSL.java @@ -15,7 +15,6 @@ */ package org.mybatis.dynamic.sql.select; -import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.util.Buildable; public class HavingDSL extends AbstractHavingStarter<HavingDSL.StandaloneHavingFinisher> { @@ -36,7 +35,6 @@ protected StandaloneHavingFinisher getThis() { return this; } - @NotNull @Override public HavingModel build() { return buildModel(); diff --git a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java index 2eb3c8b89..308107c30 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java @@ -22,7 +22,7 @@ import java.util.Optional; import java.util.function.Consumer; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SortSpecification; import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; @@ -33,10 +33,10 @@ public class MultiSelectDSL implements Buildable<MultiSelectModel>, Configurable PagingDSL<MultiSelectModel> { private final List<UnionQuery> unionQueries = new ArrayList<>(); private final SelectModel initialSelect; - private OrderByModel orderByModel; - private Long limit; - private Long offset; - private Long fetchFirstRows; + private @Nullable OrderByModel orderByModel; + private @Nullable Long limit; + private @Nullable Long offset; + private @Nullable Long fetchFirstRows; private final StatementConfiguration statementConfiguration = new StatementConfiguration(); public MultiSelectDSL(Buildable<SelectModel> builder) { @@ -63,24 +63,23 @@ public MultiSelectDSL orderBy(Collection<? extends SortSpecification> columns) { } @Override - public LimitFinisher<MultiSelectModel> limitWhenPresent(Long limit) { + public LimitFinisher<MultiSelectModel> limitWhenPresent(@Nullable Long limit) { this.limit = limit; return new LocalLimitFinisher(); } @Override - public OffsetFirstFinisher<MultiSelectModel> offsetWhenPresent(Long offset) { + public OffsetFirstFinisher<MultiSelectModel> offsetWhenPresent(@Nullable Long offset) { this.offset = offset; return new LocalOffsetFirstFinisher(); } @Override - public FetchFirstFinisher<MultiSelectModel> fetchFirstWhenPresent(Long fetchFirstRows) { + public FetchFirstFinisher<MultiSelectModel> fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { this.fetchFirstRows = fetchFirstRows; return () -> this; } - @NotNull @Override public MultiSelectModel build() { return new MultiSelectModel.Builder() @@ -107,7 +106,6 @@ public MultiSelectDSL configureStatement(Consumer<StatementConfiguration> consum } abstract class BaseBuildable implements Buildable<MultiSelectModel> { - @NotNull @Override public MultiSelectModel build() { return MultiSelectDSL.this.build(); diff --git a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java index c61188d80..94dbe765b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectModel.java @@ -20,7 +20,7 @@ import java.util.Objects; import java.util.stream.Stream; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.select.render.MultiSelectRenderer; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; @@ -45,7 +45,6 @@ public Stream<UnionQuery> unionQueries() { return unionQueries.stream(); } - @NotNull public SelectStatementProvider render(RenderingStrategy renderingStrategy) { return MultiSelectRenderer.withMultiSelectModel(this) .withRenderingStrategy(renderingStrategy) @@ -54,7 +53,7 @@ public SelectStatementProvider render(RenderingStrategy renderingStrategy) { } public static class Builder extends AbstractBuilder<Builder> { - private SelectModel initialSelect; + private @Nullable SelectModel initialSelect; private final List<UnionQuery> unionQueries = new ArrayList<>(); public Builder withInitialSelect(SelectModel initialSelect) { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/PagingModel.java b/src/main/java/org/mybatis/dynamic/sql/select/PagingModel.java index 59b4a8bf2..b5da5e01c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/PagingModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/PagingModel.java @@ -17,11 +17,13 @@ import java.util.Optional; +import org.jspecify.annotations.Nullable; + public class PagingModel { - private final Long limit; - private final Long offset; - private final Long fetchFirstRows; + private final @Nullable Long limit; + private final @Nullable Long offset; + private final @Nullable Long fetchFirstRows; private PagingModel(Builder builder) { super(); @@ -43,21 +45,21 @@ public Optional<Long> fetchFirstRows() { } public static class Builder { - private Long limit; - private Long offset; - private Long fetchFirstRows; + private @Nullable Long limit; + private @Nullable Long offset; + private @Nullable Long fetchFirstRows; - public Builder withLimit(Long limit) { + public Builder withLimit(@Nullable Long limit) { this.limit = limit; return this; } - public Builder withOffset(Long offset) { + public Builder withOffset(@Nullable Long offset) { this.offset = offset; return this; } - public Builder withFetchFirstRows(Long fetchFirstRows) { + public Builder withFetchFirstRows(@Nullable Long fetchFirstRows) { this.fetchFirstRows = fetchFirstRows; return this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java index 90156cea7..0964ee3b3 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java @@ -22,7 +22,7 @@ import java.util.Objects; import java.util.function.Consumer; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AndOrCriteriaGroup; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; @@ -46,13 +46,13 @@ public class QueryExpressionDSL<R> extends AbstractQueryExpressionDSL<QueryExpressionDSL<R>.QueryExpressionWhereBuilder, QueryExpressionDSL<R>> implements Buildable<R>, PagingDSL<R> { - private final String connector; + private final @Nullable String connector; private final SelectDSL<R> selectDSL; private final boolean isDistinct; private final List<BasicColumn> selectList; - private QueryExpressionWhereBuilder whereBuilder; - private GroupByModel groupByModel; - private QueryExpressionHavingBuilder havingBuilder; + private @Nullable QueryExpressionWhereBuilder whereBuilder; + private @Nullable GroupByModel groupByModel; + private @Nullable QueryExpressionHavingBuilder havingBuilder; protected QueryExpressionDSL(FromGatherer<R> fromGatherer, TableExpression table) { super(table); @@ -99,7 +99,6 @@ protected void applyHaving(CriteriaGroup criteriaGroup) { having().initialize(criteriaGroup); } - @NotNull @Override public R build() { return selectDSL.build(); @@ -197,17 +196,17 @@ protected QueryExpressionModel buildModel() { } @Override - public PagingDSL.LimitFinisher<R> limitWhenPresent(Long limit) { + public PagingDSL.LimitFinisher<R> limitWhenPresent(@Nullable Long limit) { return selectDSL.limitWhenPresent(limit); } @Override - public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(Long offset) { + public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(@Nullable Long offset) { return selectDSL.offsetWhenPresent(offset); } @Override - public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(Long fetchFirstRows) { + public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { return selectDSL.fetchFirstWhenPresent(fetchFirstRows); } @@ -217,7 +216,7 @@ protected QueryExpressionDSL<R> getThis() { } public static class FromGatherer<R> { - private final String connector; + private final @Nullable String connector; private final List<BasicColumn> selectList; private final SelectDSL<R> selectDSL; private final boolean isDistinct; @@ -246,9 +245,9 @@ public QueryExpressionDSL<R> from(SqlTable table, String tableAlias) { } public static class Builder<R> { - private String connector; + private @Nullable String connector; private final List<BasicColumn> selectList = new ArrayList<>(); - private SelectDSL<R> selectDSL; + private @Nullable SelectDSL<R> selectDSL; private boolean isDistinct; public Builder<R> withConnector(String connector) { @@ -308,21 +307,20 @@ public GroupByFinisher groupBy(Collection<? extends BasicColumn> columns) { } @Override - public PagingDSL.LimitFinisher<R> limitWhenPresent(Long limit) { + public PagingDSL.LimitFinisher<R> limitWhenPresent(@Nullable Long limit) { return QueryExpressionDSL.this.limitWhenPresent(limit); } @Override - public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(Long offset) { + public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(@Nullable Long offset) { return QueryExpressionDSL.this.offsetWhenPresent(offset); } @Override - public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(Long fetchFirstRows) { + public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { return QueryExpressionDSL.this.fetchFirstWhenPresent(fetchFirstRows); } - @NotNull @Override public R build() { return QueryExpressionDSL.this.build(); @@ -400,7 +398,6 @@ private JoinSpecification buildJoinSpecification() { .build(); } - @NotNull @Override public R build() { return QueryExpressionDSL.this.build(); @@ -490,17 +487,17 @@ public SelectDSL<R> orderBy(Collection<? extends SortSpecification> columns) { } @Override - public PagingDSL.LimitFinisher<R> limitWhenPresent(Long limit) { + public PagingDSL.LimitFinisher<R> limitWhenPresent(@Nullable Long limit) { return QueryExpressionDSL.this.limitWhenPresent(limit); } @Override - public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(Long offset) { + public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(@Nullable Long offset) { return QueryExpressionDSL.this.offsetWhenPresent(offset); } @Override - public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(Long fetchFirstRows) { + public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { return QueryExpressionDSL.this.fetchFirstWhenPresent(fetchFirstRows); } @@ -520,7 +517,6 @@ public SelectDSL<R> orderBy(Collection<? extends SortSpecification> columns) { return QueryExpressionDSL.this.orderBy(columns); } - @NotNull @Override public R build() { return QueryExpressionDSL.this.build(); @@ -535,17 +531,17 @@ public UnionBuilder unionAll() { } @Override - public PagingDSL.LimitFinisher<R> limitWhenPresent(Long limit) { + public PagingDSL.LimitFinisher<R> limitWhenPresent(@Nullable Long limit) { return QueryExpressionDSL.this.limitWhenPresent(limit); } @Override - public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(Long offset) { + public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(@Nullable Long offset) { return QueryExpressionDSL.this.offsetWhenPresent(offset); } @Override - public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(Long fetchFirstRows) { + public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { return QueryExpressionDSL.this.fetchFirstWhenPresent(fetchFirstRows); } @@ -592,17 +588,17 @@ public class QueryExpressionHavingBuilder extends AbstractHavingFinisher<QueryEx implements Buildable<R>, PagingDSL<R> { @Override - public PagingDSL.LimitFinisher<R> limitWhenPresent(Long limit) { + public PagingDSL.LimitFinisher<R> limitWhenPresent(@Nullable Long limit) { return QueryExpressionDSL.this.limitWhenPresent(limit); } @Override - public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(Long offset) { + public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(@Nullable Long offset) { return QueryExpressionDSL.this.offsetWhenPresent(offset); } @Override - public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(Long fetchFirstRows) { + public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { return QueryExpressionDSL.this.fetchFirstWhenPresent(fetchFirstRows); } @@ -622,7 +618,6 @@ public UnionBuilder unionAll() { return QueryExpressionDSL.this.unionAll(); } - @NotNull @Override public R build() { return QueryExpressionDSL.this.build(); 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 4d5e948ea..4561c0781 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionModel.java @@ -23,6 +23,7 @@ import java.util.Optional; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.TableExpression; @@ -31,15 +32,15 @@ import org.mybatis.dynamic.sql.where.EmbeddedWhereModel; public class QueryExpressionModel { - private final String connector; + private final @Nullable String connector; private final boolean isDistinct; private final List<BasicColumn> selectList; private final TableExpression table; - private final JoinModel joinModel; + private final @Nullable JoinModel joinModel; private final Map<SqlTable, String> tableAliases; - private final EmbeddedWhereModel whereModel; - private final GroupByModel groupByModel; - private final HavingModel havingModel; + private final @Nullable EmbeddedWhereModel whereModel; + private final @Nullable GroupByModel groupByModel; + private final @Nullable HavingModel havingModel; private QueryExpressionModel(Builder builder) { connector = builder.connector; @@ -95,17 +96,17 @@ public static Builder withSelectList(List<? extends BasicColumn> columnList) { } public static class Builder { - private String connector; + private @Nullable String connector; private boolean isDistinct; private final List<BasicColumn> selectList = new ArrayList<>(); - private TableExpression table; + private @Nullable TableExpression table; private final Map<SqlTable, String> tableAliases = new HashMap<>(); - private EmbeddedWhereModel whereModel; - private JoinModel joinModel; - private GroupByModel groupByModel; - private HavingModel havingModel; + private @Nullable EmbeddedWhereModel whereModel; + private @Nullable JoinModel joinModel; + private @Nullable GroupByModel groupByModel; + private @Nullable HavingModel havingModel; - public Builder withConnector(String connector) { + public Builder withConnector(@Nullable String connector) { this.connector = connector; return this; } @@ -135,22 +136,22 @@ public Builder withTableAliases(Map<SqlTable, String> tableAliases) { return this; } - public Builder withWhereModel(EmbeddedWhereModel whereModel) { + public Builder withWhereModel(@Nullable EmbeddedWhereModel whereModel) { this.whereModel = whereModel; return this; } - public Builder withJoinModel(JoinModel joinModel) { + public Builder withJoinModel(@Nullable JoinModel joinModel) { this.joinModel = joinModel; return this; } - public Builder withGroupByModel(GroupByModel groupByModel) { + public Builder withGroupByModel(@Nullable GroupByModel groupByModel) { this.groupByModel = groupByModel; return this; } - public Builder withHavingModel(HavingModel havingModel) { + public Builder withHavingModel(@Nullable HavingModel havingModel) { this.havingModel = havingModel; return this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java index eed99b218..7f1fd239b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java @@ -24,7 +24,7 @@ import java.util.function.Consumer; import java.util.function.Function; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.SortSpecification; import org.mybatis.dynamic.sql.common.OrderByModel; @@ -45,10 +45,10 @@ public class SelectDSL<R> implements Buildable<R>, ConfigurableStatement<SelectD private final Function<SelectModel, R> adapterFunction; private final List<QueryExpressionDSL<R>> queryExpressions = new ArrayList<>(); - private OrderByModel orderByModel; - private Long limit; - private Long offset; - private Long fetchFirstRows; + private @Nullable OrderByModel orderByModel; + private @Nullable Long limit; + private @Nullable Long offset; + private @Nullable Long fetchFirstRows; final StatementConfiguration statementConfiguration = new StatementConfiguration(); private SelectDSL(Function<SelectModel, R> adapterFunction) { @@ -107,17 +107,17 @@ void orderBy(Collection<? extends SortSpecification> columns) { orderByModel = OrderByModel.of(columns); } - public LimitFinisher<R> limitWhenPresent(Long limit) { + public LimitFinisher<R> limitWhenPresent(@Nullable Long limit) { this.limit = limit; return new LocalLimitFinisher(); } - public OffsetFirstFinisher<R> offsetWhenPresent(Long offset) { + public OffsetFirstFinisher<R> offsetWhenPresent(@Nullable Long offset) { this.offset = offset; return new LocalOffsetFirstFinisher(); } - public FetchFirstFinisher<R> fetchFirstWhenPresent(Long fetchFirstRows) { + public FetchFirstFinisher<R> fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { this.fetchFirstRows = fetchFirstRows; return () -> this; } @@ -128,7 +128,6 @@ public SelectDSL<R> configureStatement(Consumer<StatementConfiguration> consumer return this; } - @NotNull @Override public R build() { SelectModel selectModel = SelectModel.withQueryExpressions(buildModels()) @@ -154,7 +153,6 @@ private Optional<PagingModel> buildPagingModel() { } abstract class BaseBuildable implements Buildable<R> { - @NotNull @Override public R build() { return SelectDSL.this.build(); diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java index cb7d135dd..fd4eecc0c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java @@ -20,7 +20,6 @@ import java.util.Objects; import java.util.stream.Stream; -import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.select.render.SelectRenderer; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; @@ -39,7 +38,6 @@ public Stream<QueryExpressionModel> queryExpressions() { return queryExpressions.stream(); } - @NotNull public SelectStatementProvider render(RenderingStrategy renderingStrategy) { return SelectRenderer.withSelectModel(this) .withRenderingStrategy(renderingStrategy) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SubQuery.java b/src/main/java/org/mybatis/dynamic/sql/select/SubQuery.java index 271682870..c2264c162 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SubQuery.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SubQuery.java @@ -18,12 +18,13 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.TableExpression; import org.mybatis.dynamic.sql.TableExpressionVisitor; public class SubQuery implements TableExpression { private final SelectModel selectModel; - private final String alias; + private final @Nullable String alias; private SubQuery(Builder builder) { selectModel = Objects.requireNonNull(builder.selectModel); @@ -49,15 +50,15 @@ public <R> R accept(TableExpressionVisitor<R> visitor) { } public static class Builder { - private SelectModel selectModel; - private String alias; + private @Nullable SelectModel selectModel; + private @Nullable String alias; public Builder withSelectModel(SelectModel selectModel) { this.selectModel = selectModel; return this; } - public Builder withAlias(String alias) { + public Builder withAlias(@Nullable String alias) { this.alias = alias; return this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/AbstractCount.java b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/AbstractCount.java index ae91015ae..fe40329ea 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/AbstractCount.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/AbstractCount.java @@ -17,6 +17,7 @@ import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BindableColumn; /** @@ -25,13 +26,13 @@ * as it is assumed that the count functions always return a number. */ public abstract class AbstractCount implements BindableColumn<Long> { - private final String alias; + private final @Nullable String alias; protected AbstractCount() { this(null); } - protected AbstractCount(String alias) { + protected AbstractCount(@Nullable String alias) { this.alias = alias; } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/package-info.java b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/package-info.java new file mode 100644 index 000000000..36235945c --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.select.aggregate; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseDSL.java index 1dbd663a3..0c0c6ea87 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseDSL.java @@ -19,6 +19,7 @@ import java.util.Arrays; import java.util.List; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AndOrCriteriaGroup; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; @@ -30,7 +31,7 @@ public class SearchedCaseDSL implements ElseDSL<SearchedCaseDSL.SearchedCaseEnder> { private final List<SearchedCaseWhenCondition> whenConditions = new ArrayList<>(); - private BasicColumn elseValue; + private @Nullable BasicColumn elseValue; public <T> WhenDSL when(BindableColumn<T> column, VisitableCondition<T> condition, AndOrCriteriaGroup... subCriteria) { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseModel.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseModel.java index 8ca95513c..c42372868 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseModel.java @@ -20,6 +20,7 @@ import java.util.Optional; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.SortSpecification; import org.mybatis.dynamic.sql.render.RenderingContext; @@ -29,8 +30,8 @@ public class SearchedCaseModel implements BasicColumn, SortSpecification { private final List<SearchedCaseWhenCondition> whenConditions; - private final BasicColumn elseValue; - private final String alias; + private final @Nullable BasicColumn elseValue; + private final @Nullable String alias; private final String descendingPhrase; private SearchedCaseModel(Builder builder) { @@ -84,8 +85,8 @@ public FragmentAndParameters render(RenderingContext renderingContext) { public static class Builder { private final List<SearchedCaseWhenCondition> whenConditions = new ArrayList<>(); - private BasicColumn elseValue; - private String alias; + private @Nullable BasicColumn elseValue; + private @Nullable String alias; private String descendingPhrase = ""; //$NON-NLS-1$ public Builder withWhenConditions(List<SearchedCaseWhenCondition> whenConditions) { @@ -93,12 +94,12 @@ public Builder withWhenConditions(List<SearchedCaseWhenCondition> whenConditions return this; } - public Builder withElseValue(BasicColumn elseValue) { + public Builder withElseValue(@Nullable BasicColumn elseValue) { this.elseValue = elseValue; return this; } - public Builder withAlias(String alias) { + public Builder withAlias(@Nullable String alias) { this.alias = alias; return this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseWhenCondition.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseWhenCondition.java index 21fab5010..9b251be9c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseWhenCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseWhenCondition.java @@ -17,6 +17,7 @@ import java.util.Objects; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.common.AbstractBooleanExpressionModel; @@ -33,7 +34,7 @@ private SearchedCaseWhenCondition(Builder builder) { } public static class Builder extends AbstractBuilder<Builder> { - private BasicColumn thenValue; + private @Nullable BasicColumn thenValue; public Builder withThenValue(BasicColumn thenValue) { this.thenValue = thenValue; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseDSL.java index 8fc7a8360..488f20060 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseDSL.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Objects; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.VisitableCondition; @@ -27,7 +28,7 @@ public class SimpleCaseDSL<T> implements ElseDSL<SimpleCaseDSL<T>.SimpleCaseEnder> { private final BindableColumn<T> column; private final List<SimpleCaseWhenCondition<T>> whenConditions = new ArrayList<>(); - private BasicColumn elseValue; + private @Nullable BasicColumn elseValue; private SimpleCaseDSL(BindableColumn<T> column) { this.column = Objects.requireNonNull(column); diff --git a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseModel.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseModel.java index db666df22..45eb95c01 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseModel.java @@ -21,6 +21,7 @@ import java.util.Optional; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.SortSpecification; @@ -32,8 +33,8 @@ public class SimpleCaseModel<T> implements BasicColumn, SortSpecification { private final BindableColumn<T> column; private final List<SimpleCaseWhenCondition<T>> whenConditions; - private final BasicColumn elseValue; - private final String alias; + private final @Nullable BasicColumn elseValue; + private final @Nullable String alias; private final String descendingPhrase; private SimpleCaseModel(Builder<T> builder) { @@ -95,10 +96,10 @@ public FragmentAndParameters render(RenderingContext renderingContext) { } public static class Builder<T> { - private BindableColumn<T> column; + private @Nullable BindableColumn<T> column; private final List<SimpleCaseWhenCondition<T>> whenConditions = new ArrayList<>(); - private BasicColumn elseValue; - private String alias; + private @Nullable BasicColumn elseValue; + private @Nullable String alias; private String descendingPhrase = ""; //$NON-NLS-1$ public Builder<T> withColumn(BindableColumn<T> column) { @@ -111,12 +112,12 @@ public Builder<T> withWhenConditions(List<SimpleCaseWhenCondition<T>> whenCondit return this; } - public Builder<T> withElseValue(BasicColumn elseValue) { + public Builder<T> withElseValue(@Nullable BasicColumn elseValue) { this.elseValue = elseValue; return this; } - public Builder<T> withAlias(String alias) { + public Builder<T> withAlias(@Nullable String alias) { this.alias = alias; return this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/package-info.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/package-info.java new file mode 100644 index 000000000..951a3da74 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.select.caseexpression; + +import org.jspecify.annotations.NullMarked; \ No newline at end of file diff --git a/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractTypeConvertingFunction.java b/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractTypeConvertingFunction.java index 448b97cad..1517d3519 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractTypeConvertingFunction.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/AbstractTypeConvertingFunction.java @@ -18,6 +18,8 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; @@ -38,7 +40,7 @@ public abstract class AbstractTypeConvertingFunction<T, R, U extends AbstractTypeConvertingFunction<T, R, U>> implements BindableColumn<R> { protected final BasicColumn column; - protected String alias; + protected @Nullable String alias; protected AbstractTypeConvertingFunction(BasicColumn column) { this.column = Objects.requireNonNull(column); @@ -49,6 +51,7 @@ public Optional<String> alias() { return Optional.ofNullable(alias); } + @NonNull @Override public U as(String alias) { U newThing = copy(); diff --git a/src/main/java/org/mybatis/dynamic/sql/select/function/Cast.java b/src/main/java/org/mybatis/dynamic/sql/select/function/Cast.java index 742ba2705..1349d4f51 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/function/Cast.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/Cast.java @@ -18,6 +18,7 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; @@ -25,7 +26,7 @@ public class Cast implements BasicColumn { private final BasicColumn column; private final String targetType; - private final String alias; + private final @Nullable String alias; private Cast(Builder builder) { column = Objects.requireNonNull(builder.column); @@ -56,9 +57,9 @@ private String applyCast(String in) { } public static class Builder { - private BasicColumn column; - private String targetType; - private String alias; + private @Nullable BasicColumn column; + private @Nullable String targetType; + private @Nullable String alias; public Builder withColumn(BasicColumn column) { this.column = column; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/function/package-info.java b/src/main/java/org/mybatis/dynamic/sql/select/function/package-info.java new file mode 100644 index 000000000..4f8535279 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/select/function/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.select.function; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/join/JoinSpecification.java b/src/main/java/org/mybatis/dynamic/sql/select/join/JoinSpecification.java index 5ce6677cc..8cefbba6b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/join/JoinSpecification.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/join/JoinSpecification.java @@ -17,6 +17,7 @@ import java.util.Objects; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.TableExpression; import org.mybatis.dynamic.sql.common.AbstractBooleanExpressionModel; import org.mybatis.dynamic.sql.util.Validator; @@ -47,8 +48,8 @@ public static Builder withJoinTable(TableExpression table) { } public static class Builder extends AbstractBuilder<Builder> { - private TableExpression table; - private JoinType joinType; + private @Nullable TableExpression table; + private @Nullable JoinType joinType; public Builder withJoinTable(TableExpression table) { this.table = table; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/join/package-info.java b/src/main/java/org/mybatis/dynamic/sql/select/join/package-info.java new file mode 100644 index 000000000..03ec51bcc --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/select/join/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.select.join; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/package-info.java b/src/main/java/org/mybatis/dynamic/sql/select/package-info.java new file mode 100644 index 000000000..7e49fd4ec --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/select/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.select; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/DefaultSelectStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/select/render/DefaultSelectStatementProvider.java index e84eea978..a79029144 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/DefaultSelectStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/DefaultSelectStatementProvider.java @@ -20,6 +20,8 @@ import java.util.Map; import java.util.Objects; +import org.jspecify.annotations.Nullable; + public class DefaultSelectStatementProvider implements SelectStatementProvider { private final String selectStatement; private final Map<String, Object> parameters; @@ -44,7 +46,7 @@ public static Builder withSelectStatement(String selectStatement) { } public static class Builder { - private String selectStatement; + private @Nullable String selectStatement; private final Map<String, Object> parameters = new HashMap<>(); public Builder withSelectStatement(String selectStatement) { diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/JoinRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/JoinRenderer.java index 67e84bc5a..c1e8a0387 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/JoinRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/JoinRenderer.java @@ -18,6 +18,7 @@ import java.util.Objects; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.exception.InvalidSqlException; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.join.JoinModel; @@ -63,9 +64,9 @@ public static Builder withJoinModel(JoinModel joinModel) { } public static class Builder { - private JoinModel joinModel; - private TableExpressionRenderer tableExpressionRenderer; - private RenderingContext renderingContext; + private @Nullable JoinModel joinModel; + private @Nullable TableExpressionRenderer tableExpressionRenderer; + private @Nullable RenderingContext renderingContext; public Builder withJoinModel(JoinModel joinModel) { this.joinModel = joinModel; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java index 6634da889..4daf576d4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/MultiSelectRenderer.java @@ -19,6 +19,7 @@ import java.util.Optional; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.common.OrderByRenderer; import org.mybatis.dynamic.sql.render.RenderingContext; @@ -37,7 +38,7 @@ public class MultiSelectRenderer { private MultiSelectRenderer(Builder builder) { multiSelectModel = Objects.requireNonNull(builder.multiSelectModel); renderingContext = RenderingContext - .withRenderingStrategy(builder.renderingStrategy) + .withRenderingStrategy(Objects.requireNonNull(builder.renderingStrategy)) .withStatementConfiguration(multiSelectModel.statementConfiguration()) .build(); } @@ -106,8 +107,8 @@ public static Builder withMultiSelectModel(MultiSelectModel multiSelectModel) { } public static class Builder { - private RenderingStrategy renderingStrategy; - private MultiSelectModel multiSelectModel; + private @Nullable RenderingStrategy renderingStrategy; + private @Nullable MultiSelectModel multiSelectModel; public Builder withRenderingStrategy(RenderingStrategy renderingStrategy) { this.renderingStrategy = renderingStrategy; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/PagingModelRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/PagingModelRenderer.java index fecebbf92..6b79de960 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/PagingModelRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/PagingModelRenderer.java @@ -17,6 +17,7 @@ import java.util.Objects; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.PagingModel; import org.mybatis.dynamic.sql.util.FragmentAndParameters; @@ -44,8 +45,8 @@ private FragmentAndParameters fetchFirstRender() { } public static class Builder { - private PagingModel pagingModel; - private RenderingContext renderingContext; + private @Nullable PagingModel pagingModel; + private @Nullable RenderingContext renderingContext; public Builder withRenderingContext(RenderingContext renderingContext) { this.renderingContext = renderingContext; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/QueryExpressionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/QueryExpressionRenderer.java index d1c5baf09..610ba6d10 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/QueryExpressionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/QueryExpressionRenderer.java @@ -19,6 +19,7 @@ import java.util.Optional; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.TableExpression; import org.mybatis.dynamic.sql.render.ExplicitTableAliasCalculator; @@ -43,7 +44,8 @@ private QueryExpressionRenderer(Builder builder) { queryExpression = Objects.requireNonNull(builder.queryExpression); TableAliasCalculator childTableAliasCalculator = calculateChildTableAliasCalculator(queryExpression); - renderingContext = builder.renderingContext.withChildTableAliasCalculator(childTableAliasCalculator); + renderingContext = Objects.requireNonNull(builder.renderingContext) + .withChildTableAliasCalculator(childTableAliasCalculator); tableExpressionRenderer = new TableExpressionRenderer.Builder() .withRenderingContext(renderingContext) @@ -199,8 +201,8 @@ public static Builder withQueryExpression(QueryExpressionModel model) { } public static class Builder { - private QueryExpressionModel queryExpression; - private RenderingContext renderingContext; + private @Nullable QueryExpressionModel queryExpression; + private @Nullable RenderingContext renderingContext; public Builder withRenderingContext(RenderingContext renderingContext) { this.renderingContext = renderingContext; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java index 048a0b0e6..719d6aafe 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SelectRenderer.java @@ -17,6 +17,7 @@ import java.util.Objects; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.select.SelectModel; @@ -51,8 +52,8 @@ public static Builder withSelectModel(SelectModel selectModel) { } public static class Builder { - private SelectModel selectModel; - private RenderingStrategy renderingStrategy; + private @Nullable SelectModel selectModel; + private @Nullable RenderingStrategy renderingStrategy; public Builder withRenderingStrategy(RenderingStrategy renderingStrategy) { this.renderingStrategy = renderingStrategy; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java index 906adc8f9..6c4eb82ad 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java @@ -19,6 +19,7 @@ import java.util.Optional; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.common.OrderByRenderer; import org.mybatis.dynamic.sql.render.RenderingContext; @@ -85,10 +86,10 @@ public static Builder withSelectModel(SelectModel selectModel) { } public static class Builder { - private SelectModel selectModel; - private RenderingContext renderingContext; - private String prefix; - private String suffix; + private @Nullable SelectModel selectModel; + private @Nullable RenderingContext renderingContext; + private @Nullable String prefix; + private @Nullable String suffix; public Builder withRenderingContext(RenderingContext renderingContext) { this.renderingContext = renderingContext; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java index 402013623..8114e2411 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/TableExpressionRenderer.java @@ -17,6 +17,7 @@ import java.util.Objects; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.TableExpressionVisitor; import org.mybatis.dynamic.sql.render.RenderingContext; @@ -49,7 +50,7 @@ public FragmentAndParameters visit(SubQuery subQuery) { } public static class Builder { - private RenderingContext renderingContext; + private @Nullable RenderingContext renderingContext; public Builder withRenderingContext(RenderingContext renderingContext) { this.renderingContext = renderingContext; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/package-info.java b/src/main/java/org/mybatis/dynamic/sql/select/render/package-info.java new file mode 100644 index 000000000..d2f457254 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.select.render; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java index 75ccc9ac2..b6e3379e5 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java @@ -24,7 +24,7 @@ import java.util.function.Function; import java.util.function.Supplier; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.SortSpecification; import org.mybatis.dynamic.sql.SqlColumn; @@ -53,13 +53,13 @@ public class UpdateDSL<R> implements AbstractWhereStarter<UpdateDSL<R>.UpdateWhe private final Function<UpdateModel, R> adapterFunction; private final List<AbstractColumnMapping> columnMappings = new ArrayList<>(); private final SqlTable table; - private final String tableAlias; - private UpdateWhereBuilder whereBuilder; + private final @Nullable String tableAlias; + private @Nullable UpdateWhereBuilder whereBuilder; private final StatementConfiguration statementConfiguration = new StatementConfiguration(); - private Long limit; - private OrderByModel orderByModel; + private @Nullable Long limit; + private @Nullable OrderByModel orderByModel; - private UpdateDSL(SqlTable table, String tableAlias, Function<UpdateModel, R> adapterFunction) { + private UpdateDSL(SqlTable table, @Nullable String tableAlias, Function<UpdateModel, R> adapterFunction) { this.table = Objects.requireNonNull(table); this.tableAlias = tableAlias; this.adapterFunction = Objects.requireNonNull(adapterFunction); @@ -79,7 +79,7 @@ public UpdateDSL<R> limit(long limit) { return limitWhenPresent(limit); } - public UpdateDSL<R> limitWhenPresent(Long limit) { + public UpdateDSL<R> limitWhenPresent(@Nullable Long limit) { this.limit = limit; return this; } @@ -99,7 +99,6 @@ public UpdateDSL<R> orderBy(Collection<? extends SortSpecification> columns) { * * @return the update model */ - @NotNull @Override public R build() { UpdateModel updateModel = UpdateModel.withTable(table) @@ -120,7 +119,8 @@ public UpdateDSL<R> configureStatement(Consumer<StatementConfiguration> consumer return this; } - public static <R> UpdateDSL<R> update(Function<UpdateModel, R> adapterFunction, SqlTable table, String tableAlias) { + public static <R> UpdateDSL<R> update(Function<UpdateModel, R> adapterFunction, SqlTable table, + @Nullable String tableAlias) { return new UpdateDSL<>(table, tableAlias, adapterFunction); } @@ -216,7 +216,6 @@ public UpdateDSL<R> orderBy(Collection<? extends SortSpecification> columns) { return UpdateDSL.this; } - @NotNull @Override public R build() { return UpdateDSL.this.build(); diff --git a/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java b/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java index 813ad51f8..7fd07f766 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/UpdateModel.java @@ -21,7 +21,7 @@ import java.util.Optional; import java.util.stream.Stream; -import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.common.CommonBuilder; import org.mybatis.dynamic.sql.common.OrderByModel; @@ -35,11 +35,11 @@ public class UpdateModel { private final SqlTable table; - private final String tableAlias; - private final EmbeddedWhereModel whereModel; + private final @Nullable String tableAlias; + private final @Nullable EmbeddedWhereModel whereModel; private final List<AbstractColumnMapping> columnMappings; - private final Long limit; - private final OrderByModel orderByModel; + private final @Nullable Long limit; + private final @Nullable OrderByModel orderByModel; private final StatementConfiguration statementConfiguration; private UpdateModel(Builder builder) { @@ -81,7 +81,6 @@ public StatementConfiguration statementConfiguration() { return statementConfiguration; } - @NotNull public UpdateStatementProvider render(RenderingStrategy renderingStrategy) { return UpdateRenderer.withUpdateModel(this) .withRenderingStrategy(renderingStrategy) diff --git a/src/main/java/org/mybatis/dynamic/sql/update/package-info.java b/src/main/java/org/mybatis/dynamic/sql/update/package-info.java new file mode 100644 index 000000000..b1b75a4f4 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/update/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.update; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/update/render/DefaultUpdateStatementProvider.java b/src/main/java/org/mybatis/dynamic/sql/update/render/DefaultUpdateStatementProvider.java index 5e2d5d355..eb7f9fba6 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/render/DefaultUpdateStatementProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/render/DefaultUpdateStatementProvider.java @@ -19,6 +19,8 @@ import java.util.Map; import java.util.Objects; +import org.jspecify.annotations.Nullable; + public class DefaultUpdateStatementProvider implements UpdateStatementProvider { private final String updateStatement; private final Map<String, Object> parameters; @@ -43,7 +45,7 @@ public static Builder withUpdateStatement(String updateStatement) { } public static class Builder { - private String updateStatement; + private @Nullable String updateStatement; private final Map<String, Object> parameters = new HashMap<>(); public Builder withUpdateStatement(String updateStatement) { diff --git a/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java b/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java index 0e057ad47..5667830e2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/render/SetPhraseVisitor.java @@ -18,6 +18,7 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.render.RenderedParameterInfo; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.render.SubQueryRenderer; @@ -103,7 +104,7 @@ public Optional<FragmentAndParameters> visit(ColumnToColumnMapping mapping) { return Optional.of(fragmentAndParameters); } - private <T> Optional<FragmentAndParameters> buildValueFragment(AbstractColumnMapping mapping, T value) { + private <T> Optional<FragmentAndParameters> buildValueFragment(AbstractColumnMapping mapping, @Nullable T value) { RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo(mapping.column()); String setPhrase = renderingContext.aliasedColumnName(mapping.column()) + " = " //$NON-NLS-1$ 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 a22b8f756..2a3599788 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 @@ -20,6 +20,7 @@ import java.util.Optional; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.common.OrderByRenderer; import org.mybatis.dynamic.sql.render.ExplicitTableAliasCalculator; @@ -128,8 +129,8 @@ public static Builder withUpdateModel(UpdateModel updateModel) { } public static class Builder { - private UpdateModel updateModel; - private RenderingStrategy renderingStrategy; + private @Nullable UpdateModel updateModel; + private @Nullable RenderingStrategy renderingStrategy; public Builder withUpdateModel(UpdateModel updateModel) { this.updateModel = updateModel; diff --git a/src/main/java/org/mybatis/dynamic/sql/update/render/package-info.java b/src/main/java/org/mybatis/dynamic/sql/update/render/package-info.java new file mode 100644 index 000000000..625393ac4 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/update/render/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.update.render; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/util/Buildable.java b/src/main/java/org/mybatis/dynamic/sql/util/Buildable.java index dcb9fde70..d65130a6e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/Buildable.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/Buildable.java @@ -15,10 +15,7 @@ */ package org.mybatis.dynamic.sql.util; -import org.jetbrains.annotations.NotNull; - @FunctionalInterface public interface Buildable<T> { - @NotNull T build(); } \ No newline at end of file diff --git a/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java b/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java index 44a679201..cbbbf1e3b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java @@ -22,6 +22,8 @@ import java.util.Optional; import java.util.function.UnaryOperator; +import org.jspecify.annotations.Nullable; + public class FragmentAndParameters { private final String fragment; @@ -61,7 +63,7 @@ public static FragmentAndParameters fromFragment(String fragment) { } public static class Builder { - private String fragment; + private @Nullable String fragment; private final Map<String, Object> parameters = new HashMap<>(); public Builder withFragment(String fragment) { @@ -69,7 +71,8 @@ public Builder withFragment(String fragment) { return this; } - public Builder withParameter(String key, Object value) { + public Builder withParameter(String key, @Nullable Object value) { + //noinspection DataFlowIssue parameters.put(key, value); return this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/util/Predicates.java b/src/main/java/org/mybatis/dynamic/sql/util/Predicates.java index d840a214a..4fb7efa99 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/Predicates.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/Predicates.java @@ -17,10 +17,12 @@ import java.util.function.BiPredicate; +import org.jspecify.annotations.Nullable; + public class Predicates { private Predicates() {} - public static <T> BiPredicate<T, T> bothPresent() { + public static <T> BiPredicate<@Nullable T, @Nullable T> bothPresent() { return (v1, v2) -> v1 != null && v2 != null; } } diff --git a/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java b/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java index ea993d420..3104c2905 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java @@ -15,6 +15,8 @@ */ package org.mybatis.dynamic.sql.util; +import org.jspecify.annotations.Nullable; + public interface StringUtilities { static String spaceAfter(String in) { @@ -25,7 +27,7 @@ static String spaceBefore(String in) { return " " + in; //$NON-NLS-1$ } - static String safelyUpperCase(String s) { + static @Nullable String safelyUpperCase(@Nullable String s) { return s == null ? null : s.toUpperCase(); } @@ -44,7 +46,7 @@ static String toCamelCase(String inputString) { sb.append(Character.toLowerCase(c)); } } else { - if (sb.length() > 0) { + if (!sb.isEmpty()) { nextUpperCase = true; } } diff --git a/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java b/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java index 4a70597da..e0aa47bc0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java @@ -15,14 +15,28 @@ */ package org.mybatis.dynamic.sql.util; +import java.util.Collection; +import java.util.Objects; import java.util.function.Supplier; +import java.util.stream.Stream; + +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; public interface Utilities { - static <T> T buildIfNecessary(T current, Supplier<T> builder) { + static <T> T buildIfNecessary(@Nullable T current, @NonNull Supplier<T> builder) { return current == null ? builder.get() : current; } - static long safelyUnbox(Long l) { + static long safelyUnbox(@Nullable Long l) { return l == null ? 0 : l; } + + static <T> Stream<@NonNull T> filterNullValues(Stream<@Nullable T> values) { + return values.filter(Objects::nonNull); + } + + static <T> Collection<@NonNull T> removeNullElements(Collection<@Nullable T> values) { + return filterNullValues(values.stream()).toList(); + } } diff --git a/src/main/java/org/mybatis/dynamic/sql/util/ValueMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/ValueMapping.java index 424970f19..fc8681010 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/ValueMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/ValueMapping.java @@ -18,6 +18,7 @@ import java.util.Objects; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlColumn; public class ValueMapping<T> extends AbstractColumnMapping { @@ -32,7 +33,7 @@ private ValueMapping(SqlColumn<T> column, Supplier<T> valueSupplier) { localColumn = Objects.requireNonNull(column); } - public Object value() { + public @Nullable Object value() { return localColumn.convertParameterType(valueSupplier.get()); } diff --git a/src/main/java/org/mybatis/dynamic/sql/util/ValueOrNullMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/ValueOrNullMapping.java index f1198c14d..8be5818e3 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/ValueOrNullMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/ValueOrNullMapping.java @@ -19,11 +19,12 @@ import java.util.Optional; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlColumn; public class ValueOrNullMapping<T> extends AbstractColumnMapping { - private final Supplier<T> valueSupplier; + private final Supplier<@Nullable T> valueSupplier; // keep a reference to the column so we don't lose the type private final SqlColumn<T> localColumn; diff --git a/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java index eb28e8a81..ae1cf9383 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java @@ -19,11 +19,12 @@ import java.util.Optional; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlColumn; public class ValueWhenPresentMapping<T> extends AbstractColumnMapping { - private final Supplier<T> valueSupplier; + private final Supplier<@Nullable T> valueSupplier; // keep a reference to the column so we don't lose the type private final SqlColumn<T> localColumn; @@ -37,7 +38,7 @@ public Optional<Object> value() { return Optional.ofNullable(valueSupplier.get()).map(this::convert); } - private Object convert(T value) { + private @Nullable Object convert(T value) { return localColumn.convertParameterType(value); } diff --git a/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/package-info.java b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/package-info.java new file mode 100644 index 000000000..3eda4b115 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.util.mybatis3; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/util/package-info.java b/src/main/java/org/mybatis/dynamic/sql/util/package-info.java new file mode 100644 index 000000000..82bcfdd13 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/util/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.util; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/util/spring/package-info.java b/src/main/java/org/mybatis/dynamic/sql/util/spring/package-info.java new file mode 100644 index 000000000..1c53822b8 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/util/spring/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.util.spring; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/util/springbatch/package-info.java b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/package-info.java new file mode 100644 index 000000000..16a66a9fe --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/util/springbatch/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.util.springbatch; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereFinisher.java b/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereFinisher.java index cf1604307..260fef7ea 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereFinisher.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereFinisher.java @@ -19,6 +19,8 @@ import java.util.Objects; import java.util.function.Consumer; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AndOrCriteriaGroup; import org.mybatis.dynamic.sql.SqlCriterion; import org.mybatis.dynamic.sql.common.AbstractBooleanExpressionDSL; @@ -37,11 +39,12 @@ void initialize(SqlCriterion sqlCriterion) { setInitialCriterion(sqlCriterion, StatementType.WHERE); } - void initialize(SqlCriterion sqlCriterion, List<AndOrCriteriaGroup> subCriteria) { + void initialize(@Nullable SqlCriterion sqlCriterion, List<AndOrCriteriaGroup> subCriteria) { setInitialCriterion(sqlCriterion, StatementType.WHERE); super.subCriteria.addAll(subCriteria); } + @NonNull @Override public T configureStatement(Consumer<StatementConfiguration> consumer) { parentStatement.configureStatement(consumer); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereStarter.java b/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereStarter.java index 3070bde18..3a037e5e9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereStarter.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereStarter.java @@ -18,6 +18,7 @@ import java.util.Arrays; import java.util.List; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AndOrCriteriaGroup; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.ColumnAndConditionCriterion; @@ -69,7 +70,7 @@ default F where(SqlCriterion initialCriterion, AndOrCriteriaGroup... subCriteria return where(initialCriterion, Arrays.asList(subCriteria)); } - default F where(SqlCriterion initialCriterion, List<AndOrCriteriaGroup> subCriteria) { + default F where(@Nullable SqlCriterion initialCriterion, List<AndOrCriteriaGroup> subCriteria) { SqlCriterion sqlCriterion = new CriteriaGroup.Builder() .withInitialCriterion(initialCriterion) .withSubCriteria(subCriteria) diff --git a/src/main/java/org/mybatis/dynamic/sql/where/WhereDSL.java b/src/main/java/org/mybatis/dynamic/sql/where/WhereDSL.java index 418ed9fde..6a20b57e8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/WhereDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/WhereDSL.java @@ -17,7 +17,6 @@ import java.util.function.Consumer; -import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; import org.mybatis.dynamic.sql.util.Buildable; @@ -52,7 +51,6 @@ protected StandaloneWhereFinisher getThis() { return this; } - @NotNull @Override public WhereModel build() { return new WhereModel.Builder() diff --git a/src/main/java/org/mybatis/dynamic/sql/where/WhereModel.java b/src/main/java/org/mybatis/dynamic/sql/where/WhereModel.java index 1901d1163..27fed4eed 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/WhereModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/WhereModel.java @@ -18,6 +18,7 @@ import java.util.Objects; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.common.AbstractBooleanExpressionModel; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; import org.mybatis.dynamic.sql.render.RenderingContext; @@ -99,7 +100,7 @@ private WhereClauseProvider toWhereClauseProvider(FragmentAndParameters fragment } public static class Builder extends AbstractBuilder<Builder> { - private StatementConfiguration statementConfiguration; + private @Nullable StatementConfiguration statementConfiguration; public Builder withStatementConfiguration(StatementConfiguration statementConfiguration) { this.statementConfiguration = statementConfiguration; diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java index 6a91f8e88..52df9f5f5 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java @@ -17,6 +17,8 @@ import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; + /** * Utility class supporting the "and" part of a between condition. This class supports builders, so it is mutable. * @@ -28,14 +30,14 @@ * the type of condition being built */ public abstract class AndGatherer<T, R> { - protected final T value1; - protected T value2; + protected final @Nullable T value1; + protected @Nullable T value2; - protected AndGatherer(T value1) { + protected AndGatherer(@Nullable T value1) { this.value1 = value1; } - public R and(T value2) { + public R and(@Nullable T value2) { this.value2 = value2; return build(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java index c252abb09..cb469efa1 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java @@ -20,10 +20,11 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractTwoValueCondition; public class IsBetween<T> extends AbstractTwoValueCondition<T> { - private static final IsBetween<?> EMPTY = new IsBetween<Object>(null, null) { + private static final IsBetween<?> EMPTY = new IsBetween<>(null, null) { @Override public boolean isEmpty() { return true; @@ -36,7 +37,7 @@ public static <T> IsBetween<T> empty() { return t; } - protected IsBetween(T value1, T value2) { + protected IsBetween(@Nullable T value1, @Nullable T value2) { super(value1, value2); } @@ -91,7 +92,7 @@ public static <T> Builder<T> isBetween(T value1) { return new Builder<>(value1); } - public static <T> WhenPresentBuilder<T> isBetweenWhenPresent(T value1) { + public static <T> WhenPresentBuilder<T> isBetweenWhenPresent(@Nullable T value1) { return new WhenPresentBuilder<>(value1); } @@ -107,7 +108,7 @@ protected IsBetween<T> build() { } public static class WhenPresentBuilder<T> extends AndGatherer<T, IsBetween<T>> { - private WhenPresentBuilder(T value1) { + private WhenPresentBuilder(@Nullable T value1) { super(value1); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java index 0d1ee2ba0..8e1debf47 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java @@ -18,11 +18,12 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsEqualTo<T> extends AbstractSingleValueCondition<T> { - private static final IsEqualTo<?> EMPTY = new IsEqualTo<Object>(null) { + private static final IsEqualTo<?> EMPTY = new IsEqualTo<>(null) { @Override public boolean isEmpty() { return true; @@ -35,7 +36,7 @@ public static <T> IsEqualTo<T> empty() { return t; } - protected IsEqualTo(T value) { + protected IsEqualTo(@Nullable T value) { super(value); } @@ -44,7 +45,7 @@ public String operator() { return "="; //$NON-NLS-1$ } - public static <T> IsEqualTo<T> of(T value) { + public static <T> IsEqualTo<T> of(@Nullable T value) { return new IsEqualTo<>(value); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToWithSubselect.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToWithSubselect.java index 0c11774be..10bc2c285 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToWithSubselect.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToWithSubselect.java @@ -15,7 +15,6 @@ */ package org.mybatis.dynamic.sql.where.condition; -import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.AbstractSubselectCondition; import org.mybatis.dynamic.sql.select.SelectModel; import org.mybatis.dynamic.sql.util.Buildable; @@ -26,7 +25,6 @@ protected IsEqualToWithSubselect(Buildable<SelectModel> selectModelBuilder) { super(selectModelBuilder); } - @NotNull public static <T> IsEqualToWithSubselect<T> of(Buildable<SelectModel> selectModelBuilder) { return new IsEqualToWithSubselect<>(selectModelBuilder); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java index 673042b89..2f0bca75a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java @@ -18,10 +18,11 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsGreaterThan<T> extends AbstractSingleValueCondition<T> { - private static final IsGreaterThan<?> EMPTY = new IsGreaterThan<Object>(null) { + private static final IsGreaterThan<?> EMPTY = new IsGreaterThan<>(null) { @Override public boolean isEmpty() { return true; @@ -34,7 +35,7 @@ public static <T> IsGreaterThan<T> empty() { return t; } - protected IsGreaterThan(T value) { + protected IsGreaterThan(@Nullable T value) { super(value); } @@ -43,7 +44,7 @@ public String operator() { return ">"; //$NON-NLS-1$ } - public static <T> IsGreaterThan<T> of(T value) { + public static <T> IsGreaterThan<T> of(@Nullable T value) { return new IsGreaterThan<>(value); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java index 3b1e970c9..1b468b3d4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java @@ -18,10 +18,11 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsGreaterThanOrEqualTo<T> extends AbstractSingleValueCondition<T> { - private static final IsGreaterThanOrEqualTo<?> EMPTY = new IsGreaterThanOrEqualTo<Object>(null) { + private static final IsGreaterThanOrEqualTo<?> EMPTY = new IsGreaterThanOrEqualTo<>(null) { @Override public boolean isEmpty() { return true; @@ -34,7 +35,7 @@ public static <T> IsGreaterThanOrEqualTo<T> empty() { return t; } - protected IsGreaterThanOrEqualTo(T value) { + protected IsGreaterThanOrEqualTo(@Nullable T value) { super(value); } @@ -43,7 +44,7 @@ public String operator() { return ">="; //$NON-NLS-1$ } - public static <T> IsGreaterThanOrEqualTo<T> of(T value) { + public static <T> IsGreaterThanOrEqualTo<T> of(@Nullable T value) { return new IsGreaterThanOrEqualTo<>(value); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWithSubselect.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWithSubselect.java index 7f5e0fb7a..05aea23f2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWithSubselect.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWithSubselect.java @@ -15,7 +15,6 @@ */ package org.mybatis.dynamic.sql.where.condition; -import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.AbstractSubselectCondition; import org.mybatis.dynamic.sql.select.SelectModel; import org.mybatis.dynamic.sql.util.Buildable; @@ -26,7 +25,6 @@ protected IsGreaterThanOrEqualToWithSubselect(Buildable<SelectModel> selectModel super(selectModelBuilder); } - @NotNull public static <T> IsGreaterThanOrEqualToWithSubselect<T> of(Buildable<SelectModel> selectModelBuilder) { return new IsGreaterThanOrEqualToWithSubselect<>(selectModelBuilder); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanWithSubselect.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanWithSubselect.java index 5774fc5ec..225423cbd 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanWithSubselect.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanWithSubselect.java @@ -15,7 +15,6 @@ */ package org.mybatis.dynamic.sql.where.condition; -import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.AbstractSubselectCondition; import org.mybatis.dynamic.sql.select.SelectModel; import org.mybatis.dynamic.sql.util.Buildable; @@ -26,7 +25,6 @@ protected IsGreaterThanWithSubselect(Buildable<SelectModel> selectModelBuilder) super(selectModelBuilder); } - @NotNull public static <T> IsGreaterThanWithSubselect<T> of(Buildable<SelectModel> selectModelBuilder) { return new IsGreaterThanWithSubselect<>(selectModelBuilder); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java index 80ad63b44..f18cbbb81 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java @@ -21,6 +21,7 @@ import java.util.function.Predicate; import java.util.function.UnaryOperator; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.StringUtilities; @@ -61,7 +62,7 @@ public IsInCaseInsensitive filter(Predicate<? super String> predicate) { * @param mapper a mapping function to apply to the values, if not empty * @return a new condition with mapped values if renderable, otherwise an empty condition */ - public IsInCaseInsensitive map(UnaryOperator<String> mapper) { + public IsInCaseInsensitive map(UnaryOperator<@Nullable String> mapper) { return mapSupport(mapper, IsInCaseInsensitive::new, IsInCaseInsensitive::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java index c65062323..a2b785627 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java @@ -18,12 +18,13 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.Objects; import java.util.function.Predicate; import java.util.function.UnaryOperator; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; +import org.mybatis.dynamic.sql.util.Utilities; public class IsInCaseInsensitiveWhenPresent extends AbstractListValueCondition<String> implements CaseInsensitiveVisitableCondition { @@ -34,8 +35,8 @@ public static IsInCaseInsensitiveWhenPresent empty() { return EMPTY; } - protected IsInCaseInsensitiveWhenPresent(Collection<String> values) { - super(values.stream().filter(Objects::nonNull).toList()); + protected IsInCaseInsensitiveWhenPresent(Collection<@Nullable String> values) { + super(Utilities.removeNullElements(values)); } @Override @@ -56,15 +57,15 @@ public IsInCaseInsensitiveWhenPresent filter(Predicate<? super String> predicate * @param mapper a mapping function to apply to the values, if not empty * @return a new condition with mapped values if renderable, otherwise an empty condition */ - public IsInCaseInsensitiveWhenPresent map(UnaryOperator<String> mapper) { + public IsInCaseInsensitiveWhenPresent map(UnaryOperator<@Nullable String> mapper) { return mapSupport(mapper, IsInCaseInsensitiveWhenPresent::new, IsInCaseInsensitiveWhenPresent::empty); } - public static IsInCaseInsensitiveWhenPresent of(String... values) { + public static IsInCaseInsensitiveWhenPresent of(@Nullable String... values) { return of(Arrays.asList(values)); } - public static IsInCaseInsensitiveWhenPresent of(Collection<String> values) { + public static IsInCaseInsensitiveWhenPresent of(Collection<@Nullable String> values) { return new IsInCaseInsensitiveWhenPresent(values).map(StringUtilities::safelyUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java index 458bab590..ea1bfe509 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java @@ -22,6 +22,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; public class IsInWhenPresent<T> extends AbstractListValueCondition<T> { @@ -61,11 +62,11 @@ public <R> IsInWhenPresent<R> map(Function<? super T, ? extends R> mapper) { } @SafeVarargs - public static <T> IsInWhenPresent<T> of(T... values) { + public static <T> IsInWhenPresent<T> of(@Nullable T... values) { return of(Arrays.asList(values)); } - public static <T> IsInWhenPresent<T> of(Collection<T> values) { + public static <T> IsInWhenPresent<T> of(Collection<@Nullable T> values) { return new IsInWhenPresent<>(values); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWithSubselect.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWithSubselect.java index 60b936305..771e2637b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWithSubselect.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWithSubselect.java @@ -15,7 +15,6 @@ */ package org.mybatis.dynamic.sql.where.condition; -import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.AbstractSubselectCondition; import org.mybatis.dynamic.sql.select.SelectModel; import org.mybatis.dynamic.sql.util.Buildable; @@ -26,7 +25,6 @@ protected IsInWithSubselect(Buildable<SelectModel> selectModelBuilder) { super(selectModelBuilder); } - @NotNull public static <T> IsInWithSubselect<T> of(Buildable<SelectModel> selectModelBuilder) { return new IsInWithSubselect<>(selectModelBuilder); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java index 764e92c1c..dde49af88 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java @@ -18,10 +18,11 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsLessThan<T> extends AbstractSingleValueCondition<T> { - private static final IsLessThan<?> EMPTY = new IsLessThan<Object>(null) { + private static final IsLessThan<?> EMPTY = new IsLessThan<>(null) { @Override public boolean isEmpty() { return true; @@ -34,7 +35,7 @@ public static <T> IsLessThan<T> empty() { return t; } - protected IsLessThan(T value) { + protected IsLessThan(@Nullable T value) { super(value); } @@ -43,7 +44,7 @@ public String operator() { return "<"; //$NON-NLS-1$ } - public static <T> IsLessThan<T> of(T value) { + public static <T> IsLessThan<T> of(@Nullable T value) { return new IsLessThan<>(value); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java index a853838c3..d529b57bf 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java @@ -18,10 +18,11 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsLessThanOrEqualTo<T> extends AbstractSingleValueCondition<T> { - private static final IsLessThanOrEqualTo<?> EMPTY = new IsLessThanOrEqualTo<Object>(null) { + private static final IsLessThanOrEqualTo<?> EMPTY = new IsLessThanOrEqualTo<>(null) { @Override public boolean isEmpty() { return true; @@ -34,7 +35,7 @@ public static <T> IsLessThanOrEqualTo<T> empty() { return t; } - protected IsLessThanOrEqualTo(T value) { + protected IsLessThanOrEqualTo(@Nullable T value) { super(value); } @@ -43,7 +44,7 @@ public String operator() { return "<="; //$NON-NLS-1$ } - public static <T> IsLessThanOrEqualTo<T> of(T value) { + public static <T> IsLessThanOrEqualTo<T> of(@Nullable T value) { return new IsLessThanOrEqualTo<>(value); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToWithSubselect.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToWithSubselect.java index 58895b8bc..7a7769016 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToWithSubselect.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToWithSubselect.java @@ -15,7 +15,6 @@ */ package org.mybatis.dynamic.sql.where.condition; -import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.AbstractSubselectCondition; import org.mybatis.dynamic.sql.select.SelectModel; import org.mybatis.dynamic.sql.util.Buildable; @@ -26,7 +25,6 @@ protected IsLessThanOrEqualToWithSubselect(Buildable<SelectModel> selectModelBui super(selectModelBuilder); } - @NotNull public static <T> IsLessThanOrEqualToWithSubselect<T> of(Buildable<SelectModel> selectModelBuilder) { return new IsLessThanOrEqualToWithSubselect<>(selectModelBuilder); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanWithSubselect.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanWithSubselect.java index efc62b982..91a2765a4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanWithSubselect.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanWithSubselect.java @@ -15,7 +15,6 @@ */ package org.mybatis.dynamic.sql.where.condition; -import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.AbstractSubselectCondition; import org.mybatis.dynamic.sql.select.SelectModel; import org.mybatis.dynamic.sql.util.Buildable; @@ -26,7 +25,6 @@ protected IsLessThanWithSubselect(Buildable<SelectModel> selectModelBuilder) { super(selectModelBuilder); } - @NotNull public static <T> IsLessThanWithSubselect<T> of(Buildable<SelectModel> selectModelBuilder) { return new IsLessThanWithSubselect<>(selectModelBuilder); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java index 233485ff4..293d9b9d8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java @@ -18,10 +18,11 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsLike<T> extends AbstractSingleValueCondition<T> { - private static final IsLike<?> EMPTY = new IsLike<Object>(null) { + private static final IsLike<?> EMPTY = new IsLike<>(null) { @Override public boolean isEmpty() { return true; @@ -34,7 +35,7 @@ public static <T> IsLike<T> empty() { return t; } - protected IsLike(T value) { + protected IsLike(@Nullable T value) { super(value); } @@ -43,7 +44,7 @@ public String operator() { return "like"; //$NON-NLS-1$ } - public static <T> IsLike<T> of(T value) { + public static <T> IsLike<T> of(@Nullable T value) { return new IsLike<>(value); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java index 430eb41df..0ec1b7a60 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java @@ -18,6 +18,7 @@ import java.util.function.Predicate; import java.util.function.UnaryOperator; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; @@ -34,7 +35,7 @@ public static IsLikeCaseInsensitive empty() { return EMPTY; } - protected IsLikeCaseInsensitive(String value) { + protected IsLikeCaseInsensitive(@Nullable String value) { super(value); } @@ -44,7 +45,7 @@ public String operator() { } @Override - public IsLikeCaseInsensitive filter(Predicate<? super String> predicate) { + public IsLikeCaseInsensitive filter(Predicate<? super @Nullable String> predicate) { return filterSupport(predicate, IsLikeCaseInsensitive::empty, this); } @@ -56,11 +57,11 @@ public IsLikeCaseInsensitive filter(Predicate<? super String> predicate) { * @return a new condition with the result of applying the mapper to the value of this condition, * if renderable, otherwise a condition that will not render. */ - public IsLikeCaseInsensitive map(UnaryOperator<String> mapper) { + public IsLikeCaseInsensitive map(UnaryOperator<@Nullable String> mapper) { return mapSupport(mapper, IsLikeCaseInsensitive::new, IsLikeCaseInsensitive::empty); } - public static IsLikeCaseInsensitive of(String value) { + public static IsLikeCaseInsensitive of(@Nullable String value) { return new IsLikeCaseInsensitive(value).map(StringUtilities::safelyUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java index b449571bb..ddbfc4747 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java @@ -20,10 +20,11 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractTwoValueCondition; public class IsNotBetween<T> extends AbstractTwoValueCondition<T> { - private static final IsNotBetween<?> EMPTY = new IsNotBetween<Object>(null, null) { + private static final IsNotBetween<?> EMPTY = new IsNotBetween<>(null, null) { @Override public boolean isEmpty() { return true; @@ -36,7 +37,7 @@ public static <T> IsNotBetween<T> empty() { return t; } - protected IsNotBetween(T value1, T value2) { + protected IsNotBetween(@Nullable T value1, @Nullable T value2) { super(value1, value2); } @@ -92,7 +93,7 @@ public static <T> Builder<T> isNotBetween(T value1) { return new Builder<>(value1); } - public static <T> WhenPresentBuilder<T> isNotBetweenWhenPresent(T value1) { + public static <T> WhenPresentBuilder<T> isNotBetweenWhenPresent(@Nullable T value1) { return new WhenPresentBuilder<>(value1); } @@ -110,7 +111,7 @@ protected IsNotBetween<T> build() { public static class WhenPresentBuilder<T> extends AndGatherer<T, IsNotBetween<T>> { - private WhenPresentBuilder(T value1) { + private WhenPresentBuilder(@Nullable T value1) { super(value1); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java index 6af567f9d..8fbd793c0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java @@ -18,10 +18,11 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsNotEqualTo<T> extends AbstractSingleValueCondition<T> { - private static final IsNotEqualTo<?> EMPTY = new IsNotEqualTo<Object>(null) { + private static final IsNotEqualTo<?> EMPTY = new IsNotEqualTo<>(null) { @Override public boolean isEmpty() { return true; @@ -34,7 +35,7 @@ public static <T> IsNotEqualTo<T> empty() { return t; } - protected IsNotEqualTo(T value) { + protected IsNotEqualTo(@Nullable T value) { super(value); } @@ -43,7 +44,7 @@ public String operator() { return "<>"; //$NON-NLS-1$ } - public static <T> IsNotEqualTo<T> of(T value) { + public static <T> IsNotEqualTo<T> of(@Nullable T value) { return new IsNotEqualTo<>(value); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToWithSubselect.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToWithSubselect.java index f9651646d..2e19d9a19 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToWithSubselect.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToWithSubselect.java @@ -15,7 +15,6 @@ */ package org.mybatis.dynamic.sql.where.condition; -import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.AbstractSubselectCondition; import org.mybatis.dynamic.sql.select.SelectModel; import org.mybatis.dynamic.sql.util.Buildable; @@ -26,7 +25,6 @@ protected IsNotEqualToWithSubselect(Buildable<SelectModel> selectModelBuilder) { super(selectModelBuilder); } - @NotNull public static <T> IsNotEqualToWithSubselect<T> of(Buildable<SelectModel> selectModelBuilder) { return new IsNotEqualToWithSubselect<>(selectModelBuilder); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java index 2045c8096..5d97d151a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java @@ -21,6 +21,7 @@ import java.util.function.Predicate; import java.util.function.UnaryOperator; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.StringUtilities; @@ -61,7 +62,7 @@ public IsNotInCaseInsensitive filter(Predicate<? super String> predicate) { * @param mapper a mapping function to apply to the values, if not empty * @return a new condition with mapped values if renderable, otherwise an empty condition */ - public IsNotInCaseInsensitive map(UnaryOperator<String> mapper) { + public IsNotInCaseInsensitive map(UnaryOperator<@Nullable String> mapper) { return mapSupport(mapper, IsNotInCaseInsensitive::new, IsNotInCaseInsensitive::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java index 65a1311e8..409455227 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java @@ -18,12 +18,13 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.Objects; import java.util.function.Predicate; import java.util.function.UnaryOperator; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; +import org.mybatis.dynamic.sql.util.Utilities; public class IsNotInCaseInsensitiveWhenPresent extends AbstractListValueCondition<String> implements CaseInsensitiveVisitableCondition { @@ -34,8 +35,8 @@ public static IsNotInCaseInsensitiveWhenPresent empty() { return EMPTY; } - protected IsNotInCaseInsensitiveWhenPresent(Collection<String> values) { - super(values.stream().filter(Objects::nonNull).toList()); + protected IsNotInCaseInsensitiveWhenPresent(Collection<@Nullable String> values) { + super(Utilities.removeNullElements(values)); } @Override @@ -56,15 +57,15 @@ public IsNotInCaseInsensitiveWhenPresent filter(Predicate<? super String> predic * @param mapper a mapping function to apply to the values, if not empty * @return a new condition with mapped values if renderable, otherwise an empty condition */ - public IsNotInCaseInsensitiveWhenPresent map(UnaryOperator<String> mapper) { + public IsNotInCaseInsensitiveWhenPresent map(UnaryOperator<@Nullable String> mapper) { return mapSupport(mapper, IsNotInCaseInsensitiveWhenPresent::new, IsNotInCaseInsensitiveWhenPresent::empty); } - public static IsNotInCaseInsensitiveWhenPresent of(String... values) { + public static IsNotInCaseInsensitiveWhenPresent of(@Nullable String... values) { return of(Arrays.asList(values)); } - public static IsNotInCaseInsensitiveWhenPresent of(Collection<String> values) { + public static IsNotInCaseInsensitiveWhenPresent of(Collection<@Nullable String> values) { return new IsNotInCaseInsensitiveWhenPresent(values).map(StringUtilities::safelyUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWithSubselect.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWithSubselect.java index 0892afd96..f6f3764f1 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWithSubselect.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWithSubselect.java @@ -15,7 +15,6 @@ */ package org.mybatis.dynamic.sql.where.condition; -import org.jetbrains.annotations.NotNull; import org.mybatis.dynamic.sql.AbstractSubselectCondition; import org.mybatis.dynamic.sql.select.SelectModel; import org.mybatis.dynamic.sql.util.Buildable; @@ -26,7 +25,6 @@ protected IsNotInWithSubselect(Buildable<SelectModel> selectModelBuilder) { super(selectModelBuilder); } - @NotNull public static <T> IsNotInWithSubselect<T> of(Buildable<SelectModel> selectModelBuilder) { return new IsNotInWithSubselect<>(selectModelBuilder); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java index f1b6c6ee6..c27496a40 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java @@ -18,10 +18,11 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsNotLike<T> extends AbstractSingleValueCondition<T> { - private static final IsNotLike<?> EMPTY = new IsNotLike<Object>(null) { + private static final IsNotLike<?> EMPTY = new IsNotLike<>(null) { @Override public boolean isEmpty() { return true; @@ -34,7 +35,7 @@ public static <T> IsNotLike<T> empty() { return t; } - protected IsNotLike(T value) { + protected IsNotLike(@Nullable T value) { super(value); } @@ -43,7 +44,7 @@ public String operator() { return "not like"; //$NON-NLS-1$ } - public static <T> IsNotLike<T> of(T value) { + public static <T> IsNotLike<T> of(@Nullable T value) { return new IsNotLike<>(value); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java index b2ba76951..a93878d13 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java @@ -18,6 +18,7 @@ import java.util.function.Predicate; import java.util.function.UnaryOperator; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; @@ -34,7 +35,7 @@ public static IsNotLikeCaseInsensitive empty() { return EMPTY; } - protected IsNotLikeCaseInsensitive(String value) { + protected IsNotLikeCaseInsensitive(@Nullable String value) { super(value); } @@ -44,7 +45,7 @@ public String operator() { } @Override - public IsNotLikeCaseInsensitive filter(Predicate<? super String> predicate) { + public IsNotLikeCaseInsensitive filter(Predicate<? super @Nullable String> predicate) { return filterSupport(predicate, IsNotLikeCaseInsensitive::empty, this); } @@ -58,11 +59,11 @@ public IsNotLikeCaseInsensitive filter(Predicate<? super String> predicate) { * @return a new condition with the result of applying the mapper to the value of this condition, if renderable, * otherwise a condition that will not render. */ - public IsNotLikeCaseInsensitive map(UnaryOperator<String> mapper) { + public IsNotLikeCaseInsensitive map(UnaryOperator<@Nullable String> mapper) { return mapSupport(mapper, IsNotLikeCaseInsensitive::new, IsNotLikeCaseInsensitive::empty); } - public static IsNotLikeCaseInsensitive of(String value) { + public static IsNotLikeCaseInsensitive of(@Nullable String value) { return new IsNotLikeCaseInsensitive(value).map(StringUtilities::safelyUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotNull.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotNull.java index d4e4cf56a..03d558387 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotNull.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotNull.java @@ -20,7 +20,7 @@ import org.mybatis.dynamic.sql.AbstractNoValueCondition; public class IsNotNull<T> extends AbstractNoValueCondition<T> { - private static final IsNotNull<?> EMPTY = new IsNotNull<Object>() { + private static final IsNotNull<?> EMPTY = new IsNotNull<>() { @Override public boolean isEmpty() { return true; diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNull.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNull.java index eae093f10..36c68aa34 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNull.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNull.java @@ -20,7 +20,7 @@ import org.mybatis.dynamic.sql.AbstractNoValueCondition; public class IsNull<T> extends AbstractNoValueCondition<T> { - private static final IsNull<?> EMPTY = new IsNull<Object>() { + private static final IsNull<?> EMPTY = new IsNull<>() { @Override public boolean isEmpty() { return true; diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/package-info.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/package-info.java new file mode 100644 index 000000000..3457063de --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.where.condition; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/where/package-info.java b/src/main/java/org/mybatis/dynamic/sql/where/package-info.java new file mode 100644 index 000000000..194b40e86 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/where/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.where; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java index 879c4f54d..73f456981 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java @@ -19,6 +19,7 @@ import java.util.Objects; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.VisitableCondition; import org.mybatis.dynamic.sql.render.RenderingContext; @@ -56,9 +57,9 @@ public FragmentAndParameters render() { } public static class Builder<T> { - private BindableColumn<T> column; - private VisitableCondition<T> condition; - private RenderingContext renderingContext; + private @Nullable BindableColumn<T> column; + private @Nullable VisitableCondition<T> condition; + private @Nullable RenderingContext renderingContext; public Builder<T> withColumn(BindableColumn<T> column) { this.column = column; diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java index 3b2852f31..1bd7a99fa 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java @@ -20,6 +20,7 @@ import java.util.Objects; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractColumnComparisonCondition; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.AbstractNoValueCondition; @@ -109,7 +110,7 @@ public FragmentAndParameters visit(AbstractColumnComparisonCondition<T> conditio .mapFragment(f -> condition.operator() + spaceBefore(f)); } - private Object convertValue(T value) { + private @Nullable Object convertValue(@Nullable T value) { return column.convertParameterType(value); } @@ -125,8 +126,8 @@ public static <T> Builder<T> withColumn(BindableColumn<T> column) { } public static class Builder<T> { - private BindableColumn<T> column; - private RenderingContext renderingContext; + private @Nullable BindableColumn<T> column; + private @Nullable RenderingContext renderingContext; public Builder<T> withColumn(BindableColumn<T> column) { this.column = column; diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultWhereClauseProvider.java b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultWhereClauseProvider.java index fa8968c16..5a10f77d7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultWhereClauseProvider.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultWhereClauseProvider.java @@ -19,6 +19,8 @@ import java.util.Map; import java.util.Objects; +import org.jspecify.annotations.Nullable; + public class DefaultWhereClauseProvider implements WhereClauseProvider { private final String whereClause; private final Map<String, Object> parameters; @@ -43,7 +45,7 @@ public static Builder withWhereClause(String whereClause) { } public static class Builder { - private String whereClause; + private @Nullable String whereClause; private final Map<String, Object> parameters = new HashMap<>(); public Builder withWhereClause(String whereClause) { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/RenderedCriterion.java b/src/main/java/org/mybatis/dynamic/sql/where/render/RenderedCriterion.java index 690b72eae..1c6b54f27 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/RenderedCriterion.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/RenderedCriterion.java @@ -19,10 +19,11 @@ import java.util.Objects; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.util.FragmentAndParameters; public class RenderedCriterion { - private final String connector; + private final @Nullable String connector; private final FragmentAndParameters fragmentAndParameters; private RenderedCriterion(Builder builder) { @@ -54,8 +55,8 @@ private FragmentAndParameters prependFragment(FragmentAndParameters fragmentAndP } public static class Builder { - private String connector; - private FragmentAndParameters fragmentAndParameters; + private @Nullable String connector; + private @Nullable FragmentAndParameters fragmentAndParameters; public Builder withConnector(String connector) { this.connector = connector; diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/package-info.java b/src/main/java/org/mybatis/dynamic/sql/where/render/package-info.java new file mode 100644 index 000000000..cde1387a3 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package org.mybatis.dynamic.sql.where.render; + +import org.jspecify.annotations.NullMarked; diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/GroupingCriteriaCollector.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/GroupingCriteriaCollector.kt index 32e78b5ff..841539eeb 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/GroupingCriteriaCollector.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/GroupingCriteriaCollector.kt @@ -229,7 +229,7 @@ open class GroupingCriteriaCollector : SubCriteriaCollector() { * * @param condition the condition to be applied to this column, in this scope */ - operator fun <T> BindableColumn<T>.invoke(condition: VisitableCondition<T>) { + operator fun <T : Any> BindableColumn<T>.invoke(condition: VisitableCondition<T>) { initialCriterion = ColumnAndConditionCriterion.withColumn(this) .withCondition(condition) .build() @@ -243,7 +243,7 @@ open class GroupingCriteriaCollector : SubCriteriaCollector() { fun BindableColumn<*>.isNotNull() = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isNotNull()) - infix fun <T> BindableColumn<T>.isEqualTo(value: T & Any) = + infix fun <T : Any> BindableColumn<T>.isEqualTo(value: T) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isEqualTo(value)) infix fun BindableColumn<*>.isEqualTo(subQuery: KotlinSubQueryBuilder.() -> Unit) = @@ -252,10 +252,10 @@ open class GroupingCriteriaCollector : SubCriteriaCollector() { infix fun BindableColumn<*>.isEqualTo(column: BasicColumn) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isEqualTo(column)) - infix fun <T> BindableColumn<T>.isEqualToWhenPresent(value: T?) = + infix fun <T : Any> BindableColumn<T>.isEqualToWhenPresent(value: T?) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isEqualToWhenPresent(value)) - infix fun <T> BindableColumn<T>.isNotEqualTo(value: T & Any) = + infix fun <T : Any> BindableColumn<T>.isNotEqualTo(value: T) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isNotEqualTo(value)) infix fun BindableColumn<*>.isNotEqualTo(subQuery: KotlinSubQueryBuilder.() -> Unit) = @@ -264,10 +264,10 @@ open class GroupingCriteriaCollector : SubCriteriaCollector() { infix fun BindableColumn<*>.isNotEqualTo(column: BasicColumn) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isNotEqualTo(column)) - infix fun <T> BindableColumn<T>.isNotEqualToWhenPresent(value: T?) = + infix fun <T : Any> BindableColumn<T>.isNotEqualToWhenPresent(value: T?) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isNotEqualToWhenPresent(value)) - infix fun <T> BindableColumn<T>.isGreaterThan(value: T & Any) = + infix fun <T : Any> BindableColumn<T>.isGreaterThan(value: T) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isGreaterThan(value)) infix fun BindableColumn<*>.isGreaterThan(subQuery: KotlinSubQueryBuilder.() -> Unit) = @@ -276,10 +276,10 @@ open class GroupingCriteriaCollector : SubCriteriaCollector() { infix fun BindableColumn<*>.isGreaterThan(column: BasicColumn) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isGreaterThan(column)) - infix fun <T> BindableColumn<T>.isGreaterThanWhenPresent(value: T?) = + infix fun <T : Any> BindableColumn<T>.isGreaterThanWhenPresent(value: T?) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isGreaterThanWhenPresent(value)) - infix fun <T> BindableColumn<T>.isGreaterThanOrEqualTo(value: T & Any) = + infix fun <T : Any> BindableColumn<T>.isGreaterThanOrEqualTo(value: T) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isGreaterThanOrEqualTo(value)) infix fun BindableColumn<*>.isGreaterThanOrEqualTo(subQuery: KotlinSubQueryBuilder.() -> Unit) = @@ -288,10 +288,10 @@ open class GroupingCriteriaCollector : SubCriteriaCollector() { infix fun BindableColumn<*>.isGreaterThanOrEqualTo(column: BasicColumn) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isGreaterThanOrEqualTo(column)) - infix fun <T> BindableColumn<T>.isGreaterThanOrEqualToWhenPresent(value: T?) = + infix fun <T : Any> BindableColumn<T>.isGreaterThanOrEqualToWhenPresent(value: T?) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isGreaterThanOrEqualToWhenPresent(value)) - infix fun <T> BindableColumn<T>.isLessThan(value: T & Any) = + infix fun <T : Any> BindableColumn<T>.isLessThan(value: T) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isLessThan(value)) infix fun BindableColumn<*>.isLessThan(subQuery: KotlinSubQueryBuilder.() -> Unit) = @@ -300,10 +300,10 @@ open class GroupingCriteriaCollector : SubCriteriaCollector() { infix fun BindableColumn<*>.isLessThan(column: BasicColumn) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isLessThan(column)) - infix fun <T> BindableColumn<T>.isLessThanWhenPresent(value: T?) = + infix fun <T : Any> BindableColumn<T>.isLessThanWhenPresent(value: T?) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isLessThanWhenPresent(value)) - infix fun <T> BindableColumn<T>.isLessThanOrEqualTo(value: T & Any) = + infix fun <T : Any> BindableColumn<T>.isLessThanOrEqualTo(value: T) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isLessThanOrEqualTo(value)) infix fun BindableColumn<*>.isLessThanOrEqualTo(subQuery: KotlinSubQueryBuilder.() -> Unit) = @@ -312,82 +312,82 @@ open class GroupingCriteriaCollector : SubCriteriaCollector() { infix fun BindableColumn<*>.isLessThanOrEqualTo(column: BasicColumn) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isLessThanOrEqualTo(column)) - infix fun <T> BindableColumn<T>.isLessThanOrEqualToWhenPresent(value: T?) = + infix fun <T : Any> BindableColumn<T>.isLessThanOrEqualToWhenPresent(value: T?) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isLessThanOrEqualToWhenPresent(value)) - fun <T> BindableColumn<T>.isIn(vararg values: T & Any) = isIn(values.asList()) + fun <T : Any> BindableColumn<T>.isIn(vararg values: T) = isIn(values.asList()) @JvmName("isInArray") - infix fun <T> BindableColumn<T>.isIn(values: Array<out T & Any>) = + infix fun <T : Any> BindableColumn<T>.isIn(values: Array<out T>) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isIn(values)) - infix fun <T> BindableColumn<T>.isIn(values: Collection<T & Any>) = + infix fun <T : Any> BindableColumn<T>.isIn(values: Collection<T>) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isIn(values)) infix fun BindableColumn<*>.isIn(subQuery: KotlinSubQueryBuilder.() -> Unit) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isIn(subQuery)) - fun <T> BindableColumn<T>.isInWhenPresent(vararg values: T?) = isInWhenPresent(values.asList()) + fun <T : Any> BindableColumn<T>.isInWhenPresent(vararg values: T?) = isInWhenPresent(values.asList()) @JvmName("isInArrayWhenPresent") - infix fun <T> BindableColumn<T>.isInWhenPresent(values: Array<out T?>?) = + infix fun <T : Any> BindableColumn<T>.isInWhenPresent(values: Array<out T?>?) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isInWhenPresent(values)) - infix fun <T> BindableColumn<T>.isInWhenPresent(values: Collection<T?>?) = + infix fun <T : Any> BindableColumn<T>.isInWhenPresent(values: Collection<T?>?) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isInWhenPresent(values)) - fun <T> BindableColumn<T>.isNotIn(vararg values: T & Any) = isNotIn(values.asList()) + fun <T : Any> BindableColumn<T>.isNotIn(vararg values: T) = isNotIn(values.asList()) @JvmName("isNotInArray") - infix fun <T> BindableColumn<T>.isNotIn(values: Array<out T & Any>) = + infix fun <T : Any> BindableColumn<T>.isNotIn(values: Array<out T>) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isNotIn(values)) - infix fun <T> BindableColumn<T>.isNotIn(values: Collection<T & Any>) = + infix fun <T : Any> BindableColumn<T>.isNotIn(values: Collection<T>) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isNotIn(values)) infix fun BindableColumn<*>.isNotIn(subQuery: KotlinSubQueryBuilder.() -> Unit) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isNotIn(subQuery)) - fun <T> BindableColumn<T>.isNotInWhenPresent(vararg values: T?) = isNotInWhenPresent(values.asList()) + fun <T : Any> BindableColumn<T>.isNotInWhenPresent(vararg values: T?) = isNotInWhenPresent(values.asList()) @JvmName("isNotInArrayWhenPresent") - infix fun <T> BindableColumn<T>.isNotInWhenPresent(values: Array<out T?>?) = + infix fun <T : Any> BindableColumn<T>.isNotInWhenPresent(values: Array<out T?>?) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isNotInWhenPresent(values)) - infix fun <T> BindableColumn<T>.isNotInWhenPresent(values: Collection<T?>?) = + infix fun <T : Any> BindableColumn<T>.isNotInWhenPresent(values: Collection<T?>?) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isNotInWhenPresent(values)) - infix fun <T> BindableColumn<T>.isBetween(value1: T & Any) = - SecondValueCollector<T & Any> { + infix fun <T : Any> BindableColumn<T>.isBetween(value1: T) = + SecondValueCollector<T> { invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isBetween(value1).and(it)) } - infix fun <T> BindableColumn<T>.isBetweenWhenPresent(value1: T?) = + infix fun <T : Any> BindableColumn<T>.isBetweenWhenPresent(value1: T?) = NullableSecondValueCollector<T> { invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isBetweenWhenPresent(value1).and(it)) } - infix fun <T> BindableColumn<T>.isNotBetween(value1: T & Any) = - SecondValueCollector<T & Any> { + infix fun <T : Any> BindableColumn<T>.isNotBetween(value1: T) = + SecondValueCollector<T> { invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isNotBetween(value1).and(it)) } - infix fun <T> BindableColumn<T>.isNotBetweenWhenPresent(value1: T?) = + infix fun <T : Any> BindableColumn<T>.isNotBetweenWhenPresent(value1: T?) = NullableSecondValueCollector<T> { invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isNotBetweenWhenPresent(value1).and(it)) } // for string columns, but generic for columns with type handlers - infix fun <T> BindableColumn<T>.isLike(value: T & Any) = + infix fun <T : Any> BindableColumn<T>.isLike(value: T) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isLike(value)) - infix fun <T> BindableColumn<T>.isLikeWhenPresent(value: T?) = + infix fun <T : Any> BindableColumn<T>.isLikeWhenPresent(value: T?) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isLikeWhenPresent(value)) - infix fun <T> BindableColumn<T>.isNotLike(value: T & Any) = + infix fun <T : Any> BindableColumn<T>.isNotLike(value: T) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isNotLike(value)) - infix fun <T> BindableColumn<T>.isNotLikeWhenPresent(value: T?) = + infix fun <T : Any> BindableColumn<T>.isNotLikeWhenPresent(value: T?) = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isNotLikeWhenPresent(value)) // shortcuts for booleans diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt index e724e3146..f85927682 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt @@ -28,17 +28,17 @@ class JoinCollector { internal fun initialCriterion() = invalidIfNull(criteriaCollector.initialCriterion, "ERROR.22") //$NON-NLS-1$ internal fun subCriteria() = criteriaCollector.subCriteria - fun <T> on(leftColumn: BindableColumn<T>): RightColumnCollector<T> = RightColumnCollector { + fun <T : Any> on(leftColumn: BindableColumn<T>): RightColumnCollector<T> = RightColumnCollector { assertNull(criteriaCollector.initialCriterion, "ERROR.45") //$NON-NLS-1$ criteriaCollector.apply { leftColumn.invoke(it) } } - fun <T> and(leftColumn: BindableColumn<T>): RightColumnCollector<T> = RightColumnCollector { + fun <T : Any> and(leftColumn: BindableColumn<T>): RightColumnCollector<T> = RightColumnCollector { criteriaCollector.and { leftColumn.invoke(it) } } } -class RightColumnCollector<T>(private val joinConditionConsumer: (VisitableCondition<T>) -> Unit) { +class RightColumnCollector<T : Any>(private val joinConditionConsumer: (VisitableCondition<T>) -> Unit) { infix fun equalTo(rightColumn: BindableColumn<T>) = joinConditionConsumer.invoke(SqlBuilder.isEqualTo(rightColumn)) infix fun equalTo(value: T) = joinConditionConsumer.invoke(SqlBuilder.isEqualTo(value)) diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBatchInsertBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBatchInsertBuilder.kt index 2d2d798c7..aa2dd3703 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBatchInsertBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinBatchInsertBuilder.kt @@ -33,7 +33,7 @@ class KotlinBatchInsertBuilder<T : Any> (private val rows: Collection<T>): Build this.table = table } - fun <C> map(column: SqlColumn<C>) = MultiRowInsertColumnMapCompleter(column) { + fun <C : Any> map(column: SqlColumn<C>) = MultiRowInsertColumnMapCompleter(column) { columnMappings.add(it) } @@ -41,7 +41,7 @@ class KotlinBatchInsertBuilder<T : Any> (private val rows: Collection<T>): Build assertNotNull(table, "ERROR.23") //$NON-NLS-1$ return with(BatchInsertDSL.Builder<T>()) { withRecords(rows) - withTable(table) + withTable(table!!) withColumnMappings(columnMappings) build() }.build() diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinGeneralInsertBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinGeneralInsertBuilder.kt index 296d7aa28..413ddcac4 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinGeneralInsertBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinGeneralInsertBuilder.kt @@ -29,7 +29,7 @@ class KotlinGeneralInsertBuilder(private val table: SqlTable) : Buildable<Genera private val columnMappings = mutableListOf<AbstractColumnMapping>() - fun <T> set(column: SqlColumn<T>) = GeneralInsertColumnSetCompleter(column) { + fun <T : Any> set(column: SqlColumn<T>) = GeneralInsertColumnSetCompleter(column) { columnMappings.add(it) } diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertBuilder.kt index e161b5c6e..8b76231f7 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertBuilder.kt @@ -33,7 +33,7 @@ class KotlinInsertBuilder<T : Any> (private val row: T): Buildable<InsertModel<T this.table = table } - fun <C> map(column: SqlColumn<C>) = SingleRowInsertColumnMapCompleter(column) { + fun <C : Any> map(column: SqlColumn<C>) = SingleRowInsertColumnMapCompleter(column) { columnMappings.add(it) } @@ -41,7 +41,7 @@ class KotlinInsertBuilder<T : Any> (private val row: T): Buildable<InsertModel<T assertNotNull(table, "ERROR.25") //$NON-NLS-1$ return with(InsertDSL.Builder<T>()) { withRow(row) - withTable(table) + withTable(table!!) withColumnMappings(columnMappings) build() }.build() diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertColumnMapCompleters.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertColumnMapCompleters.kt index ab49f086a..076001b9e 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertColumnMapCompleters.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinInsertColumnMapCompleters.kt @@ -28,7 +28,7 @@ import org.mybatis.dynamic.sql.util.ValueOrNullMapping import org.mybatis.dynamic.sql.util.ValueWhenPresentMapping @MyBatisDslMarker -sealed class AbstractInsertColumnMapCompleter<T>( +sealed class AbstractInsertColumnMapCompleter<T : Any>( internal val column: SqlColumn<T>, internal val mappingConsumer: (AbstractColumnMapping) -> Unit) { @@ -39,7 +39,7 @@ sealed class AbstractInsertColumnMapCompleter<T>( infix fun toStringConstant(constant: String) = mappingConsumer.invoke(StringConstantMapping.of(column, constant)) } -class MultiRowInsertColumnMapCompleter<T>( +class MultiRowInsertColumnMapCompleter<T : Any>( column: SqlColumn<T>, mappingConsumer: (AbstractColumnMapping) -> Unit) : AbstractInsertColumnMapCompleter<T>(column, mappingConsumer) { @@ -49,7 +49,7 @@ class MultiRowInsertColumnMapCompleter<T>( fun toRow() = mappingConsumer.invoke(RowMapping.of(column)) } -class SingleRowInsertColumnMapCompleter<T>( +class SingleRowInsertColumnMapCompleter<T : Any>( column: SqlColumn<T>, mappingConsumer: (AbstractColumnMapping) -> Unit) : AbstractInsertColumnMapCompleter<T>(column, mappingConsumer) { @@ -62,14 +62,14 @@ class SingleRowInsertColumnMapCompleter<T>( fun toRow() = mappingConsumer.invoke(RowMapping.of(column)) } -class GeneralInsertColumnSetCompleter<T>( +class GeneralInsertColumnSetCompleter<T : Any>( column: SqlColumn<T>, mappingConsumer: (AbstractColumnMapping) -> Unit) : AbstractInsertColumnMapCompleter<T>(column, mappingConsumer) { - infix fun toValue(value: T & Any) = toValue { value } + infix fun toValue(value: T) = toValue { value } - infix fun toValue(value: () -> T & Any) = mappingConsumer.invoke(ValueMapping.of(column, value)) + infix fun toValue(value: () -> T) = mappingConsumer.invoke(ValueMapping.of(column, value)) infix fun toValueOrNull(value: T?) = toValueOrNull { value } diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiRowInsertBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiRowInsertBuilder.kt index f97ca8510..b00a62aef 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiRowInsertBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinMultiRowInsertBuilder.kt @@ -33,7 +33,7 @@ class KotlinMultiRowInsertBuilder<T : Any> (private val rows: Collection<T>): Bu this.table = table } - fun <C> map(column: SqlColumn<C>) = MultiRowInsertColumnMapCompleter(column) { + fun <C : Any> map(column: SqlColumn<C>) = MultiRowInsertColumnMapCompleter(column) { columnMappings.add(it) } @@ -41,7 +41,7 @@ class KotlinMultiRowInsertBuilder<T : Any> (private val rows: Collection<T>): Bu assertNotNull(table, "ERROR.26") //$NON-NLS-1$ return with(MultiRowInsertDSL.Builder<T>()) { withRecords(rows) - withTable(table) + withTable(table!!) withColumnMappings(columnMappings) build() }.build() diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSubQueryBuilders.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSubQueryBuilders.kt index 3ae99d435..9439e4058 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSubQueryBuilders.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSubQueryBuilders.kt @@ -84,11 +84,11 @@ class KotlinInsertSelectSubQueryBuilder : KotlinBaseSubQueryBuilder(), Buildable assertNotNull(table, "ERROR.29") //$NON-NLS-1$ val dsl = if (columnList == null) { - SqlBuilder.insertInto(table) + SqlBuilder.insertInto(table!!) .withSelectStatement { buildSelectModel() } } else { - SqlBuilder.insertInto(table) - .withColumnList(columnList) + SqlBuilder.insertInto(table!!) + .withColumnList(columnList!!) .withSelectStatement { buildSelectModel() } } diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt index 91d14cf58..f83e45add 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinUpdateBuilder.kt @@ -27,7 +27,7 @@ typealias UpdateCompleter = KotlinUpdateBuilder.() -> Unit class KotlinUpdateBuilder(private val dsl: UpdateDSL<UpdateModel>) : KotlinBaseBuilder<UpdateDSL<UpdateModel>>(), Buildable<UpdateModel> { - fun <T> set(column: SqlColumn<T>): KotlinSetClauseFinisher<T> = KotlinSetClauseFinisher(column) + fun <T : Any> set(column: SqlColumn<T>): KotlinSetClauseFinisher<T> = KotlinSetClauseFinisher(column) fun orderBy(vararg columns: SortSpecification) { dsl.orderBy(columns.toList()) @@ -47,7 +47,7 @@ class KotlinUpdateBuilder(private val dsl: UpdateDSL<UpdateModel>) : @MyBatisDslMarker @Suppress("TooManyFunctions") - inner class KotlinSetClauseFinisher<T>(private val column: SqlColumn<T>) { + inner class KotlinSetClauseFinisher<T : Any>(private val column: SqlColumn<T>) { fun equalToNull(): Unit = applyToDsl { set(column).equalToNull() @@ -63,9 +63,9 @@ class KotlinUpdateBuilder(private val dsl: UpdateDSL<UpdateModel>) : set(column).equalToStringConstant(constant) } - infix fun equalTo(value: T & Any): Unit = equalTo { value } + infix fun equalTo(value: T): Unit = equalTo { value } - infix fun equalTo(value: () -> T & Any): Unit = + infix fun equalTo(value: () -> T): Unit = applyToDsl { set(column).equalTo(value) } diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/ColumnExtensions.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/ColumnExtensions.kt index 59e24a82b..ab5f81a2a 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/ColumnExtensions.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/ColumnExtensions.kt @@ -20,17 +20,17 @@ import org.mybatis.dynamic.sql.SqlColumn import org.mybatis.dynamic.sql.select.caseexpression.SearchedCaseModel import org.mybatis.dynamic.sql.select.caseexpression.SimpleCaseModel -infix fun <T> DerivedColumn<T>.`as`(alias: String): DerivedColumn<T> = this.`as`(alias) +infix fun <T : Any> DerivedColumn<T>.`as`(alias: String): DerivedColumn<T> = this.`as`(alias) -infix fun <T> SqlColumn<T>.`as`(alias: String): SqlColumn<T> = this.`as`(alias) +infix fun <T : Any> SqlColumn<T>.`as`(alias: String): SqlColumn<T> = this.`as`(alias) infix fun SearchedCaseModel.`as`(alias: String): SearchedCaseModel = this.`as`(alias) -infix fun <T> SimpleCaseModel<T>.`as`(alias: String): SimpleCaseModel<T> = this.`as`(alias) +infix fun <T : Any> SimpleCaseModel<T>.`as`(alias: String): SimpleCaseModel<T> = this.`as`(alias) /** * Adds a qualifier to a column for use with table aliases (typically in joins or sub queries). * This is as close to natural SQL syntax as we can get in Kotlin. Natural SQL would look like * "qualifier.column". With this function we can say "qualifier(column)". */ -operator fun <T> String.invoke(column: SqlColumn<T>): SqlColumn<T> = column.qualifiedWith(this) +operator fun <T : Any> String.invoke(column: SqlColumn<T>): SqlColumn<T> = column.qualifiedWith(this) diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt index 8be26db50..a7fe899d6 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt @@ -129,45 +129,45 @@ fun count(column: BasicColumn): Count = SqlBuilder.count(column) fun countDistinct(column: BasicColumn): CountDistinct = SqlBuilder.countDistinct(column) -fun <T> max(column: BindableColumn<T>): Max<T> = SqlBuilder.max(column) +fun <T : Any> max(column: BindableColumn<T>): Max<T> = SqlBuilder.max(column) -fun <T> min(column: BindableColumn<T>): Min<T> = SqlBuilder.min(column) +fun <T : Any> min(column: BindableColumn<T>): Min<T> = SqlBuilder.min(column) -fun <T> avg(column: BindableColumn<T>): Avg<T> = SqlBuilder.avg(column) +fun <T : Any> avg(column: BindableColumn<T>): Avg<T> = SqlBuilder.avg(column) -fun <T> sum(column: BindableColumn<T>): Sum<T> = SqlBuilder.sum(column) +fun <T : Any> sum(column: BindableColumn<T>): Sum<T> = SqlBuilder.sum(column) fun sum(column: BasicColumn): Sum<*> = SqlBuilder.sum(column) -fun <T> sum(column: BindableColumn<T>, condition: VisitableCondition<T>): Sum<T> = SqlBuilder.sum(column, condition) +fun <T : Any> sum(column: BindableColumn<T>, condition: VisitableCondition<T>): Sum<T> = SqlBuilder.sum(column, condition) // constants -fun <T> constant(constant: String): Constant<T> = SqlBuilder.constant(constant) +fun <T : Any> constant(constant: String): Constant<T> = SqlBuilder.constant(constant) fun stringConstant(constant: String): StringConstant = SqlBuilder.stringConstant(constant) -fun <T> value(value: T): BoundValue<T> = SqlBuilder.value(value) +fun <T : Any> value(value: T): BoundValue<T> = SqlBuilder.value(value) // functions -fun <T> add( +fun <T : Any> add( firstColumn: BindableColumn<T>, secondColumn: BasicColumn, vararg subsequentColumns: BasicColumn ): Add<T> = Add.of(firstColumn, secondColumn, subsequentColumns.asList()) -fun <T> divide( +fun <T : Any> divide( firstColumn: BindableColumn<T>, secondColumn: BasicColumn, vararg subsequentColumns: BasicColumn ): Divide<T> = Divide.of(firstColumn, secondColumn, subsequentColumns.asList()) -fun <T> multiply( +fun <T : Any> multiply( firstColumn: BindableColumn<T>, secondColumn: BasicColumn, vararg subsequentColumns: BasicColumn ): Multiply<T> = Multiply.of(firstColumn, secondColumn, subsequentColumns.asList()) -fun <T> subtract( +fun <T : Any> subtract( firstColumn: BindableColumn<T>, secondColumn: BasicColumn, vararg subsequentColumns: BasicColumn @@ -176,147 +176,147 @@ fun <T> subtract( fun cast(receiver: CastDSL.() -> Unit): Cast = invalidIfNull(CastDSL().apply(receiver).cast, "ERROR.43") -fun <T> concat( +fun <T : Any> concat( firstColumn: BindableColumn<T>, vararg subsequentColumns: BasicColumn ): Concat<T> = Concat.of(firstColumn, subsequentColumns.asList()) -fun <T> concatenate( +fun <T : Any> concatenate( firstColumn: BindableColumn<T>, secondColumn: BasicColumn, vararg subsequentColumns: BasicColumn ): Concatenate<T> = Concatenate.of(firstColumn, secondColumn, subsequentColumns.asList()) -fun <T> applyOperator( +fun <T : Any> applyOperator( operator: String, firstColumn: BindableColumn<T>, secondColumn: BasicColumn, vararg subsequentColumns: BasicColumn ): OperatorFunction<T> = OperatorFunction.of(operator, firstColumn, secondColumn, subsequentColumns.asList()) -fun <T> lower(column: BindableColumn<T>): Lower<T> = SqlBuilder.lower(column) +fun <T : Any> lower(column: BindableColumn<T>): Lower<T> = SqlBuilder.lower(column) -fun <T> substring( +fun <T : Any> substring( column: BindableColumn<T>, offset: Int, length: Int ): Substring<T> = SqlBuilder.substring(column, offset, length) -fun <T> upper(column: BindableColumn<T>): Upper<T> = SqlBuilder.upper(column) +fun <T : Any> upper(column: BindableColumn<T>): Upper<T> = SqlBuilder.upper(column) // conditions for all data types -fun <T> isNull(): IsNull<T> = SqlBuilder.isNull() +fun <T : Any> isNull(): IsNull<T> = SqlBuilder.isNull() -fun <T> isNotNull(): IsNotNull<T> = SqlBuilder.isNotNull() +fun <T : Any> isNotNull(): IsNotNull<T> = SqlBuilder.isNotNull() -fun <T> isEqualTo(value: T & Any): IsEqualTo<T> = SqlBuilder.isEqualTo(value) +fun <T : Any> isEqualTo(value: T): IsEqualTo<T> = SqlBuilder.isEqualTo(value) -fun <T> isEqualTo(subQuery: KotlinSubQueryBuilder.() -> Unit): IsEqualToWithSubselect<T> = +fun <T : Any> isEqualTo(subQuery: KotlinSubQueryBuilder.() -> Unit): IsEqualToWithSubselect<T> = SqlBuilder.isEqualTo(KotlinSubQueryBuilder().apply(subQuery)) -fun <T> isEqualTo(column: BasicColumn): IsEqualToColumn<T> = SqlBuilder.isEqualTo(column) +fun <T : Any> isEqualTo(column: BasicColumn): IsEqualToColumn<T> = SqlBuilder.isEqualTo(column) -fun <T> isEqualToWhenPresent(value: T?): IsEqualTo<T> = SqlBuilder.isEqualToWhenPresent(value) +fun <T : Any> isEqualToWhenPresent(value: T?): IsEqualTo<T> = SqlBuilder.isEqualToWhenPresent(value) -fun <T> isNotEqualTo(value: T & Any): IsNotEqualTo<T> = SqlBuilder.isNotEqualTo(value) +fun <T : Any> isNotEqualTo(value: T): IsNotEqualTo<T> = SqlBuilder.isNotEqualTo(value) -fun <T> isNotEqualTo(subQuery: KotlinSubQueryBuilder.() -> Unit): IsNotEqualToWithSubselect<T> = +fun <T : Any> isNotEqualTo(subQuery: KotlinSubQueryBuilder.() -> Unit): IsNotEqualToWithSubselect<T> = SqlBuilder.isNotEqualTo(KotlinSubQueryBuilder().apply(subQuery)) -fun <T> isNotEqualTo(column: BasicColumn): IsNotEqualToColumn<T> = SqlBuilder.isNotEqualTo(column) +fun <T : Any> isNotEqualTo(column: BasicColumn): IsNotEqualToColumn<T> = SqlBuilder.isNotEqualTo(column) -fun <T> isNotEqualToWhenPresent(value: T?): IsNotEqualTo<T> = SqlBuilder.isNotEqualToWhenPresent(value) +fun <T : Any> isNotEqualToWhenPresent(value: T?): IsNotEqualTo<T> = SqlBuilder.isNotEqualToWhenPresent(value) -fun <T> isGreaterThan(value: T & Any): IsGreaterThan<T> = SqlBuilder.isGreaterThan(value) +fun <T : Any> isGreaterThan(value: T): IsGreaterThan<T> = SqlBuilder.isGreaterThan(value) -fun <T> isGreaterThan(subQuery: KotlinSubQueryBuilder.() -> Unit): IsGreaterThanWithSubselect<T> = +fun <T : Any> isGreaterThan(subQuery: KotlinSubQueryBuilder.() -> Unit): IsGreaterThanWithSubselect<T> = SqlBuilder.isGreaterThan(KotlinSubQueryBuilder().apply(subQuery)) -fun <T> isGreaterThan(column: BasicColumn): IsGreaterThanColumn<T> = SqlBuilder.isGreaterThan(column) +fun <T : Any> isGreaterThan(column: BasicColumn): IsGreaterThanColumn<T> = SqlBuilder.isGreaterThan(column) -fun <T> isGreaterThanWhenPresent(value: T?): IsGreaterThan<T> = SqlBuilder.isGreaterThanWhenPresent(value) +fun <T : Any> isGreaterThanWhenPresent(value: T?): IsGreaterThan<T> = SqlBuilder.isGreaterThanWhenPresent(value) -fun <T> isGreaterThanOrEqualTo(value: T & Any): IsGreaterThanOrEqualTo<T> = SqlBuilder.isGreaterThanOrEqualTo(value) +fun <T : Any> isGreaterThanOrEqualTo(value: T): IsGreaterThanOrEqualTo<T> = SqlBuilder.isGreaterThanOrEqualTo(value) -fun <T> isGreaterThanOrEqualTo(subQuery: KotlinSubQueryBuilder.() -> Unit): IsGreaterThanOrEqualToWithSubselect<T> = +fun <T : Any> isGreaterThanOrEqualTo(subQuery: KotlinSubQueryBuilder.() -> Unit): IsGreaterThanOrEqualToWithSubselect<T> = SqlBuilder.isGreaterThanOrEqualTo(KotlinSubQueryBuilder().apply(subQuery)) -fun <T> isGreaterThanOrEqualTo(column: BasicColumn): IsGreaterThanOrEqualToColumn<T> = +fun <T : Any> isGreaterThanOrEqualTo(column: BasicColumn): IsGreaterThanOrEqualToColumn<T> = SqlBuilder.isGreaterThanOrEqualTo(column) -fun <T> isGreaterThanOrEqualToWhenPresent(value: T?): IsGreaterThanOrEqualTo<T> = +fun <T : Any> isGreaterThanOrEqualToWhenPresent(value: T?): IsGreaterThanOrEqualTo<T> = SqlBuilder.isGreaterThanOrEqualToWhenPresent(value) -fun <T> isLessThan(value: T & Any): IsLessThan<T> = SqlBuilder.isLessThan(value) +fun <T : Any> isLessThan(value: T): IsLessThan<T> = SqlBuilder.isLessThan(value) -fun <T> isLessThan(subQuery: KotlinSubQueryBuilder.() -> Unit): IsLessThanWithSubselect<T> = +fun <T : Any> isLessThan(subQuery: KotlinSubQueryBuilder.() -> Unit): IsLessThanWithSubselect<T> = SqlBuilder.isLessThan(KotlinSubQueryBuilder().apply(subQuery)) -fun <T> isLessThan(column: BasicColumn): IsLessThanColumn<T> = SqlBuilder.isLessThan(column) +fun <T : Any> isLessThan(column: BasicColumn): IsLessThanColumn<T> = SqlBuilder.isLessThan(column) -fun <T> isLessThanWhenPresent(value: T?): IsLessThan<T> = SqlBuilder.isLessThanWhenPresent(value) +fun <T : Any> isLessThanWhenPresent(value: T?): IsLessThan<T> = SqlBuilder.isLessThanWhenPresent(value) -fun <T> isLessThanOrEqualTo(value: T & Any): IsLessThanOrEqualTo<T> = SqlBuilder.isLessThanOrEqualTo(value) +fun <T : Any> isLessThanOrEqualTo(value: T): IsLessThanOrEqualTo<T> = SqlBuilder.isLessThanOrEqualTo(value) -fun <T> isLessThanOrEqualTo(subQuery: KotlinSubQueryBuilder.() -> Unit): IsLessThanOrEqualToWithSubselect<T> = +fun <T : Any> isLessThanOrEqualTo(subQuery: KotlinSubQueryBuilder.() -> Unit): IsLessThanOrEqualToWithSubselect<T> = SqlBuilder.isLessThanOrEqualTo(KotlinSubQueryBuilder().apply(subQuery)) -fun <T> isLessThanOrEqualTo(column: BasicColumn): IsLessThanOrEqualToColumn<T> = SqlBuilder.isLessThanOrEqualTo(column) +fun <T : Any> isLessThanOrEqualTo(column: BasicColumn): IsLessThanOrEqualToColumn<T> = SqlBuilder.isLessThanOrEqualTo(column) -fun <T> isLessThanOrEqualToWhenPresent(value: T?): IsLessThanOrEqualTo<T> = +fun <T : Any> isLessThanOrEqualToWhenPresent(value: T?): IsLessThanOrEqualTo<T> = SqlBuilder.isLessThanOrEqualToWhenPresent(value) -fun <T> isIn(vararg values: T & Any): IsIn<T> = isIn(values.asList()) +fun <T : Any> isIn(vararg values: T): IsIn<T> = isIn(values.asList()) @JvmName("isInArray") -fun <T> isIn(values: Array<out T & Any>): IsIn<T> = SqlBuilder.isIn(values.asList()) +fun <T : Any> isIn(values: Array<out T>): IsIn<T> = SqlBuilder.isIn(values.asList()) -fun <T> isIn(values: Collection<T & Any>): IsIn<T> = SqlBuilder.isIn(values) +fun <T : Any> isIn(values: Collection<T>): IsIn<T> = SqlBuilder.isIn(values) -fun <T> isIn(subQuery: KotlinSubQueryBuilder.() -> Unit): IsInWithSubselect<T> = +fun <T : Any> isIn(subQuery: KotlinSubQueryBuilder.() -> Unit): IsInWithSubselect<T> = SqlBuilder.isIn(KotlinSubQueryBuilder().apply(subQuery)) -fun <T> isInWhenPresent(vararg values: T?): IsInWhenPresent<T> = isInWhenPresent(values.asList()) +fun <T : Any> isInWhenPresent(vararg values: T?): IsInWhenPresent<T> = isInWhenPresent(values.asList()) @JvmName("isInArrayWhenPresent") -fun <T> isInWhenPresent(values: Array<out T?>?): IsInWhenPresent<T> = SqlBuilder.isInWhenPresent(values?.asList()) +fun <T : Any> isInWhenPresent(values: Array<out T?>?): IsInWhenPresent<T> = SqlBuilder.isInWhenPresent(values?.asList()) -fun <T> isInWhenPresent(values: Collection<T?>?): IsInWhenPresent<T> = SqlBuilder.isInWhenPresent(values) +fun <T : Any> isInWhenPresent(values: Collection<T?>?): IsInWhenPresent<T> = SqlBuilder.isInWhenPresent(values) -fun <T> isNotIn(vararg values: T & Any): IsNotIn<T> = isNotIn(values.asList()) +fun <T : Any> isNotIn(vararg values: T): IsNotIn<T> = isNotIn(values.asList()) @JvmName("isNotInArray") -fun <T> isNotIn(values: Array<out T & Any>): IsNotIn<T> = SqlBuilder.isNotIn(values.asList()) +fun <T : Any> isNotIn(values: Array<out T>): IsNotIn<T> = SqlBuilder.isNotIn(values.asList()) -fun <T> isNotIn(values: Collection<T & Any>): IsNotIn<T> = SqlBuilder.isNotIn(values) +fun <T : Any> isNotIn(values: Collection<T>): IsNotIn<T> = SqlBuilder.isNotIn(values) -fun <T> isNotIn(subQuery: KotlinSubQueryBuilder.() -> Unit): IsNotInWithSubselect<T> = +fun <T : Any> isNotIn(subQuery: KotlinSubQueryBuilder.() -> Unit): IsNotInWithSubselect<T> = SqlBuilder.isNotIn(KotlinSubQueryBuilder().apply(subQuery)) -fun <T> isNotInWhenPresent(vararg values: T?): IsNotInWhenPresent<T> = isNotInWhenPresent(values.asList()) +fun <T : Any> isNotInWhenPresent(vararg values: T?): IsNotInWhenPresent<T> = isNotInWhenPresent(values.asList()) @JvmName("isNotInArrayWhenPresent") -fun <T> isNotInWhenPresent(values: Array<out T?>?): IsNotInWhenPresent<T> = SqlBuilder.isNotInWhenPresent(values?.asList()) +fun <T : Any> isNotInWhenPresent(values: Array<out T?>?): IsNotInWhenPresent<T> = SqlBuilder.isNotInWhenPresent(values?.asList()) -fun <T> isNotInWhenPresent(values: Collection<T?>?): IsNotInWhenPresent<T> = SqlBuilder.isNotInWhenPresent(values) +fun <T : Any> isNotInWhenPresent(values: Collection<T?>?): IsNotInWhenPresent<T> = SqlBuilder.isNotInWhenPresent(values) -fun <T> isBetween(value1: T & Any): BetweenBuilder<T & Any> = BetweenBuilder(value1) +fun <T : Any> isBetween(value1: T): BetweenBuilder<T> = BetweenBuilder(value1) -fun <T> isBetweenWhenPresent(value1: T?): BetweenWhenPresentBuilder<T> = BetweenWhenPresentBuilder(value1) +fun <T : Any> isBetweenWhenPresent(value1: T?): BetweenWhenPresentBuilder<T> = BetweenWhenPresentBuilder(value1) -fun <T> isNotBetween(value1: T & Any): NotBetweenBuilder<T & Any> = NotBetweenBuilder(value1) +fun <T : Any> isNotBetween(value1: T): NotBetweenBuilder<T> = NotBetweenBuilder(value1) -fun <T> isNotBetweenWhenPresent(value1: T?): NotBetweenWhenPresentBuilder<T> = +fun <T : Any> isNotBetweenWhenPresent(value1: T?): NotBetweenWhenPresentBuilder<T> = NotBetweenWhenPresentBuilder(value1) // for string columns, but generic for columns with type handlers -fun <T> isLike(value: T & Any): IsLike<T> = SqlBuilder.isLike(value) +fun <T : Any> isLike(value: T): IsLike<T> = SqlBuilder.isLike(value) -fun <T> isLikeWhenPresent(value: T?): IsLike<T> = SqlBuilder.isLikeWhenPresent(value) +fun <T : Any> isLikeWhenPresent(value: T?): IsLike<T> = SqlBuilder.isLikeWhenPresent(value) -fun <T> isNotLike(value: T & Any): IsNotLike<T> = SqlBuilder.isNotLike(value) +fun <T : Any> isNotLike(value: T): IsNotLike<T> = SqlBuilder.isNotLike(value) -fun <T> isNotLikeWhenPresent(value: T?): IsNotLike<T> = SqlBuilder.isNotLikeWhenPresent(value) +fun <T : Any> isNotLikeWhenPresent(value: T?): IsNotLike<T> = SqlBuilder.isNotLikeWhenPresent(value) // shortcuts for booleans fun isTrue(): IsEqualTo<Boolean> = isEqualTo(true) @@ -392,21 +392,21 @@ fun sortColumn(name: String): SortSpecification = SqlBuilder.sortColumn(name) fun sortColumn(tableAlias: String, column: SqlColumn<*>): SortSpecification = SqlBuilder.sortColumn(tableAlias, column) // DSL Support Classes -class BetweenBuilder<T>(private val value1: T) { +class BetweenBuilder<T : Any>(private val value1: T) { fun and(value2: T): IsBetween<T> = SqlBuilder.isBetween(value1).and(value2) } -class BetweenWhenPresentBuilder<T>(private val value1: T?) { +class BetweenWhenPresentBuilder<T : Any>(private val value1: T?) { fun and(value2: T?): IsBetween<T> { return SqlBuilder.isBetweenWhenPresent<T>(value1).and(value2) } } -class NotBetweenBuilder<T>(private val value1: T) { +class NotBetweenBuilder<T : Any>(private val value1: T) { fun and(value2: T): IsNotBetween<T> = SqlBuilder.isNotBetween(value1).and(value2) } -class NotBetweenWhenPresentBuilder<T>(private val value1: T?) { +class NotBetweenWhenPresentBuilder<T : Any>(private val value1: T?) { fun and(value2: T?): IsNotBetween<T> { return SqlBuilder.isNotBetweenWhenPresent<T>(value1).and(value2) } diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/spring/NamedParameterJdbcTemplateExtensions.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/spring/NamedParameterJdbcTemplateExtensions.kt index 8654abe44..6cfd88151 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/spring/NamedParameterJdbcTemplateExtensions.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/spring/NamedParameterJdbcTemplateExtensions.kt @@ -65,7 +65,7 @@ fun NamedParameterJdbcTemplate.deleteFrom(table: SqlTable, completer: DeleteComp delete(org.mybatis.dynamic.sql.util.kotlin.spring.deleteFrom(table, completer)) // batch insert -fun <T> NamedParameterJdbcTemplate.insertBatch(insertStatement: BatchInsert<T>): IntArray = +fun <T : Any> NamedParameterJdbcTemplate.insertBatch(insertStatement: BatchInsert<T>): IntArray = batchUpdate(insertStatement.insertStatementSQL, BatchInsertUtility.createBatch(insertStatement.records)) fun <T : Any> NamedParameterJdbcTemplate.insertBatch( @@ -81,10 +81,10 @@ fun <T : Any> NamedParameterJdbcTemplate.insertBatch( insertBatch(org.mybatis.dynamic.sql.util.kotlin.spring.insertBatch(records, completer)) // single row insert -fun <T> NamedParameterJdbcTemplate.insert(insertStatement: InsertStatementProvider<T>): Int = +fun <T : Any> NamedParameterJdbcTemplate.insert(insertStatement: InsertStatementProvider<T>): Int = update(insertStatement.insertStatement, BeanPropertySqlParameterSource(insertStatement)) -fun <T> NamedParameterJdbcTemplate.insert( +fun <T : Any> NamedParameterJdbcTemplate.insert( insertStatement: InsertStatementProvider<T>, keyHolder: KeyHolder ): Int = @@ -119,10 +119,10 @@ fun <T : Any> NamedParameterJdbcTemplate.insertMultiple( ): Int = insertMultiple(org.mybatis.dynamic.sql.util.kotlin.spring.insertMultiple(records, completer)) -fun <T> NamedParameterJdbcTemplate.insertMultiple(insertStatement: MultiRowInsertStatementProvider<T>): Int = +fun <T : Any> NamedParameterJdbcTemplate.insertMultiple(insertStatement: MultiRowInsertStatementProvider<T>): Int = update(insertStatement.insertStatement, BeanPropertySqlParameterSource(insertStatement)) -fun <T> NamedParameterJdbcTemplate.insertMultiple( +fun <T : Any> NamedParameterJdbcTemplate.insertMultiple( insertStatement: MultiRowInsertStatementProvider<T>, keyHolder: KeyHolder ): Int = From 8e1509201051332c5381eb1442c00331bc73f227 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 2 Jan 2025 15:49:47 -0500 Subject: [PATCH 146/260] JSpecify updates for Between --- .../org/mybatis/dynamic/sql/SqlBuilder.java | 60 +++++++++---------- .../sql/where/condition/IsBetween.java | 4 +- .../sql/where/condition/IsNotBetween.java | 4 +- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java index 4be99f7ae..366472d22 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java @@ -622,7 +622,7 @@ static <T> IsEqualTo<T> isEqualTo(@Nullable T value) { return IsEqualTo.of(value); } - static <T> IsEqualTo<T> isEqualTo(Supplier<T> valueSupplier) { + static <T> IsEqualTo<T> isEqualTo(Supplier<@Nullable T> valueSupplier) { return isEqualTo(valueSupplier.get()); } @@ -638,7 +638,7 @@ static <T> IsEqualTo<T> isEqualToWhenPresent(@Nullable T value) { return IsEqualTo.of(value).filter(Objects::nonNull); } - static <T> IsEqualTo<T> isEqualToWhenPresent(Supplier<T> valueSupplier) { + static <T> IsEqualTo<T> isEqualToWhenPresent(Supplier<@Nullable T> valueSupplier) { return isEqualToWhenPresent(valueSupplier.get()); } @@ -646,7 +646,7 @@ static <T> IsNotEqualTo<T> isNotEqualTo(@Nullable T value) { return IsNotEqualTo.of(value); } - static <T> IsNotEqualTo<T> isNotEqualTo(Supplier<T> valueSupplier) { + static <T> IsNotEqualTo<T> isNotEqualTo(Supplier<@Nullable T> valueSupplier) { return isNotEqualTo(valueSupplier.get()); } @@ -662,7 +662,7 @@ static <T> IsNotEqualTo<T> isNotEqualToWhenPresent(@Nullable T value) { return IsNotEqualTo.of(value).filter(Objects::nonNull); } - static <T> IsNotEqualTo<T> isNotEqualToWhenPresent(Supplier<T> valueSupplier) { + static <T> IsNotEqualTo<T> isNotEqualToWhenPresent(Supplier<@Nullable T> valueSupplier) { return isNotEqualToWhenPresent(valueSupplier.get()); } @@ -670,7 +670,7 @@ static <T> IsGreaterThan<T> isGreaterThan(@Nullable T value) { return IsGreaterThan.of(value); } - static <T> IsGreaterThan<T> isGreaterThan(Supplier<T> valueSupplier) { + static <T> IsGreaterThan<T> isGreaterThan(Supplier<@Nullable T> valueSupplier) { return isGreaterThan(valueSupplier.get()); } @@ -686,7 +686,7 @@ static <T> IsGreaterThan<T> isGreaterThanWhenPresent(@Nullable T value) { return IsGreaterThan.of(value).filter(Objects::nonNull); } - static <T> IsGreaterThan<T> isGreaterThanWhenPresent(Supplier<T> valueSupplier) { + static <T> IsGreaterThan<T> isGreaterThanWhenPresent(Supplier<@Nullable T> valueSupplier) { return isGreaterThanWhenPresent(valueSupplier.get()); } @@ -694,7 +694,7 @@ static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualTo(@Nullable T value) { return IsGreaterThanOrEqualTo.of(value); } - static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualTo(Supplier<T> valueSupplier) { + static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualTo(Supplier<@Nullable T> valueSupplier) { return isGreaterThanOrEqualTo(valueSupplier.get()); } @@ -711,7 +711,7 @@ static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualToWhenPresent(@Nullable return IsGreaterThanOrEqualTo.of(value).filter(Objects::nonNull); } - static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualToWhenPresent(Supplier<T> valueSupplier) { + static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualToWhenPresent(Supplier<@Nullable T> valueSupplier) { return isGreaterThanOrEqualToWhenPresent(valueSupplier.get()); } @@ -719,7 +719,7 @@ static <T> IsLessThan<T> isLessThan(@Nullable T value) { return IsLessThan.of(value); } - static <T> IsLessThan<T> isLessThan(Supplier<T> valueSupplier) { + static <T> IsLessThan<T> isLessThan(Supplier<@Nullable T> valueSupplier) { return isLessThan(valueSupplier.get()); } @@ -735,7 +735,7 @@ static <T> IsLessThan<T> isLessThanWhenPresent(@Nullable T value) { return IsLessThan.of(value).filter(Objects::nonNull); } - static <T> IsLessThan<T> isLessThanWhenPresent(Supplier<T> valueSupplier) { + static <T> IsLessThan<T> isLessThanWhenPresent(Supplier<@Nullable T> valueSupplier) { return isLessThanWhenPresent(valueSupplier.get()); } @@ -743,7 +743,7 @@ static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualTo(@Nullable T value) { return IsLessThanOrEqualTo.of(value); } - static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualTo(Supplier<T> valueSupplier) { + static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualTo(Supplier<@Nullable T> valueSupplier) { return isLessThanOrEqualTo(valueSupplier.get()); } @@ -759,7 +759,7 @@ static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualToWhenPresent(@Nullable T val return IsLessThanOrEqualTo.of(value).filter(Objects::nonNull); } - static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualToWhenPresent(Supplier<T> valueSupplier) { + static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualToWhenPresent(Supplier<@Nullable T> valueSupplier) { return isLessThanOrEqualToWhenPresent(valueSupplier.get()); } @@ -807,11 +807,11 @@ static <T> IsNotInWhenPresent<T> isNotInWhenPresent(@Nullable Collection<@Nullab return values == null ? IsNotInWhenPresent.empty() : IsNotInWhenPresent.of(values); } - static <T> IsBetween.Builder<T> isBetween(T value1) { + static <T> IsBetween.Builder<T> isBetween(@Nullable T value1) { return IsBetween.isBetween(value1); } - static <T> IsBetween.Builder<T> isBetween(Supplier<T> valueSupplier1) { + static <T> IsBetween.Builder<T> isBetween(Supplier<@Nullable T> valueSupplier1) { return isBetween(valueSupplier1.get()); } @@ -819,15 +819,15 @@ static <T> IsBetween.WhenPresentBuilder<T> isBetweenWhenPresent(@Nullable T valu return IsBetween.isBetweenWhenPresent(value1); } - static <T> IsBetween.WhenPresentBuilder<T> isBetweenWhenPresent(Supplier<T> valueSupplier1) { + static <T> IsBetween.WhenPresentBuilder<T> isBetweenWhenPresent(Supplier<@Nullable T> valueSupplier1) { return isBetweenWhenPresent(valueSupplier1.get()); } - static <T> IsNotBetween.Builder<T> isNotBetween(T value1) { + static <T> IsNotBetween.Builder<T> isNotBetween(@Nullable T value1) { return IsNotBetween.isNotBetween(value1); } - static <T> IsNotBetween.Builder<T> isNotBetween(Supplier<T> valueSupplier1) { + static <T> IsNotBetween.Builder<T> isNotBetween(Supplier<@Nullable T> valueSupplier1) { return isNotBetween(valueSupplier1.get()); } @@ -835,16 +835,16 @@ static <T> IsNotBetween.WhenPresentBuilder<T> isNotBetweenWhenPresent(@Nullable return IsNotBetween.isNotBetweenWhenPresent(value1); } - static <T> IsNotBetween.WhenPresentBuilder<T> isNotBetweenWhenPresent(Supplier<T> valueSupplier1) { + static <T> IsNotBetween.WhenPresentBuilder<T> isNotBetweenWhenPresent(Supplier<@Nullable T> valueSupplier1) { return isNotBetweenWhenPresent(valueSupplier1.get()); } // for string columns, but generic for columns with type handlers - static <T> IsLike<T> isLike(T value) { + static <T> IsLike<T> isLike(@Nullable T value) { return IsLike.of(value); } - static <T> IsLike<T> isLike(Supplier<T> valueSupplier) { + static <T> IsLike<T> isLike(Supplier<@Nullable T> valueSupplier) { return isLike(valueSupplier.get()); } @@ -852,15 +852,15 @@ static <T> IsLike<T> isLikeWhenPresent(@Nullable T value) { return IsLike.of(value).filter(Objects::nonNull); } - static <T> IsLike<T> isLikeWhenPresent(Supplier<T> valueSupplier) { + static <T> IsLike<T> isLikeWhenPresent(Supplier<@Nullable T> valueSupplier) { return isLikeWhenPresent(valueSupplier.get()); } - static <T> IsNotLike<T> isNotLike(T value) { + static <T> IsNotLike<T> isNotLike(@Nullable T value) { return IsNotLike.of(value); } - static <T> IsNotLike<T> isNotLike(Supplier<T> valueSupplier) { + static <T> IsNotLike<T> isNotLike(Supplier<@Nullable T> valueSupplier) { return isNotLike(valueSupplier.get()); } @@ -868,7 +868,7 @@ static <T> IsNotLike<T> isNotLikeWhenPresent(@Nullable T value) { return IsNotLike.of(value).filter(Objects::nonNull); } - static <T> IsNotLike<T> isNotLikeWhenPresent(Supplier<T> valueSupplier) { + static <T> IsNotLike<T> isNotLikeWhenPresent(Supplier<@Nullable T> valueSupplier) { return isNotLikeWhenPresent(valueSupplier.get()); } @@ -882,11 +882,11 @@ static IsEqualTo<Boolean> isFalse() { } // conditions for strings only - static IsLikeCaseInsensitive isLikeCaseInsensitive(String value) { + static IsLikeCaseInsensitive isLikeCaseInsensitive(@Nullable String value) { return IsLikeCaseInsensitive.of(value); } - static IsLikeCaseInsensitive isLikeCaseInsensitive(Supplier<String> valueSupplier) { + static IsLikeCaseInsensitive isLikeCaseInsensitive(Supplier<@Nullable String> valueSupplier) { return isLikeCaseInsensitive(valueSupplier.get()); } @@ -894,15 +894,15 @@ static IsLikeCaseInsensitive isLikeCaseInsensitiveWhenPresent(@Nullable String v return IsLikeCaseInsensitive.of(value).filter(Objects::nonNull); } - static IsLikeCaseInsensitive isLikeCaseInsensitiveWhenPresent(Supplier<String> valueSupplier) { + static IsLikeCaseInsensitive isLikeCaseInsensitiveWhenPresent(Supplier<@Nullable String> valueSupplier) { return isLikeCaseInsensitiveWhenPresent(valueSupplier.get()); } - static IsNotLikeCaseInsensitive isNotLikeCaseInsensitive(String value) { + static IsNotLikeCaseInsensitive isNotLikeCaseInsensitive(@Nullable String value) { return IsNotLikeCaseInsensitive.of(value); } - static IsNotLikeCaseInsensitive isNotLikeCaseInsensitive(Supplier<String> valueSupplier) { + static IsNotLikeCaseInsensitive isNotLikeCaseInsensitive(Supplier<@Nullable String> valueSupplier) { return isNotLikeCaseInsensitive(valueSupplier.get()); } @@ -910,7 +910,7 @@ static IsNotLikeCaseInsensitive isNotLikeCaseInsensitiveWhenPresent(@Nullable St return IsNotLikeCaseInsensitive.of(value).filter(Objects::nonNull); } - static IsNotLikeCaseInsensitive isNotLikeCaseInsensitiveWhenPresent(Supplier<String> valueSupplier) { + static IsNotLikeCaseInsensitive isNotLikeCaseInsensitiveWhenPresent(Supplier<@Nullable String> valueSupplier) { return isNotLikeCaseInsensitiveWhenPresent(valueSupplier.get()); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java index cb469efa1..5a87679eb 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java @@ -88,7 +88,7 @@ public <R> IsBetween<R> map(Function<? super T, ? extends R> mapper) { return map(mapper, mapper); } - public static <T> Builder<T> isBetween(T value1) { + public static <T> Builder<T> isBetween(@Nullable T value1) { return new Builder<>(value1); } @@ -97,7 +97,7 @@ public static <T> WhenPresentBuilder<T> isBetweenWhenPresent(@Nullable T value1) } public static class Builder<T> extends AndGatherer<T, IsBetween<T>> { - private Builder(T value1) { + private Builder(@Nullable T value1) { super(value1); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java index ddbfc4747..2f748c18c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java @@ -89,7 +89,7 @@ public <R> IsNotBetween<R> map(Function<? super T, ? extends R> mapper) { return map(mapper, mapper); } - public static <T> Builder<T> isNotBetween(T value1) { + public static <T> Builder<T> isNotBetween(@Nullable T value1) { return new Builder<>(value1); } @@ -99,7 +99,7 @@ public static <T> WhenPresentBuilder<T> isNotBetweenWhenPresent(@Nullable T valu public static class Builder<T> extends AndGatherer<T, IsNotBetween<T>> { - private Builder(T value1) { + private Builder(@Nullable T value1) { super(value1); } From 6daca91884ac6f2ef29033c5179d8e0ef8611d70 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 2 Jan 2025 16:44:54 -0500 Subject: [PATCH 147/260] Further JSpecify refinements --- .../sql/AbstractListValueCondition.java | 23 +++++++++++-------- .../org/mybatis/dynamic/sql/SqlBuilder.java | 16 ++++++------- .../dynamic/sql/insert/GeneralInsertDSL.java | 8 +++---- .../sql/insert/InsertColumnListModel.java | 5 ++-- .../dynamic/sql/select/join/JoinModel.java | 5 ++-- .../mybatis/dynamic/sql/update/UpdateDSL.java | 8 +++---- .../sql/where/condition/AndGatherer.java | 2 +- .../where/condition/IsInCaseInsensitive.java | 6 ++--- .../condition/IsNotInCaseInsensitive.java | 6 ++--- .../where/render/DefaultConditionVisitor.java | 2 +- .../java/examples/animal/data/Length.java | 2 ++ .../custom_render/JsonRenderingStrategy.java | 2 ++ .../joins/ItemMasterDynamicSQLSupport.java | 2 ++ .../examples/joins/UserDynamicSQLSupport.java | 2 ++ .../paging/LimitAndOffsetAdapter.java | 2 ++ .../sharding/TableCodesDynamicSqlSupport.java | 2 ++ .../spring/LastNameParameterConverter.java | 6 +++-- .../spring/YesNoParameterConverter.java | 3 ++- .../examples/type_conversion/ToBase64.java | 2 ++ .../mybatis/dynamic/sql/InvalidSQLTest.java | 5 ++-- .../sql/insert/InsertStatementTest.java | 17 +++++++------- .../sql/where/condition/FilterAndMapTest.java | 13 ++++++----- 22 files changed, 82 insertions(+), 57 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java index 21230c821..965bb975b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java @@ -23,14 +23,16 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; + public abstract class AbstractListValueCondition<T> implements VisitableCondition<T> { - protected final Collection<T> values; + protected final Collection<@Nullable T> values; - protected AbstractListValueCondition(Collection<T> values) { + protected AbstractListValueCondition(Collection<@Nullable T> values) { this.values = Objects.requireNonNull(values); } - public final Stream<T> values() { + public final Stream<@Nullable T> values() { return values.stream(); } @@ -44,18 +46,18 @@ public <R> R accept(ConditionVisitor<T, R> visitor) { return visitor.visit(this); } - private <R> Collection<R> applyMapper(Function<? super T, ? extends R> mapper) { + private <R> Collection<R> applyMapper(Function<? super @Nullable T, ? extends @Nullable R> mapper) { Objects.requireNonNull(mapper); return values.stream().map(mapper).collect(Collectors.toList()); } - private Collection<T> applyFilter(Predicate<? super T> predicate) { + private Collection<T> applyFilter(Predicate<? super @Nullable T> predicate) { Objects.requireNonNull(predicate); return values.stream().filter(predicate).toList(); } - protected <S extends AbstractListValueCondition<T>> S filterSupport(Predicate<? super T> predicate, - Function<Collection<T>, S> constructor, S self, Supplier<S> emptySupplier) { + protected <S extends AbstractListValueCondition<T>> S filterSupport(Predicate<? super @Nullable T> predicate, + Function<Collection<@Nullable T>, S> constructor, S self, Supplier<S> emptySupplier) { if (isEmpty()) { return self; } else { @@ -64,8 +66,9 @@ protected <S extends AbstractListValueCondition<T>> S filterSupport(Predicate<? } } - protected <R, S extends AbstractListValueCondition<R>> S mapSupport(Function<? super T, ? extends R> mapper, - Function<Collection<R>, S> constructor, Supplier<S> emptySupplier) { + protected <R, S extends AbstractListValueCondition<R>> S mapSupport( + Function<? super @Nullable T, ? extends @Nullable R> mapper, + Function<Collection<@Nullable R>, S> constructor, Supplier<S> emptySupplier) { if (isEmpty()) { return emptySupplier.get(); } else { @@ -81,7 +84,7 @@ protected <R, S extends AbstractListValueCondition<R>> S mapSupport(Function<? s * * @return a new condition with filtered values if renderable, otherwise an empty condition */ - public abstract AbstractListValueCondition<T> filter(Predicate<? super T> predicate); + public abstract AbstractListValueCondition<T> filter(Predicate<? super @Nullable T> predicate); public abstract String operator(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java index 366472d22..9f3738f03 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java @@ -764,11 +764,11 @@ static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualToWhenPresent(Supplier<@Nulla } @SafeVarargs - static <T> IsIn<T> isIn(T... values) { + static <T> IsIn<T> isIn(@Nullable T... values) { return IsIn.of(values); } - static <T> IsIn<T> isIn(Collection<T> values) { + static <T> IsIn<T> isIn(Collection<@Nullable T> values) { return IsIn.of(values); } @@ -786,11 +786,11 @@ static <T> IsInWhenPresent<T> isInWhenPresent(@Nullable Collection<@Nullable T> } @SafeVarargs - static <T> IsNotIn<T> isNotIn(T... values) { + static <T> IsNotIn<T> isNotIn(@Nullable T... values) { return IsNotIn.of(values); } - static <T> IsNotIn<T> isNotIn(Collection<T> values) { + static <T> IsNotIn<T> isNotIn(Collection<@Nullable T> values) { return IsNotIn.of(values); } @@ -914,11 +914,11 @@ static IsNotLikeCaseInsensitive isNotLikeCaseInsensitiveWhenPresent(Supplier<@Nu return isNotLikeCaseInsensitiveWhenPresent(valueSupplier.get()); } - static IsInCaseInsensitive isInCaseInsensitive(String... values) { + static IsInCaseInsensitive isInCaseInsensitive(@Nullable String... values) { return IsInCaseInsensitive.of(values); } - static IsInCaseInsensitive isInCaseInsensitive(Collection<String> values) { + static IsInCaseInsensitive isInCaseInsensitive(Collection<@Nullable String> values) { return IsInCaseInsensitive.of(values); } @@ -931,11 +931,11 @@ static IsInCaseInsensitiveWhenPresent isInCaseInsensitiveWhenPresent( return values == null ? IsInCaseInsensitiveWhenPresent.empty() : IsInCaseInsensitiveWhenPresent.of(values); } - static IsNotInCaseInsensitive isNotInCaseInsensitive(String... values) { + static IsNotInCaseInsensitive isNotInCaseInsensitive(@Nullable String... values) { return IsNotInCaseInsensitive.of(values); } - static IsNotInCaseInsensitive isNotInCaseInsensitive(Collection<String> values) { + static IsNotInCaseInsensitive isNotInCaseInsensitive(Collection<@Nullable String> values) { return IsNotInCaseInsensitive.of(values); } diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertDSL.java b/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertDSL.java index 327e5d103..5cba9063d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/GeneralInsertDSL.java @@ -92,20 +92,20 @@ public GeneralInsertDSL toValue(Supplier<T> valueSupplier) { return GeneralInsertDSL.this; } - public GeneralInsertDSL toValueOrNull(T value) { + public GeneralInsertDSL toValueOrNull(@Nullable T value) { return toValueOrNull(() -> value); } - public GeneralInsertDSL toValueOrNull(Supplier<T> valueSupplier) { + public GeneralInsertDSL toValueOrNull(Supplier<@Nullable T> valueSupplier) { columnMappings.add(ValueOrNullMapping.of(column, valueSupplier)); return GeneralInsertDSL.this; } - public GeneralInsertDSL toValueWhenPresent(T value) { + public GeneralInsertDSL toValueWhenPresent(@Nullable T value) { return toValueWhenPresent(() -> value); } - public GeneralInsertDSL toValueWhenPresent(Supplier<T> valueSupplier) { + public GeneralInsertDSL toValueWhenPresent(Supplier<@Nullable T> valueSupplier) { columnMappings.add(ValueWhenPresentMapping.of(column, valueSupplier)); return GeneralInsertDSL.this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/InsertColumnListModel.java b/src/main/java/org/mybatis/dynamic/sql/insert/InsertColumnListModel.java index c1c0669c9..56131f0e9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/InsertColumnListModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/InsertColumnListModel.java @@ -20,13 +20,14 @@ import java.util.Objects; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.util.Validator; public class InsertColumnListModel { private final List<SqlColumn<?>> columns = new ArrayList<>(); - private InsertColumnListModel(List<SqlColumn<?>> columns) { + private InsertColumnListModel(@Nullable List<SqlColumn<?>> columns) { Objects.requireNonNull(columns); Validator.assertNotEmpty(columns, "ERROR.4"); //$NON-NLS-1$ this.columns.addAll(columns); @@ -37,7 +38,7 @@ public Stream<SqlColumn<?>> columns() { return columns.stream(); } - public static InsertColumnListModel of(List<SqlColumn<?>> columns) { + public static InsertColumnListModel of(@Nullable List<SqlColumn<?>> columns) { return new InsertColumnListModel(columns); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/join/JoinModel.java b/src/main/java/org/mybatis/dynamic/sql/select/join/JoinModel.java index ab6cc67db..fe987c1b4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/join/JoinModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/join/JoinModel.java @@ -20,13 +20,14 @@ import java.util.Objects; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.TableExpression; import org.mybatis.dynamic.sql.util.Validator; public class JoinModel { private final List<JoinSpecification> joinSpecifications = new ArrayList<>(); - private JoinModel(List<JoinSpecification> joinSpecifications) { + private JoinModel(@Nullable List<JoinSpecification> joinSpecifications) { Objects.requireNonNull(joinSpecifications); Validator.assertNotEmpty(joinSpecifications, "ERROR.15"); //$NON-NLS-1$ this.joinSpecifications.addAll(joinSpecifications); @@ -36,7 +37,7 @@ public Stream<JoinSpecification> joinSpecifications() { return joinSpecifications.stream(); } - public static JoinModel of(List<JoinSpecification> joinSpecifications) { + public static JoinModel of(@Nullable List<JoinSpecification> joinSpecifications) { return new JoinModel(joinSpecifications); } diff --git a/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java index b6e3379e5..c6fcd50d7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java @@ -174,20 +174,20 @@ public UpdateDSL<R> equalTo(BasicColumn rightColumn) { return UpdateDSL.this; } - public UpdateDSL<R> equalToOrNull(T value) { + public UpdateDSL<R> equalToOrNull(@Nullable T value) { return equalToOrNull(() -> value); } - public UpdateDSL<R> equalToOrNull(Supplier<T> valueSupplier) { + public UpdateDSL<R> equalToOrNull(Supplier<@Nullable T> valueSupplier) { columnMappings.add(ValueOrNullMapping.of(column, valueSupplier)); return UpdateDSL.this; } - public UpdateDSL<R> equalToWhenPresent(T value) { + public UpdateDSL<R> equalToWhenPresent(@Nullable T value) { return equalToWhenPresent(() -> value); } - public UpdateDSL<R> equalToWhenPresent(Supplier<T> valueSupplier) { + public UpdateDSL<R> equalToWhenPresent(Supplier<@Nullable T> valueSupplier) { columnMappings.add(ValueWhenPresentMapping.of(column, valueSupplier)); return UpdateDSL.this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java index 52df9f5f5..c30229d93 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java @@ -42,7 +42,7 @@ public R and(@Nullable T value2) { return build(); } - public R and(Supplier<T> valueSupplier2) { + public R and(Supplier<@Nullable T> valueSupplier2) { return and(valueSupplier2.get()); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java index f18cbbb81..00b6ef445 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java @@ -35,7 +35,7 @@ public static IsInCaseInsensitive empty() { return EMPTY; } - protected IsInCaseInsensitive(Collection<String> values) { + protected IsInCaseInsensitive(Collection<@Nullable String> values) { super(values); } @@ -66,11 +66,11 @@ public IsInCaseInsensitive map(UnaryOperator<@Nullable String> mapper) { return mapSupport(mapper, IsInCaseInsensitive::new, IsInCaseInsensitive::empty); } - public static IsInCaseInsensitive of(String... values) { + public static IsInCaseInsensitive of(@Nullable String... values) { return of(Arrays.asList(values)); } - public static IsInCaseInsensitive of(Collection<String> values) { + public static IsInCaseInsensitive of(Collection<@Nullable String> values) { return new IsInCaseInsensitive(values).map(StringUtilities::safelyUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java index 5d97d151a..88b7529d8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java @@ -35,7 +35,7 @@ public static IsNotInCaseInsensitive empty() { return EMPTY; } - protected IsNotInCaseInsensitive(Collection<String> values) { + protected IsNotInCaseInsensitive(Collection<@Nullable String> values) { super(values); } @@ -66,11 +66,11 @@ public IsNotInCaseInsensitive map(UnaryOperator<@Nullable String> mapper) { return mapSupport(mapper, IsNotInCaseInsensitive::new, IsNotInCaseInsensitive::empty); } - public static IsNotInCaseInsensitive of(String... values) { + public static IsNotInCaseInsensitive of(@Nullable String... values) { return of(Arrays.asList(values)); } - public static IsNotInCaseInsensitive of(Collection<String> values) { + public static IsNotInCaseInsensitive of(Collection<@Nullable String> values) { return new IsNotInCaseInsensitive(values).map(StringUtilities::safelyUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java index 1bd7a99fa..d55e83425 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java @@ -114,7 +114,7 @@ public FragmentAndParameters visit(AbstractColumnComparisonCondition<T> conditio return column.convertParameterType(value); } - private FragmentAndParameters toFragmentAndParameters(T value) { + private FragmentAndParameters toFragmentAndParameters(@Nullable T value) { RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo(column); return FragmentAndParameters.withFragment(parameterInfo.renderedPlaceHolder()) .withParameter(parameterInfo.parameterMapKey(), convertValue(value)) diff --git a/src/test/java/examples/animal/data/Length.java b/src/test/java/examples/animal/data/Length.java index a7a8abcb5..8358ecce6 100644 --- a/src/test/java/examples/animal/data/Length.java +++ b/src/test/java/examples/animal/data/Length.java @@ -18,12 +18,14 @@ import java.sql.JDBCType; import java.util.Optional; +import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.function.AbstractTypeConvertingFunction; import org.mybatis.dynamic.sql.util.FragmentAndParameters; +@NullMarked public class Length extends AbstractTypeConvertingFunction<Object, Integer, Length> { private Length(BasicColumn column) { super(column); diff --git a/src/test/java/examples/custom_render/JsonRenderingStrategy.java b/src/test/java/examples/custom_render/JsonRenderingStrategy.java index 62c822e93..0f9838329 100644 --- a/src/test/java/examples/custom_render/JsonRenderingStrategy.java +++ b/src/test/java/examples/custom_render/JsonRenderingStrategy.java @@ -15,9 +15,11 @@ */ package examples.custom_render; +import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.MyBatis3RenderingStrategy; +@NullMarked public class JsonRenderingStrategy extends MyBatis3RenderingStrategy { @Override diff --git a/src/test/java/examples/joins/ItemMasterDynamicSQLSupport.java b/src/test/java/examples/joins/ItemMasterDynamicSQLSupport.java index 15bf72505..5e5b836fa 100644 --- a/src/test/java/examples/joins/ItemMasterDynamicSQLSupport.java +++ b/src/test/java/examples/joins/ItemMasterDynamicSQLSupport.java @@ -17,9 +17,11 @@ import java.sql.JDBCType; +import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.AliasableSqlTable; import org.mybatis.dynamic.sql.SqlColumn; +@NullMarked public final class ItemMasterDynamicSQLSupport { public static final ItemMaster itemMaster = new ItemMaster(); public static final SqlColumn<Integer> itemId = itemMaster.itemId; diff --git a/src/test/java/examples/joins/UserDynamicSQLSupport.java b/src/test/java/examples/joins/UserDynamicSQLSupport.java index 883cd81e9..05bf6330e 100644 --- a/src/test/java/examples/joins/UserDynamicSQLSupport.java +++ b/src/test/java/examples/joins/UserDynamicSQLSupport.java @@ -17,9 +17,11 @@ import java.sql.JDBCType; +import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.AliasableSqlTable; import org.mybatis.dynamic.sql.SqlColumn; +@NullMarked public class UserDynamicSQLSupport { public static final User user = new User(); public final SqlColumn<Integer> userId = user.userId; diff --git a/src/test/java/examples/paging/LimitAndOffsetAdapter.java b/src/test/java/examples/paging/LimitAndOffsetAdapter.java index de4dafab7..4bf136a8b 100644 --- a/src/test/java/examples/paging/LimitAndOffsetAdapter.java +++ b/src/test/java/examples/paging/LimitAndOffsetAdapter.java @@ -20,6 +20,7 @@ import java.util.Objects; import java.util.function.Function; +import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.render.RenderingStrategies; import org.mybatis.dynamic.sql.select.SelectModel; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; @@ -40,6 +41,7 @@ * * @author Jeff Butler */ +@NullMarked public class LimitAndOffsetAdapter<R> { private final SelectModel selectModel; private final Function<SelectStatementProvider, R> mapperMethod; diff --git a/src/test/java/examples/sharding/TableCodesDynamicSqlSupport.java b/src/test/java/examples/sharding/TableCodesDynamicSqlSupport.java index 6cec6e9c8..96d66c20a 100644 --- a/src/test/java/examples/sharding/TableCodesDynamicSqlSupport.java +++ b/src/test/java/examples/sharding/TableCodesDynamicSqlSupport.java @@ -17,9 +17,11 @@ import java.sql.JDBCType; +import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.AliasableSqlTable; import org.mybatis.dynamic.sql.SqlColumn; +@NullMarked public final class TableCodesDynamicSqlSupport { public static final TableCodes tableCodes = new TableCodes(); public static final SqlColumn<Integer> id = tableCodes.id; diff --git a/src/test/java/examples/spring/LastNameParameterConverter.java b/src/test/java/examples/spring/LastNameParameterConverter.java index 0914bf4e7..d14bfcb32 100644 --- a/src/test/java/examples/spring/LastNameParameterConverter.java +++ b/src/test/java/examples/spring/LastNameParameterConverter.java @@ -15,12 +15,14 @@ */ package examples.spring; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.ParameterTypeConverter; import org.springframework.core.convert.converter.Converter; -public class LastNameParameterConverter implements ParameterTypeConverter<LastName, String>, Converter<LastName, String> { +public class LastNameParameterConverter implements ParameterTypeConverter<LastName, String>, + Converter<LastName, String> { @Override - public String convert(LastName source) { + public @Nullable String convert(@Nullable LastName source) { return source == null ? null : source.getName(); } } diff --git a/src/test/java/examples/spring/YesNoParameterConverter.java b/src/test/java/examples/spring/YesNoParameterConverter.java index 131c0d84a..07fd95ced 100644 --- a/src/test/java/examples/spring/YesNoParameterConverter.java +++ b/src/test/java/examples/spring/YesNoParameterConverter.java @@ -15,12 +15,13 @@ */ package examples.spring; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.ParameterTypeConverter; public class YesNoParameterConverter implements ParameterTypeConverter<Boolean, String> { @Override - public String convert(Boolean source) { + public @Nullable String convert(@Nullable Boolean source) { return source == null ? null : source ? "Yes" : "No"; } } diff --git a/src/test/java/examples/type_conversion/ToBase64.java b/src/test/java/examples/type_conversion/ToBase64.java index 46cdb26ed..d6de2ff76 100644 --- a/src/test/java/examples/type_conversion/ToBase64.java +++ b/src/test/java/examples/type_conversion/ToBase64.java @@ -18,12 +18,14 @@ import java.sql.JDBCType; import java.util.Optional; +import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.function.AbstractTypeConvertingFunction; import org.mybatis.dynamic.sql.util.FragmentAndParameters; +@NullMarked public class ToBase64 extends AbstractTypeConvertingFunction<byte[], String, ToBase64> { protected ToBase64(BasicColumn column) { diff --git a/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java b/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java index 2464a4000..4f96f14de 100644 --- a/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java @@ -27,6 +27,7 @@ import java.util.MissingResourceException; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; @@ -261,9 +262,9 @@ void testInvalidValueAlias() { } static class TestRow { - private Integer id; + private @Nullable Integer id; - public Integer getId() { + public @Nullable Integer getId() { return id; } 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 e991bef02..ef0f94bfc 100644 --- a/src/test/java/org/mybatis/dynamic/sql/insert/InsertStatementTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/insert/InsertStatementTest.java @@ -20,6 +20,7 @@ import java.sql.JDBCType; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.SqlTable; @@ -116,12 +117,12 @@ void testSelectiveInsertStatementBuilder() { } static class TestRecord { - private Integer id; - private String firstName; - private String lastName; - private String occupation; + private @Nullable Integer id; + private @Nullable String firstName; + private @Nullable String lastName; + private @Nullable String occupation; - Integer getId() { + @Nullable Integer getId() { return id; } @@ -129,7 +130,7 @@ void setId(Integer id) { this.id = id; } - String getFirstName() { + @Nullable String getFirstName() { return firstName; } @@ -137,7 +138,7 @@ void setFirstName(String firstName) { this.firstName = firstName; } - String getLastName() { + @Nullable String getLastName() { return lastName; } @@ -145,7 +146,7 @@ void setLastName(String lastName) { this.lastName = lastName; } - String getOccupation() { + @Nullable String getOccupation() { return occupation; } diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java index 68adb5714..0541ce2ed 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Objects; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.SqlBuilder; @@ -431,7 +432,7 @@ void testIsInRenderableMapShouldReturnMappedObject() { IsIn<String> cond = SqlBuilder.isIn("Fred", "Wilma"); assertThat(cond.isEmpty()).isFalse(); IsIn<String> mapped = cond.map(String::toUpperCase); - List<String> mappedValues = mapped.values().toList(); + List<@Nullable String> mappedValues = mapped.values().toList(); assertThat(mappedValues).containsExactly("FRED", "WILMA"); } @@ -440,31 +441,31 @@ void testIsNotInRenderableMapShouldReturnMappedObject() { IsNotIn<String> cond = SqlBuilder.isNotIn("Fred", "Wilma"); assertThat(cond.isEmpty()).isFalse(); IsNotIn<String> mapped = cond.map(String::toUpperCase); - List<String> mappedValues = mapped.values().toList(); + List<@Nullable String> mappedValues = mapped.values().toList(); assertThat(mappedValues).containsExactly("FRED", "WILMA"); } @Test void testIsNotInCaseInsensitiveRenderableMapShouldReturnMappedObject() { IsNotInCaseInsensitive cond = SqlBuilder.isNotInCaseInsensitive("Fred ", "Wilma "); - List<String> values = cond.values().toList(); + List<@Nullable String> values = cond.values().toList(); assertThat(values).containsExactly("FRED ", "WILMA "); assertThat(cond.isEmpty()).isFalse(); IsNotInCaseInsensitive mapped = cond.map(String::trim); - List<String> mappedValues = mapped.values().toList(); + List<@Nullable String> mappedValues = mapped.values().toList(); assertThat(mappedValues).containsExactly("FRED", "WILMA"); } @Test void testIsInCaseInsensitiveRenderableMapShouldReturnMappedObject() { IsInCaseInsensitive cond = SqlBuilder.isInCaseInsensitive("Fred ", "Wilma "); - List<String> values = cond.values().toList(); + List<@Nullable String> values = cond.values().toList(); assertThat(values).containsExactly("FRED ", "WILMA "); assertThat(cond.isEmpty()).isFalse(); IsInCaseInsensitive mapped = cond.map(String::trim); - List<String> mappedValues = mapped.values().toList(); + List<@Nullable String> mappedValues = mapped.values().toList(); assertThat(mappedValues).containsExactly("FRED", "WILMA"); } From 147d40de17b1a263e37004c025e8c2d585567e6b Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 2 Jan 2025 17:12:07 -0500 Subject: [PATCH 148/260] Non-Nullable Type --- .../kotlin/mybatis3/custom/render/KCustomRenderingTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KCustomRenderingTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KCustomRenderingTest.kt index d0c7e7a04..47a6fcaed 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KCustomRenderingTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KCustomRenderingTest.kt @@ -304,7 +304,7 @@ class KCustomRenderingTest { } } - private fun <T> dereference(column: SqlColumn<T>, attribute: String) = + private fun <T : Any> dereference(column: SqlColumn<T>, attribute: String) = SqlColumn.of<String>(column.name() + "->>'" + attribute + "'", column.table(), JDBCType.VARCHAR) companion object { From 16c3880d0f9114d6dd2690b69e00635f455464e6 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 3 Jan 2025 09:39:40 -0500 Subject: [PATCH 149/260] Make ParameterTypeConverter compatible with Spring --- src/main/java/org/mybatis/dynamic/sql/BindableColumn.java | 2 +- .../java/org/mybatis/dynamic/sql/ParameterTypeConverter.java | 2 +- src/main/java/org/mybatis/dynamic/sql/SqlColumn.java | 2 +- .../mybatis/dynamic/sql/util/ValueWhenPresentMapping.java | 2 +- .../java/examples/spring/LastNameParameterConverter.java | 4 ++-- src/test/java/examples/spring/YesNoParameterConverter.java | 5 +++-- 6 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/BindableColumn.java b/src/main/java/org/mybatis/dynamic/sql/BindableColumn.java index a7b7b6697..0fd90b7c8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/BindableColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/BindableColumn.java @@ -36,7 +36,7 @@ public interface BindableColumn<T> extends BasicColumn { @Override BindableColumn<T> as(String alias); - default @Nullable Object convertParameterType(@Nullable T value) { + default @Nullable Object convertParameterType(T value) { return value; } diff --git a/src/main/java/org/mybatis/dynamic/sql/ParameterTypeConverter.java b/src/main/java/org/mybatis/dynamic/sql/ParameterTypeConverter.java index 53a8afefd..a37212e22 100644 --- a/src/main/java/org/mybatis/dynamic/sql/ParameterTypeConverter.java +++ b/src/main/java/org/mybatis/dynamic/sql/ParameterTypeConverter.java @@ -52,5 +52,5 @@ */ @FunctionalInterface public interface ParameterTypeConverter<S, T> { - @Nullable T convert(@Nullable S source); + @Nullable T convert(S source); } diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java b/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java index 5d4e5bc5b..4c841d86b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlColumn.java @@ -81,7 +81,7 @@ public Optional<Class<T>> javaType() { @Override public @Nullable Object convertParameterType(@Nullable T value) { - return parameterTypeConverter.convert(value); + return value == null ? null : parameterTypeConverter.convert(value); } @Override diff --git a/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java index ae1cf9383..cf146651c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java @@ -38,7 +38,7 @@ public Optional<Object> value() { return Optional.ofNullable(valueSupplier.get()).map(this::convert); } - private @Nullable Object convert(T value) { + private @Nullable Object convert(@Nullable T value) { return localColumn.convertParameterType(value); } diff --git a/src/test/java/examples/spring/LastNameParameterConverter.java b/src/test/java/examples/spring/LastNameParameterConverter.java index d14bfcb32..51f972cf6 100644 --- a/src/test/java/examples/spring/LastNameParameterConverter.java +++ b/src/test/java/examples/spring/LastNameParameterConverter.java @@ -22,7 +22,7 @@ public class LastNameParameterConverter implements ParameterTypeConverter<LastName, String>, Converter<LastName, String> { @Override - public @Nullable String convert(@Nullable LastName source) { - return source == null ? null : source.getName(); + public @Nullable String convert(LastName source) { + return source.getName(); } } diff --git a/src/test/java/examples/spring/YesNoParameterConverter.java b/src/test/java/examples/spring/YesNoParameterConverter.java index 07fd95ced..166020620 100644 --- a/src/test/java/examples/spring/YesNoParameterConverter.java +++ b/src/test/java/examples/spring/YesNoParameterConverter.java @@ -15,13 +15,14 @@ */ package examples.spring; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.ParameterTypeConverter; public class YesNoParameterConverter implements ParameterTypeConverter<Boolean, String> { @Override - public @Nullable String convert(@Nullable Boolean source) { - return source == null ? null : source ? "Yes" : "No"; + public @Nullable String convert(@NonNull Boolean source) { + return source ? "Yes" : "No"; } } From 450526fd05de62acd24354cfd171f4cba6700e62 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 3 Jan 2025 12:47:51 -0500 Subject: [PATCH 150/260] Single value conditions do not expect null values --- CHANGELOG.md | 24 +++++- .../sql/AbstractSingleValueCondition.java | 8 +- .../org/mybatis/dynamic/sql/SqlBuilder.java | 60 +++++++-------- .../sql/where/condition/IsEqualTo.java | 13 +++- .../sql/where/condition/IsGreaterThan.java | 13 +++- .../condition/IsGreaterThanOrEqualTo.java | 13 +++- .../sql/where/condition/IsLessThan.java | 13 +++- .../where/condition/IsLessThanOrEqualTo.java | 13 +++- .../dynamic/sql/where/condition/IsLike.java | 13 +++- .../condition/IsLikeCaseInsensitive.java | 20 +++-- .../sql/where/condition/IsNotEqualTo.java | 13 +++- .../sql/where/condition/IsNotLike.java | 13 +++- .../condition/IsNotLikeCaseInsensitive.java | 20 +++-- ...onditionsWithPredicatesAnimalDataTest.java | 54 +++++++++---- src/test/java/issues/gh105/Issue105Test.java | 6 +- .../sql/where/condition/FilterAndMapTest.java | 31 ++++---- .../sql/where/condition/SupplierTest.java | 77 ++++++++++--------- 17 files changed, 246 insertions(+), 158 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a61b8b89..2e103bd04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ you are unable to move to this version of Java then the releases in the 1.x line In addition, we have taken the opportunity to make changes to the library that may break existing code. We have worked to make these changes as minimal as possible. -**Potentially Breaking Changes:** +### Potentially Breaking Changes: - If you use this library with MyBatis' Spring Batch integration, you will need to make changes as we have refactored that support to be more flexible. Please see the @@ -25,7 +25,27 @@ worked to make these changes as minimal as possible. [Extending the Library](https://mybatis.org/mybatis-dynamic-sql/docs/extending.html) page, the change should be limited to changing the private constructor to accept `BasicColumn` rather than `BindableColumn`. -Other important changes: +### Adoption of JSpecify (https://jspecify.dev/) + +Following the lead of many other projects (including The Spring Framework), we have adopted JSpecify to fully +specify the null handling properties of this library. In general, the library does not expect that you will pass a null +value into any method. There are two exceptions to this rule: + +1. Some builder methods will accept a null value if the target object will properly handle null values through the + use of java.util.Optional +2. Methods with names that include "WhenPresent" will properly handle null parameters + (for example, "isEqualToWhenPresent") + +As you might expect, standardizing null handling revealed some issues in the library that may impact you: + +Case-insensitive conditions like "isLikeCaseInsensitive" will now throw a NullPointerException if you pass in null +values. + +The where conditions (isEqualTo, isLessThan, etc.) can be filtered and result in an "empty" condition - +similar to java.util.Optional. Previously, calling a "value" method of the condition would return null. Now +those methods will throw "NoSuchElementException". This should not impact you in normal usage. + +### Other important changes: - The library now requires Java 17 - Deprecated code from prior releases is removed diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java index 073551b76..13d4dc8e1 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java @@ -19,16 +19,14 @@ import java.util.function.Predicate; import java.util.function.Supplier; -import org.jspecify.annotations.Nullable; - public abstract class AbstractSingleValueCondition<T> implements VisitableCondition<T> { - protected final @Nullable T value; + protected final T value; - protected AbstractSingleValueCondition(@Nullable T value) { + protected AbstractSingleValueCondition(T value) { this.value = value; } - public @Nullable T value() { + public T value() { return value; } diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java index 9f3738f03..7d9f8543a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java @@ -618,11 +618,11 @@ static <T> IsNotNull<T> isNotNull() { return new IsNotNull<>(); } - static <T> IsEqualTo<T> isEqualTo(@Nullable T value) { + static <T> IsEqualTo<T> isEqualTo(T value) { return IsEqualTo.of(value); } - static <T> IsEqualTo<T> isEqualTo(Supplier<@Nullable T> valueSupplier) { + static <T> IsEqualTo<T> isEqualTo(Supplier<T> valueSupplier) { return isEqualTo(valueSupplier.get()); } @@ -635,18 +635,18 @@ static <T> IsEqualToColumn<T> isEqualTo(BasicColumn column) { } static <T> IsEqualTo<T> isEqualToWhenPresent(@Nullable T value) { - return IsEqualTo.of(value).filter(Objects::nonNull); + return value == null ? IsEqualTo.empty() : IsEqualTo.of(value); } static <T> IsEqualTo<T> isEqualToWhenPresent(Supplier<@Nullable T> valueSupplier) { return isEqualToWhenPresent(valueSupplier.get()); } - static <T> IsNotEqualTo<T> isNotEqualTo(@Nullable T value) { + static <T> IsNotEqualTo<T> isNotEqualTo(T value) { return IsNotEqualTo.of(value); } - static <T> IsNotEqualTo<T> isNotEqualTo(Supplier<@Nullable T> valueSupplier) { + static <T> IsNotEqualTo<T> isNotEqualTo(Supplier<T> valueSupplier) { return isNotEqualTo(valueSupplier.get()); } @@ -659,18 +659,18 @@ static <T> IsNotEqualToColumn<T> isNotEqualTo(BasicColumn column) { } static <T> IsNotEqualTo<T> isNotEqualToWhenPresent(@Nullable T value) { - return IsNotEqualTo.of(value).filter(Objects::nonNull); + return value == null ? IsNotEqualTo.empty() : IsNotEqualTo.of(value); } static <T> IsNotEqualTo<T> isNotEqualToWhenPresent(Supplier<@Nullable T> valueSupplier) { return isNotEqualToWhenPresent(valueSupplier.get()); } - static <T> IsGreaterThan<T> isGreaterThan(@Nullable T value) { + static <T> IsGreaterThan<T> isGreaterThan(T value) { return IsGreaterThan.of(value); } - static <T> IsGreaterThan<T> isGreaterThan(Supplier<@Nullable T> valueSupplier) { + static <T> IsGreaterThan<T> isGreaterThan(Supplier<T> valueSupplier) { return isGreaterThan(valueSupplier.get()); } @@ -683,18 +683,18 @@ static <T> IsGreaterThanColumn<T> isGreaterThan(BasicColumn column) { } static <T> IsGreaterThan<T> isGreaterThanWhenPresent(@Nullable T value) { - return IsGreaterThan.of(value).filter(Objects::nonNull); + return value == null ? IsGreaterThan.empty() : IsGreaterThan.of(value); } static <T> IsGreaterThan<T> isGreaterThanWhenPresent(Supplier<@Nullable T> valueSupplier) { return isGreaterThanWhenPresent(valueSupplier.get()); } - static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualTo(@Nullable T value) { + static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualTo(T value) { return IsGreaterThanOrEqualTo.of(value); } - static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualTo(Supplier<@Nullable T> valueSupplier) { + static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualTo(Supplier<T> valueSupplier) { return isGreaterThanOrEqualTo(valueSupplier.get()); } @@ -708,18 +708,18 @@ static <T> IsGreaterThanOrEqualToColumn<T> isGreaterThanOrEqualTo(BasicColumn co } static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualToWhenPresent(@Nullable T value) { - return IsGreaterThanOrEqualTo.of(value).filter(Objects::nonNull); + return value == null ? IsGreaterThanOrEqualTo.empty() : IsGreaterThanOrEqualTo.of(value); } static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualToWhenPresent(Supplier<@Nullable T> valueSupplier) { return isGreaterThanOrEqualToWhenPresent(valueSupplier.get()); } - static <T> IsLessThan<T> isLessThan(@Nullable T value) { + static <T> IsLessThan<T> isLessThan(T value) { return IsLessThan.of(value); } - static <T> IsLessThan<T> isLessThan(Supplier<@Nullable T> valueSupplier) { + static <T> IsLessThan<T> isLessThan(Supplier<T> valueSupplier) { return isLessThan(valueSupplier.get()); } @@ -732,18 +732,18 @@ static <T> IsLessThanColumn<T> isLessThan(BasicColumn column) { } static <T> IsLessThan<T> isLessThanWhenPresent(@Nullable T value) { - return IsLessThan.of(value).filter(Objects::nonNull); + return value == null ? IsLessThan.empty() : IsLessThan.of(value); } static <T> IsLessThan<T> isLessThanWhenPresent(Supplier<@Nullable T> valueSupplier) { return isLessThanWhenPresent(valueSupplier.get()); } - static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualTo(@Nullable T value) { + static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualTo(T value) { return IsLessThanOrEqualTo.of(value); } - static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualTo(Supplier<@Nullable T> valueSupplier) { + static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualTo(Supplier<T> valueSupplier) { return isLessThanOrEqualTo(valueSupplier.get()); } @@ -756,7 +756,7 @@ static <T> IsLessThanOrEqualToColumn<T> isLessThanOrEqualTo(BasicColumn column) } static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualToWhenPresent(@Nullable T value) { - return IsLessThanOrEqualTo.of(value).filter(Objects::nonNull); + return value == null ? IsLessThanOrEqualTo.empty() : IsLessThanOrEqualTo.of(value); } static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualToWhenPresent(Supplier<@Nullable T> valueSupplier) { @@ -840,32 +840,32 @@ static <T> IsNotBetween.WhenPresentBuilder<T> isNotBetweenWhenPresent(Supplier<@ } // for string columns, but generic for columns with type handlers - static <T> IsLike<T> isLike(@Nullable T value) { + static <T> IsLike<T> isLike(T value) { return IsLike.of(value); } - static <T> IsLike<T> isLike(Supplier<@Nullable T> valueSupplier) { + static <T> IsLike<T> isLike(Supplier<T> valueSupplier) { return isLike(valueSupplier.get()); } static <T> IsLike<T> isLikeWhenPresent(@Nullable T value) { - return IsLike.of(value).filter(Objects::nonNull); + return value == null ? IsLike.empty() : IsLike.of(value); } static <T> IsLike<T> isLikeWhenPresent(Supplier<@Nullable T> valueSupplier) { return isLikeWhenPresent(valueSupplier.get()); } - static <T> IsNotLike<T> isNotLike(@Nullable T value) { + static <T> IsNotLike<T> isNotLike(T value) { return IsNotLike.of(value); } - static <T> IsNotLike<T> isNotLike(Supplier<@Nullable T> valueSupplier) { + static <T> IsNotLike<T> isNotLike(Supplier<T> valueSupplier) { return isNotLike(valueSupplier.get()); } static <T> IsNotLike<T> isNotLikeWhenPresent(@Nullable T value) { - return IsNotLike.of(value).filter(Objects::nonNull); + return value == null ? IsNotLike.empty() : IsNotLike.of(value); } static <T> IsNotLike<T> isNotLikeWhenPresent(Supplier<@Nullable T> valueSupplier) { @@ -882,32 +882,32 @@ static IsEqualTo<Boolean> isFalse() { } // conditions for strings only - static IsLikeCaseInsensitive isLikeCaseInsensitive(@Nullable String value) { + static IsLikeCaseInsensitive isLikeCaseInsensitive(String value) { return IsLikeCaseInsensitive.of(value); } - static IsLikeCaseInsensitive isLikeCaseInsensitive(Supplier<@Nullable String> valueSupplier) { + static IsLikeCaseInsensitive isLikeCaseInsensitive(Supplier<String> valueSupplier) { return isLikeCaseInsensitive(valueSupplier.get()); } static IsLikeCaseInsensitive isLikeCaseInsensitiveWhenPresent(@Nullable String value) { - return IsLikeCaseInsensitive.of(value).filter(Objects::nonNull); + return value == null ? IsLikeCaseInsensitive.empty() : IsLikeCaseInsensitive.of(value); } static IsLikeCaseInsensitive isLikeCaseInsensitiveWhenPresent(Supplier<@Nullable String> valueSupplier) { return isLikeCaseInsensitiveWhenPresent(valueSupplier.get()); } - static IsNotLikeCaseInsensitive isNotLikeCaseInsensitive(@Nullable String value) { + static IsNotLikeCaseInsensitive isNotLikeCaseInsensitive(String value) { return IsNotLikeCaseInsensitive.of(value); } - static IsNotLikeCaseInsensitive isNotLikeCaseInsensitive(Supplier<@Nullable String> valueSupplier) { + static IsNotLikeCaseInsensitive isNotLikeCaseInsensitive(Supplier<String> valueSupplier) { return isNotLikeCaseInsensitive(valueSupplier.get()); } static IsNotLikeCaseInsensitive isNotLikeCaseInsensitiveWhenPresent(@Nullable String value) { - return IsNotLikeCaseInsensitive.of(value).filter(Objects::nonNull); + return value == null ? IsNotLikeCaseInsensitive.empty() : IsNotLikeCaseInsensitive.of(value); } static IsNotLikeCaseInsensitive isNotLikeCaseInsensitiveWhenPresent(Supplier<@Nullable String> valueSupplier) { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java index 8e1debf47..0a4b19207 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java @@ -15,15 +15,20 @@ */ package org.mybatis.dynamic.sql.where.condition; +import java.util.NoSuchElementException; import java.util.function.Function; import java.util.function.Predicate; -import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsEqualTo<T> extends AbstractSingleValueCondition<T> { - private static final IsEqualTo<?> EMPTY = new IsEqualTo<>(null) { + private static final IsEqualTo<?> EMPTY = new IsEqualTo<Object>(-1) { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + @Override public boolean isEmpty() { return true; @@ -36,7 +41,7 @@ public static <T> IsEqualTo<T> empty() { return t; } - protected IsEqualTo(@Nullable T value) { + protected IsEqualTo(T value) { super(value); } @@ -45,7 +50,7 @@ public String operator() { return "="; //$NON-NLS-1$ } - public static <T> IsEqualTo<T> of(@Nullable T value) { + public static <T> IsEqualTo<T> of(T value) { return new IsEqualTo<>(value); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java index 2f0bca75a..a0ed1a2bc 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java @@ -15,14 +15,19 @@ */ package org.mybatis.dynamic.sql.where.condition; +import java.util.NoSuchElementException; import java.util.function.Function; import java.util.function.Predicate; -import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsGreaterThan<T> extends AbstractSingleValueCondition<T> { - private static final IsGreaterThan<?> EMPTY = new IsGreaterThan<>(null) { + private static final IsGreaterThan<?> EMPTY = new IsGreaterThan<Object>(-1) { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + @Override public boolean isEmpty() { return true; @@ -35,7 +40,7 @@ public static <T> IsGreaterThan<T> empty() { return t; } - protected IsGreaterThan(@Nullable T value) { + protected IsGreaterThan(T value) { super(value); } @@ -44,7 +49,7 @@ public String operator() { return ">"; //$NON-NLS-1$ } - public static <T> IsGreaterThan<T> of(@Nullable T value) { + public static <T> IsGreaterThan<T> of(T value) { return new IsGreaterThan<>(value); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java index 1b468b3d4..59560339b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java @@ -15,14 +15,19 @@ */ package org.mybatis.dynamic.sql.where.condition; +import java.util.NoSuchElementException; import java.util.function.Function; import java.util.function.Predicate; -import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsGreaterThanOrEqualTo<T> extends AbstractSingleValueCondition<T> { - private static final IsGreaterThanOrEqualTo<?> EMPTY = new IsGreaterThanOrEqualTo<>(null) { + private static final IsGreaterThanOrEqualTo<?> EMPTY = new IsGreaterThanOrEqualTo<Object>(-1) { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + @Override public boolean isEmpty() { return true; @@ -35,7 +40,7 @@ public static <T> IsGreaterThanOrEqualTo<T> empty() { return t; } - protected IsGreaterThanOrEqualTo(@Nullable T value) { + protected IsGreaterThanOrEqualTo(T value) { super(value); } @@ -44,7 +49,7 @@ public String operator() { return ">="; //$NON-NLS-1$ } - public static <T> IsGreaterThanOrEqualTo<T> of(@Nullable T value) { + public static <T> IsGreaterThanOrEqualTo<T> of(T value) { return new IsGreaterThanOrEqualTo<>(value); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java index dde49af88..09e2e7ba6 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java @@ -15,14 +15,19 @@ */ package org.mybatis.dynamic.sql.where.condition; +import java.util.NoSuchElementException; import java.util.function.Function; import java.util.function.Predicate; -import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsLessThan<T> extends AbstractSingleValueCondition<T> { - private static final IsLessThan<?> EMPTY = new IsLessThan<>(null) { + private static final IsLessThan<?> EMPTY = new IsLessThan<Object>(-1) { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + @Override public boolean isEmpty() { return true; @@ -35,7 +40,7 @@ public static <T> IsLessThan<T> empty() { return t; } - protected IsLessThan(@Nullable T value) { + protected IsLessThan(T value) { super(value); } @@ -44,7 +49,7 @@ public String operator() { return "<"; //$NON-NLS-1$ } - public static <T> IsLessThan<T> of(@Nullable T value) { + public static <T> IsLessThan<T> of(T value) { return new IsLessThan<>(value); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java index d529b57bf..b11d06c88 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java @@ -15,14 +15,19 @@ */ package org.mybatis.dynamic.sql.where.condition; +import java.util.NoSuchElementException; import java.util.function.Function; import java.util.function.Predicate; -import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsLessThanOrEqualTo<T> extends AbstractSingleValueCondition<T> { - private static final IsLessThanOrEqualTo<?> EMPTY = new IsLessThanOrEqualTo<>(null) { + private static final IsLessThanOrEqualTo<?> EMPTY = new IsLessThanOrEqualTo<Object>(-1) { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + @Override public boolean isEmpty() { return true; @@ -35,7 +40,7 @@ public static <T> IsLessThanOrEqualTo<T> empty() { return t; } - protected IsLessThanOrEqualTo(@Nullable T value) { + protected IsLessThanOrEqualTo(T value) { super(value); } @@ -44,7 +49,7 @@ public String operator() { return "<="; //$NON-NLS-1$ } - public static <T> IsLessThanOrEqualTo<T> of(@Nullable T value) { + public static <T> IsLessThanOrEqualTo<T> of(T value) { return new IsLessThanOrEqualTo<>(value); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java index 293d9b9d8..9d79bed81 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java @@ -15,14 +15,19 @@ */ package org.mybatis.dynamic.sql.where.condition; +import java.util.NoSuchElementException; import java.util.function.Function; import java.util.function.Predicate; -import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsLike<T> extends AbstractSingleValueCondition<T> { - private static final IsLike<?> EMPTY = new IsLike<>(null) { + private static final IsLike<?> EMPTY = new IsLike<Object>(-1) { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + @Override public boolean isEmpty() { return true; @@ -35,7 +40,7 @@ public static <T> IsLike<T> empty() { return t; } - protected IsLike(@Nullable T value) { + protected IsLike(T value) { super(value); } @@ -44,7 +49,7 @@ public String operator() { return "like"; //$NON-NLS-1$ } - public static <T> IsLike<T> of(@Nullable T value) { + public static <T> IsLike<T> of(T value) { return new IsLike<>(value); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java index 0ec1b7a60..e44a9f74c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java @@ -15,16 +15,20 @@ */ package org.mybatis.dynamic.sql.where.condition; +import java.util.NoSuchElementException; import java.util.function.Predicate; import java.util.function.UnaryOperator; -import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; -import org.mybatis.dynamic.sql.util.StringUtilities; public class IsLikeCaseInsensitive extends AbstractSingleValueCondition<String> implements CaseInsensitiveVisitableCondition { - private static final IsLikeCaseInsensitive EMPTY = new IsLikeCaseInsensitive(null) { + private static final IsLikeCaseInsensitive EMPTY = new IsLikeCaseInsensitive("") { //$NON-NLS-1$ + @Override + public String value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + @Override public boolean isEmpty() { return true; @@ -35,7 +39,7 @@ public static IsLikeCaseInsensitive empty() { return EMPTY; } - protected IsLikeCaseInsensitive(@Nullable String value) { + protected IsLikeCaseInsensitive(String value) { super(value); } @@ -45,7 +49,7 @@ public String operator() { } @Override - public IsLikeCaseInsensitive filter(Predicate<? super @Nullable String> predicate) { + public IsLikeCaseInsensitive filter(Predicate<? super String> predicate) { return filterSupport(predicate, IsLikeCaseInsensitive::empty, this); } @@ -57,11 +61,11 @@ public IsLikeCaseInsensitive filter(Predicate<? super @Nullable String> predicat * @return a new condition with the result of applying the mapper to the value of this condition, * if renderable, otherwise a condition that will not render. */ - public IsLikeCaseInsensitive map(UnaryOperator<@Nullable String> mapper) { + public IsLikeCaseInsensitive map(UnaryOperator<String> mapper) { return mapSupport(mapper, IsLikeCaseInsensitive::new, IsLikeCaseInsensitive::empty); } - public static IsLikeCaseInsensitive of(@Nullable String value) { - return new IsLikeCaseInsensitive(value).map(StringUtilities::safelyUpperCase); + public static IsLikeCaseInsensitive of(String value) { + return new IsLikeCaseInsensitive(value).map(String::toUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java index 8fbd793c0..821fd019f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java @@ -15,14 +15,19 @@ */ package org.mybatis.dynamic.sql.where.condition; +import java.util.NoSuchElementException; import java.util.function.Function; import java.util.function.Predicate; -import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsNotEqualTo<T> extends AbstractSingleValueCondition<T> { - private static final IsNotEqualTo<?> EMPTY = new IsNotEqualTo<>(null) { + private static final IsNotEqualTo<?> EMPTY = new IsNotEqualTo<Object>(-1) { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + @Override public boolean isEmpty() { return true; @@ -35,7 +40,7 @@ public static <T> IsNotEqualTo<T> empty() { return t; } - protected IsNotEqualTo(@Nullable T value) { + protected IsNotEqualTo(T value) { super(value); } @@ -44,7 +49,7 @@ public String operator() { return "<>"; //$NON-NLS-1$ } - public static <T> IsNotEqualTo<T> of(@Nullable T value) { + public static <T> IsNotEqualTo<T> of(T value) { return new IsNotEqualTo<>(value); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java index c27496a40..7379a316b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java @@ -15,14 +15,19 @@ */ package org.mybatis.dynamic.sql.where.condition; +import java.util.NoSuchElementException; import java.util.function.Function; import java.util.function.Predicate; -import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsNotLike<T> extends AbstractSingleValueCondition<T> { - private static final IsNotLike<?> EMPTY = new IsNotLike<>(null) { + private static final IsNotLike<?> EMPTY = new IsNotLike<Object>(-1) { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + @Override public boolean isEmpty() { return true; @@ -35,7 +40,7 @@ public static <T> IsNotLike<T> empty() { return t; } - protected IsNotLike(@Nullable T value) { + protected IsNotLike(T value) { super(value); } @@ -44,7 +49,7 @@ public String operator() { return "not like"; //$NON-NLS-1$ } - public static <T> IsNotLike<T> of(@Nullable T value) { + public static <T> IsNotLike<T> of(T value) { return new IsNotLike<>(value); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java index a93878d13..ec073a162 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java @@ -15,16 +15,20 @@ */ package org.mybatis.dynamic.sql.where.condition; +import java.util.NoSuchElementException; import java.util.function.Predicate; import java.util.function.UnaryOperator; -import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; -import org.mybatis.dynamic.sql.util.StringUtilities; public class IsNotLikeCaseInsensitive extends AbstractSingleValueCondition<String> implements CaseInsensitiveVisitableCondition { - private static final IsNotLikeCaseInsensitive EMPTY = new IsNotLikeCaseInsensitive(null) { + private static final IsNotLikeCaseInsensitive EMPTY = new IsNotLikeCaseInsensitive("") { //$NON-NLS-1$ + @Override + public String value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + @Override public boolean isEmpty() { return true; @@ -35,7 +39,7 @@ public static IsNotLikeCaseInsensitive empty() { return EMPTY; } - protected IsNotLikeCaseInsensitive(@Nullable String value) { + protected IsNotLikeCaseInsensitive(String value) { super(value); } @@ -45,7 +49,7 @@ public String operator() { } @Override - public IsNotLikeCaseInsensitive filter(Predicate<? super @Nullable String> predicate) { + public IsNotLikeCaseInsensitive filter(Predicate<? super String> predicate) { return filterSupport(predicate, IsNotLikeCaseInsensitive::empty, this); } @@ -59,11 +63,11 @@ public IsNotLikeCaseInsensitive filter(Predicate<? super @Nullable String> predi * @return a new condition with the result of applying the mapper to the value of this condition, if renderable, * otherwise a condition that will not render. */ - public IsNotLikeCaseInsensitive map(UnaryOperator<@Nullable String> mapper) { + public IsNotLikeCaseInsensitive map(UnaryOperator<String> mapper) { return mapSupport(mapper, IsNotLikeCaseInsensitive::new, IsNotLikeCaseInsensitive::empty); } - public static IsNotLikeCaseInsensitive of(@Nullable String value) { - return new IsNotLikeCaseInsensitive(value).map(StringUtilities::safelyUpperCase); + public static IsNotLikeCaseInsensitive of(String value) { + return new IsNotLikeCaseInsensitive(value).map(String::toUpperCase); } } diff --git a/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java b/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java index a967052d2..cdbc250d9 100644 --- a/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java +++ b/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java @@ -78,7 +78,7 @@ void testAllIgnored() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isGreaterThan(NULL_INTEGER).filter(Objects::nonNull)) // the where clause should not render + .where(id, isGreaterThanWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) // the where clause should not render .orderBy(id) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() @@ -93,6 +93,26 @@ void testAllIgnored() { } } + @Test + void testSelectByNull() { + // this method demonstrates that ignoring the null value warning will still work + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); + SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) + .from(animalData) + .where(id, isGreaterThan(NULL_INTEGER)) // should be an IDE warning about passing null to a nonnull method + .orderBy(id) + .build() + .render(RenderingStrategies.MYBATIS3); + List<AnimalData> animals = mapper.selectMany(selectStatement); + assertAll( + () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id > #{parameters.p1,jdbcType=INTEGER} order by id"), + () -> assertThat(selectStatement.getParameters()).containsEntry("p1", null), + () -> assertThat(animals).hasSize(0) + ); + } + } + @Test void testIgnoredBetweenRendered() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { @@ -100,7 +120,7 @@ void testIgnoredBetweenRendered() { SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) .where(id, isEqualTo(3)) - .and(id, isNotEqualTo(NULL_INTEGER).filter(Objects::nonNull)) + .and(id, isNotEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) .or(id, isEqualTo(4).filter(Objects::nonNull)) .orderBy(id) .build() @@ -121,7 +141,7 @@ void testIgnoredInWhere() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isLessThanWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) .and(id, isEqualTo(3).filter(Objects::nonNull)) .or(id, isEqualTo(4).filter(Objects::nonNull)) .orderBy(id) @@ -143,10 +163,10 @@ void testManyIgnored() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull), and(id, isGreaterThanOrEqualTo(NULL_INTEGER).filter(Objects::nonNull))) - .and(id, isEqualTo(NULL_INTEGER).filter(Objects::nonNull), or(id, isEqualTo(3), and(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull)))) - .or(id, isEqualTo(4).filter(Objects::nonNull), and(id, isGreaterThanOrEqualTo(NULL_INTEGER).filter(Objects::nonNull))) - .and(id, isNotEqualTo(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isLessThanWhenPresent(NULL_INTEGER).filter(Objects::nonNull), and(id, isGreaterThanOrEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull))) + .and(id, isEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull), or(id, isEqualTo(3), and(id, isLessThanWhenPresent(NULL_INTEGER).filter(Objects::nonNull)))) + .or(id, isEqualTo(4).filter(Objects::nonNull), and(id, isGreaterThanOrEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull))) + .and(id, isNotEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -166,7 +186,7 @@ void testIgnoredInitialWhere() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull), and(id, isEqualTo(3).filter(Objects::nonNull))) + .where(id, isLessThanWhenPresent(NULL_INTEGER).filter(Objects::nonNull), and(id, isEqualTo(3).filter(Objects::nonNull))) .or(id, isEqualTo(4).filter(Objects::nonNull)) .orderBy(id) .build() @@ -206,7 +226,7 @@ void testEqualWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isEqualTo(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -246,7 +266,7 @@ void testNotEqualWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isNotEqualTo(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isNotEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -286,7 +306,7 @@ void testGreaterThanWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isGreaterThan(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isGreaterThanWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -326,7 +346,7 @@ void testGreaterThanOrEqualToWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isGreaterThanOrEqualTo(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isGreaterThanOrEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -365,7 +385,7 @@ void testLessThanWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isLessThanWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -404,7 +424,7 @@ void testLessThanOrEqualToWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThanOrEqualTo(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isLessThanOrEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -842,7 +862,7 @@ void testIsLikeCaseInsensitiveWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isLikeCaseInsensitive((String) null).filter(Objects::nonNull)) + .where(animalName, isLikeCaseInsensitiveWhenPresent((String) null).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -882,7 +902,7 @@ void testIsNotLikeWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isNotLike((String) null).filter(Objects::nonNull)) + .where(animalName, isNotLikeWhenPresent((String) null).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -922,7 +942,7 @@ void testIsNotLikeCaseInsensitiveWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isNotLikeCaseInsensitive((String) null).filter(Objects::nonNull)) + .where(animalName, isNotLikeCaseInsensitiveWhenPresent((String) null).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() diff --git a/src/test/java/issues/gh105/Issue105Test.java b/src/test/java/issues/gh105/Issue105Test.java index 8fb16f22d..cf400e0a7 100644 --- a/src/test/java/issues/gh105/Issue105Test.java +++ b/src/test/java/issues/gh105/Issue105Test.java @@ -57,7 +57,7 @@ void testFuzzyLikeFirstNameNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(firstName, isLike(fName).filter(Objects::nonNull).map(SearchUtils::addWildcards)) + .where(firstName, isLikeWhenPresent(fName).filter(Objects::nonNull).map(SearchUtils::addWildcards)) .and(lastName, isLike(lName).filter(Objects::nonNull).map(SearchUtils::addWildcards)) .build() .render(RenderingStrategies.MYBATIS3); @@ -735,7 +735,7 @@ void testLikeCaseInsensitiveTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(firstName, isLikeCaseInsensitive((String) null).filter(Objects::nonNull).map(SearchUtils::addWildcards)) + .where(firstName, isLikeCaseInsensitiveWhenPresent((String) null).filter(Objects::nonNull).map(SearchUtils::addWildcards)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); @@ -863,7 +863,7 @@ void testNotLikeCaseInsensitiveTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(firstName, isNotLikeCaseInsensitive((String) null).filter(Objects::nonNull).map(SearchUtils::addWildcards)) + .where(firstName, isNotLikeCaseInsensitiveWhenPresent((String) null).filter(Objects::nonNull).map(SearchUtils::addWildcards)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java index 0541ce2ed..cb05b28b7 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java @@ -19,6 +19,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import java.util.List; +import java.util.NoSuchElementException; import java.util.Objects; import org.jspecify.annotations.Nullable; @@ -34,16 +35,14 @@ void testTypeConversion() { } @Test - void testTypeConversionWithNullThrowsException() { - IsEqualTo<String> cond = SqlBuilder.isEqualTo((String) null); - assertThatExceptionOfType(NumberFormatException.class).isThrownBy(() -> - cond.map(Integer::parseInt) - ); + void testTypeConversionWithEmptyDoesNotThrowException() { + SqlBuilder.isEqualToWhenPresent((String) null).map(Integer::parseInt); + assertThat(true).isTrue(); } @Test void testTypeConversionWithNullAndFilterDoesNotThrowException() { - IsEqualTo<Integer> cond = SqlBuilder.isEqualTo((String) null).filter(Objects::nonNull).map(Integer::parseInt); + IsEqualTo<Integer> cond = SqlBuilder.isEqualToWhenPresent((String) null).filter(Objects::nonNull).map(Integer::parseInt); assertThat(cond.isEmpty()).isTrue(); } @@ -124,7 +123,7 @@ void testIsEqualMapUnRenderableShouldNotThrowNullPointerException() { IsEqualTo<String> cond = SqlBuilder.isEqualTo("Fred").filter(s -> false); IsEqualTo<String> mapped = cond.map(String::toUpperCase); assertThat(cond.isEmpty()).isTrue(); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond).isSameAs(mapped); } @@ -157,7 +156,7 @@ void testIsNotEqualMapUnRenderableShouldNotThrowNullPointerException() { IsNotEqualTo<String> cond = SqlBuilder.isNotEqualTo("Fred").filter(s -> false); IsNotEqualTo<String> mapped = cond.map(String::toUpperCase); assertThat(cond.isEmpty()).isTrue(); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond).isSameAs(mapped); } @@ -190,7 +189,7 @@ void testIsLessThanMapUnRenderableShouldNotThrowNullPointerException() { IsLessThan<String> cond = SqlBuilder.isLessThan("Fred").filter(s -> false); IsLessThan<String> mapped = cond.map(String::toUpperCase); assertThat(cond.isEmpty()).isTrue(); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond).isSameAs(mapped); } @@ -223,7 +222,7 @@ void testIsLessThanOrEqualMapUnRenderableShouldNotThrowNullPointerException() { IsLessThanOrEqualTo<String> cond = SqlBuilder.isLessThanOrEqualTo("Fred").filter(s -> false); IsLessThanOrEqualTo<String> mapped = cond.map(String::toUpperCase); assertThat(cond.isEmpty()).isTrue(); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond).isSameAs(mapped); } @@ -256,7 +255,7 @@ void testIsGreaterThanMapUnRenderableShouldNotThrowNullPointerException() { IsGreaterThan<String> cond = SqlBuilder.isGreaterThan("Fred").filter(s -> false); IsGreaterThan<String> mapped = cond.map(String::toUpperCase); assertThat(cond.isEmpty()).isTrue(); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond).isSameAs(mapped); } @@ -289,7 +288,7 @@ void testIsGreaterThanOrEqualMapUnRenderableShouldNotThrowNullPointerException() IsGreaterThanOrEqualTo<String> cond = SqlBuilder.isGreaterThanOrEqualTo("Fred").filter(s -> false); IsGreaterThanOrEqualTo<String> mapped = cond.map(String::toUpperCase); assertThat(cond.isEmpty()).isTrue(); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond).isSameAs(mapped); } @@ -322,7 +321,7 @@ void testIsLikeMapUnRenderableShouldNotThrowNullPointerException() { IsLike<String> cond = SqlBuilder.isLike("Fred").filter(s -> false); IsLike<String> mapped = cond.map(String::toUpperCase); assertThat(cond.isEmpty()).isTrue(); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond).isSameAs(mapped); } @@ -356,7 +355,7 @@ void testIsLikeCaseInsensitiveMapUnRenderableShouldNotThrowNullPointerException( IsLikeCaseInsensitive cond = SqlBuilder.isLikeCaseInsensitive("Fred").filter(s -> false); IsLikeCaseInsensitive mapped = cond.map(String::toUpperCase); assertThat(cond.isEmpty()).isTrue(); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond).isSameAs(mapped); } @@ -389,7 +388,7 @@ void testIsNotLikeMapUnRenderableShouldNotThrowNullPointerException() { IsNotLike<String> cond = SqlBuilder.isNotLike("Fred").filter(s -> false); IsNotLike<String> mapped = cond.map(String::toUpperCase); assertThat(cond.isEmpty()).isTrue(); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond).isSameAs(mapped); } @@ -423,7 +422,7 @@ void testIsNotLikeCaseInsensitiveMapUnRenderableShouldNotThrowNullPointerExcepti IsNotLikeCaseInsensitive cond = SqlBuilder.isNotLikeCaseInsensitive("Fred").filter(s -> false); IsNotLikeCaseInsensitive mapped = cond.map(String::toUpperCase); assertThat(cond.isEmpty()).isTrue(); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond).isSameAs(mapped); } diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java index 86675e51d..3c6d64032 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java @@ -16,10 +16,13 @@ package org.mybatis.dynamic.sql.where.condition; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.SqlBuilder; +import java.util.NoSuchElementException; + // series of tests to check that the Supplier based DSL methods function correctly class SupplierTest { @@ -97,7 +100,7 @@ void testIsEqualToWhenPresent() { @Test void testIsEqualToWhenPresentNull() { IsEqualTo<Integer> cond = SqlBuilder.isEqualToWhenPresent(() -> null); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -110,9 +113,9 @@ void testIsNotEqualTo() { @Test void testIsNotEqualToNull() { - IsNotEqualTo<Integer> cond = SqlBuilder.isNotEqualTo(() -> (Integer) null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); + IsNotEqualTo<Integer> cond = SqlBuilder.isNotEqualToWhenPresent(() -> null); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); + assertThat(cond.isEmpty()).isTrue(); } @Test @@ -125,7 +128,7 @@ void testIsNotEqualToWhenPresent() { @Test void testIsNotEqualToWhenPresentNull() { IsNotEqualTo<Integer> cond = SqlBuilder.isNotEqualToWhenPresent(() -> null); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -138,9 +141,9 @@ void testIsGreaterThan() { @Test void testIsGreaterThanNull() { - IsGreaterThan<Integer> cond = SqlBuilder.isGreaterThan(() -> (Integer) null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); + IsGreaterThan<Integer> cond = SqlBuilder.isGreaterThanWhenPresent(() -> null); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); + assertThat(cond.isEmpty()).isTrue(); } @Test @@ -153,7 +156,7 @@ void testIsGreaterThanWhenPresent() { @Test void testIsGreaterThanWhenPresentNull() { IsGreaterThan<Integer> cond = SqlBuilder.isGreaterThanWhenPresent(() -> null); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -166,9 +169,9 @@ void testIsGreaterThanOrEqualTo() { @Test void testIsGreaterThanOrEqualToNull() { - IsGreaterThanOrEqualTo<Integer> cond = SqlBuilder.isGreaterThanOrEqualTo(() -> (Integer) null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); + IsGreaterThanOrEqualTo<Integer> cond = SqlBuilder.isGreaterThanOrEqualToWhenPresent(() -> null); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); + assertThat(cond.isEmpty()).isTrue(); } @Test @@ -181,7 +184,7 @@ void testIsGreaterThanOrEqualToWhenPresent() { @Test void testIsGreaterThanOrEqualToWhenPresentNull() { IsGreaterThanOrEqualTo<Integer> cond = SqlBuilder.isGreaterThanOrEqualToWhenPresent(() -> null); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -194,9 +197,9 @@ void testIsLessThan() { @Test void testIsLessThanNull() { - IsLessThan<Integer> cond = SqlBuilder.isLessThan(() -> (Integer) null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); + IsLessThan<Integer> cond = SqlBuilder.isLessThanWhenPresent(() -> null); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); + assertThat(cond.isEmpty()).isTrue(); } @Test @@ -209,7 +212,7 @@ void testIsLessThanWhenPresent() { @Test void testIsLessThanWhenPresentNull() { IsLessThan<Integer> cond = SqlBuilder.isLessThanWhenPresent(() -> null); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -222,9 +225,9 @@ void testIsLessThanOrEqualTo() { @Test void testIsLessThanOrEqualToNull() { - IsLessThanOrEqualTo<Integer> cond = SqlBuilder.isLessThanOrEqualTo(() -> (Integer) null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); + IsLessThanOrEqualTo<Integer> cond = SqlBuilder.isLessThanOrEqualToWhenPresent(() -> null); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); + assertThat(cond.isEmpty()).isTrue(); } @Test @@ -237,7 +240,7 @@ void testIsLessThanOrEqualToWhenPresent() { @Test void testIsLessThanOrEqualToWhenPresentNull() { IsLessThanOrEqualTo<Integer> cond = SqlBuilder.isLessThanOrEqualToWhenPresent(() -> null); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -250,9 +253,9 @@ void testIsLike() { @Test void testIsLikeNull() { - IsLike<String> cond = SqlBuilder.isLike(() -> null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); + IsLike<String> cond = SqlBuilder.isLikeWhenPresent(() -> null); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); + assertThat(cond.isEmpty()).isTrue(); } @Test @@ -264,9 +267,9 @@ void testIsLikeCaseInsensitive() { @Test void testIsLikeCaseInsensitiveNull() { - IsLikeCaseInsensitive cond = SqlBuilder.isLikeCaseInsensitive(() -> null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); + IsLikeCaseInsensitive cond = SqlBuilder.isLikeCaseInsensitiveWhenPresent(() -> null); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); + assertThat(cond.isEmpty()).isTrue(); } @Test @@ -279,7 +282,7 @@ void testIsLikeCaseInsensitiveWhenPresent() { @Test void testIsLikeCaseInsensitiveWhenPresentNull() { IsLikeCaseInsensitive cond = SqlBuilder.isLikeCaseInsensitiveWhenPresent(() -> null); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -293,7 +296,7 @@ void testIsLikeWhenPresent() { @Test void testIsLikeWhenPresentNull() { IsLike<String> cond = SqlBuilder.isLikeWhenPresent(() -> null); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -306,9 +309,9 @@ void testIsNotLike() { @Test void testIsNotLikeNull() { - IsNotLike<String> cond = SqlBuilder.isNotLike(() -> null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); + IsNotLike<String> cond = SqlBuilder.isNotLikeWhenPresent(() -> null); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); + assertThat(cond.isEmpty()).isTrue(); } @Test @@ -321,7 +324,7 @@ void testIsNotLikeWhenPresent() { @Test void testIsNotLikeWhenPresentNull() { IsNotLike<String> cond = SqlBuilder.isNotLikeWhenPresent(() -> null); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -334,9 +337,9 @@ void testIsNotLikeCaseInsensitive() { @Test void testIsNotLikeCaseInsensitiveNull() { - IsNotLikeCaseInsensitive cond = SqlBuilder.isNotLikeCaseInsensitive(() -> null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); + IsNotLikeCaseInsensitive cond = SqlBuilder.isNotLikeCaseInsensitiveWhenPresent(() -> null); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); + assertThat(cond.isEmpty()).isTrue(); } @Test @@ -349,7 +352,7 @@ void testIsNotLikeCaseInsensitiveWhenPresent() { @Test void testIsNotLikeCaseInsensitiveWhenPresentNull() { IsNotLikeCaseInsensitive cond = SqlBuilder.isNotLikeCaseInsensitiveWhenPresent(() -> null); - assertThat(cond.value()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } } From e6eef016ef55bfc66e7094da20b9658295f9462d Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 3 Jan 2025 14:20:13 -0500 Subject: [PATCH 151/260] List value conditions do not expect null values --- .../sql/AbstractListValueCondition.java | 23 ++++++++----------- .../org/mybatis/dynamic/sql/SqlBuilder.java | 8 +++---- .../where/condition/IsInCaseInsensitive.java | 12 ++++------ .../IsInCaseInsensitiveWhenPresent.java | 5 ++-- .../condition/IsNotInCaseInsensitive.java | 12 ++++------ .../IsNotInCaseInsensitiveWhenPresent.java | 5 ++-- .../where/render/DefaultConditionVisitor.java | 4 ++-- .../examples/animal/data/AnimalDataTest.java | 18 +-------------- 8 files changed, 31 insertions(+), 56 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java index 965bb975b..21230c821 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java @@ -23,16 +23,14 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import org.jspecify.annotations.Nullable; - public abstract class AbstractListValueCondition<T> implements VisitableCondition<T> { - protected final Collection<@Nullable T> values; + protected final Collection<T> values; - protected AbstractListValueCondition(Collection<@Nullable T> values) { + protected AbstractListValueCondition(Collection<T> values) { this.values = Objects.requireNonNull(values); } - public final Stream<@Nullable T> values() { + public final Stream<T> values() { return values.stream(); } @@ -46,18 +44,18 @@ public <R> R accept(ConditionVisitor<T, R> visitor) { return visitor.visit(this); } - private <R> Collection<R> applyMapper(Function<? super @Nullable T, ? extends @Nullable R> mapper) { + private <R> Collection<R> applyMapper(Function<? super T, ? extends R> mapper) { Objects.requireNonNull(mapper); return values.stream().map(mapper).collect(Collectors.toList()); } - private Collection<T> applyFilter(Predicate<? super @Nullable T> predicate) { + private Collection<T> applyFilter(Predicate<? super T> predicate) { Objects.requireNonNull(predicate); return values.stream().filter(predicate).toList(); } - protected <S extends AbstractListValueCondition<T>> S filterSupport(Predicate<? super @Nullable T> predicate, - Function<Collection<@Nullable T>, S> constructor, S self, Supplier<S> emptySupplier) { + protected <S extends AbstractListValueCondition<T>> S filterSupport(Predicate<? super T> predicate, + Function<Collection<T>, S> constructor, S self, Supplier<S> emptySupplier) { if (isEmpty()) { return self; } else { @@ -66,9 +64,8 @@ protected <S extends AbstractListValueCondition<T>> S filterSupport(Predicate<? } } - protected <R, S extends AbstractListValueCondition<R>> S mapSupport( - Function<? super @Nullable T, ? extends @Nullable R> mapper, - Function<Collection<@Nullable R>, S> constructor, Supplier<S> emptySupplier) { + protected <R, S extends AbstractListValueCondition<R>> S mapSupport(Function<? super T, ? extends R> mapper, + Function<Collection<R>, S> constructor, Supplier<S> emptySupplier) { if (isEmpty()) { return emptySupplier.get(); } else { @@ -84,7 +81,7 @@ protected <R, S extends AbstractListValueCondition<R>> S mapSupport( * * @return a new condition with filtered values if renderable, otherwise an empty condition */ - public abstract AbstractListValueCondition<T> filter(Predicate<? super @Nullable T> predicate); + public abstract AbstractListValueCondition<T> filter(Predicate<? super T> predicate); public abstract String operator(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java index 7d9f8543a..2da8cecf8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java @@ -914,11 +914,11 @@ static IsNotLikeCaseInsensitive isNotLikeCaseInsensitiveWhenPresent(Supplier<@Nu return isNotLikeCaseInsensitiveWhenPresent(valueSupplier.get()); } - static IsInCaseInsensitive isInCaseInsensitive(@Nullable String... values) { + static IsInCaseInsensitive isInCaseInsensitive(String... values) { return IsInCaseInsensitive.of(values); } - static IsInCaseInsensitive isInCaseInsensitive(Collection<@Nullable String> values) { + static IsInCaseInsensitive isInCaseInsensitive(Collection<String> values) { return IsInCaseInsensitive.of(values); } @@ -931,11 +931,11 @@ static IsInCaseInsensitiveWhenPresent isInCaseInsensitiveWhenPresent( return values == null ? IsInCaseInsensitiveWhenPresent.empty() : IsInCaseInsensitiveWhenPresent.of(values); } - static IsNotInCaseInsensitive isNotInCaseInsensitive(@Nullable String... values) { + static IsNotInCaseInsensitive isNotInCaseInsensitive(String... values) { return IsNotInCaseInsensitive.of(values); } - static IsNotInCaseInsensitive isNotInCaseInsensitive(Collection<@Nullable String> values) { + static IsNotInCaseInsensitive isNotInCaseInsensitive(Collection<String> values) { return IsNotInCaseInsensitive.of(values); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java index 00b6ef445..d0fc67a23 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java @@ -21,10 +21,8 @@ import java.util.function.Predicate; import java.util.function.UnaryOperator; -import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; -import org.mybatis.dynamic.sql.util.StringUtilities; import org.mybatis.dynamic.sql.util.Validator; public class IsInCaseInsensitive extends AbstractListValueCondition<String> @@ -35,7 +33,7 @@ public static IsInCaseInsensitive empty() { return EMPTY; } - protected IsInCaseInsensitive(Collection<@Nullable String> values) { + protected IsInCaseInsensitive(Collection<String> values) { super(values); } @@ -62,15 +60,15 @@ public IsInCaseInsensitive filter(Predicate<? super String> predicate) { * @param mapper a mapping function to apply to the values, if not empty * @return a new condition with mapped values if renderable, otherwise an empty condition */ - public IsInCaseInsensitive map(UnaryOperator<@Nullable String> mapper) { + public IsInCaseInsensitive map(UnaryOperator<String> mapper) { return mapSupport(mapper, IsInCaseInsensitive::new, IsInCaseInsensitive::empty); } - public static IsInCaseInsensitive of(@Nullable String... values) { + public static IsInCaseInsensitive of(String... values) { return of(Arrays.asList(values)); } - public static IsInCaseInsensitive of(Collection<@Nullable String> values) { - return new IsInCaseInsensitive(values).map(StringUtilities::safelyUpperCase); + public static IsInCaseInsensitive of(Collection<String> values) { + return new IsInCaseInsensitive(values).map(String::toUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java index a2b785627..64111df90 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java @@ -23,7 +23,6 @@ import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; -import org.mybatis.dynamic.sql.util.StringUtilities; import org.mybatis.dynamic.sql.util.Utilities; public class IsInCaseInsensitiveWhenPresent extends AbstractListValueCondition<String> @@ -57,7 +56,7 @@ public IsInCaseInsensitiveWhenPresent filter(Predicate<? super String> predicate * @param mapper a mapping function to apply to the values, if not empty * @return a new condition with mapped values if renderable, otherwise an empty condition */ - public IsInCaseInsensitiveWhenPresent map(UnaryOperator<@Nullable String> mapper) { + public IsInCaseInsensitiveWhenPresent map(UnaryOperator<String> mapper) { return mapSupport(mapper, IsInCaseInsensitiveWhenPresent::new, IsInCaseInsensitiveWhenPresent::empty); } @@ -66,6 +65,6 @@ public static IsInCaseInsensitiveWhenPresent of(@Nullable String... values) { } public static IsInCaseInsensitiveWhenPresent of(Collection<@Nullable String> values) { - return new IsInCaseInsensitiveWhenPresent(values).map(StringUtilities::safelyUpperCase); + return new IsInCaseInsensitiveWhenPresent(values).map(String::toUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java index 88b7529d8..113de053d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java @@ -21,10 +21,8 @@ import java.util.function.Predicate; import java.util.function.UnaryOperator; -import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; -import org.mybatis.dynamic.sql.util.StringUtilities; import org.mybatis.dynamic.sql.util.Validator; public class IsNotInCaseInsensitive extends AbstractListValueCondition<String> @@ -35,7 +33,7 @@ public static IsNotInCaseInsensitive empty() { return EMPTY; } - protected IsNotInCaseInsensitive(Collection<@Nullable String> values) { + protected IsNotInCaseInsensitive(Collection<String> values) { super(values); } @@ -62,15 +60,15 @@ public IsNotInCaseInsensitive filter(Predicate<? super String> predicate) { * @param mapper a mapping function to apply to the values, if not empty * @return a new condition with mapped values if renderable, otherwise an empty condition */ - public IsNotInCaseInsensitive map(UnaryOperator<@Nullable String> mapper) { + public IsNotInCaseInsensitive map(UnaryOperator<String> mapper) { return mapSupport(mapper, IsNotInCaseInsensitive::new, IsNotInCaseInsensitive::empty); } - public static IsNotInCaseInsensitive of(@Nullable String... values) { + public static IsNotInCaseInsensitive of(String... values) { return of(Arrays.asList(values)); } - public static IsNotInCaseInsensitive of(Collection<@Nullable String> values) { - return new IsNotInCaseInsensitive(values).map(StringUtilities::safelyUpperCase); + public static IsNotInCaseInsensitive of(Collection<String> values) { + return new IsNotInCaseInsensitive(values).map(String::toUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java index 409455227..c2b0a0e2f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java @@ -23,7 +23,6 @@ import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; -import org.mybatis.dynamic.sql.util.StringUtilities; import org.mybatis.dynamic.sql.util.Utilities; public class IsNotInCaseInsensitiveWhenPresent extends AbstractListValueCondition<String> @@ -57,7 +56,7 @@ public IsNotInCaseInsensitiveWhenPresent filter(Predicate<? super String> predic * @param mapper a mapping function to apply to the values, if not empty * @return a new condition with mapped values if renderable, otherwise an empty condition */ - public IsNotInCaseInsensitiveWhenPresent map(UnaryOperator<@Nullable String> mapper) { + public IsNotInCaseInsensitiveWhenPresent map(UnaryOperator<String> mapper) { return mapSupport(mapper, IsNotInCaseInsensitiveWhenPresent::new, IsNotInCaseInsensitiveWhenPresent::empty); } @@ -66,6 +65,6 @@ public static IsNotInCaseInsensitiveWhenPresent of(@Nullable String... values) { } public static IsNotInCaseInsensitiveWhenPresent of(Collection<@Nullable String> values) { - return new IsNotInCaseInsensitiveWhenPresent(values).map(StringUtilities::safelyUpperCase); + return new IsNotInCaseInsensitiveWhenPresent(values).map(String::toUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java index d55e83425..6a3fb038d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java @@ -110,11 +110,11 @@ public FragmentAndParameters visit(AbstractColumnComparisonCondition<T> conditio .mapFragment(f -> condition.operator() + spaceBefore(f)); } - private @Nullable Object convertValue(@Nullable T value) { + private @Nullable Object convertValue(T value) { return column.convertParameterType(value); } - private FragmentAndParameters toFragmentAndParameters(@Nullable T value) { + private FragmentAndParameters toFragmentAndParameters(T value) { RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo(column); return FragmentAndParameters.withFragment(parameterInfo.renderedPlaceHolder()) .withParameter(parameterInfo.parameterMapKey(), convertValue(value)) diff --git a/src/test/java/examples/animal/data/AnimalDataTest.java b/src/test/java/examples/animal/data/AnimalDataTest.java index a883b4bd2..b1d5844da 100644 --- a/src/test/java/examples/animal/data/AnimalDataTest.java +++ b/src/test/java/examples/animal/data/AnimalDataTest.java @@ -744,7 +744,7 @@ void testInCaseSensitiveCondition() { SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isInCaseInsensitive("yellow-bellied marmot", "verbet", null)) + .where(animalName, isInCaseInsensitive("yellow-bellied marmot", "verbet")) .build() .render(RenderingStrategies.MYBATIS3); @@ -785,22 +785,6 @@ void testNotInCaseSensitiveCondition() { } } - @Test - void testNotInCaseSensitiveConditionWithNull() { - try (SqlSession sqlSession = sqlSessionFactory.openSession()) { - AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); - - SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) - .from(animalData) - .where(animalName, isNotInCaseInsensitive((String)null)) - .build() - .render(RenderingStrategies.MYBATIS3); - - List<AnimalData> animals = mapper.selectMany(selectStatement); - assertThat(animals).isEmpty(); - } - } - @Test void testNotInConditionWithEventuallyEmptyList() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { From 543e0fde73d8782cdb538d59ac931f7bf18d6f4f Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 3 Jan 2025 15:11:25 -0500 Subject: [PATCH 152/260] Two value conditions do not expect null values --- .../sql/AbstractTwoValueCondition.java | 12 ++--- .../org/mybatis/dynamic/sql/SqlBuilder.java | 16 +++--- .../sql/where/condition/AndGatherer.java | 16 +++--- .../condition/AndWhenPresentGatherer.java | 49 +++++++++++++++++++ .../sql/where/condition/IsBetween.java | 32 ++++++++---- .../sql/where/condition/IsNotBetween.java | 32 ++++++++---- src/test/java/issues/gh105/Issue105Test.java | 2 +- .../sql/where/condition/SupplierTest.java | 8 +-- 8 files changed, 119 insertions(+), 48 deletions(-) create mode 100644 src/main/java/org/mybatis/dynamic/sql/where/condition/AndWhenPresentGatherer.java diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java index 39dd8cfd3..c36fe186d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java @@ -21,22 +21,20 @@ import java.util.function.Predicate; import java.util.function.Supplier; -import org.jspecify.annotations.Nullable; - public abstract class AbstractTwoValueCondition<T> implements VisitableCondition<T> { - protected final @Nullable T value1; - protected final @Nullable T value2; + protected final T value1; + protected final T value2; - protected AbstractTwoValueCondition(@Nullable T value1, @Nullable T value2) { + protected AbstractTwoValueCondition(T value1, T value2) { this.value1 = value1; this.value2 = value2; } - public @Nullable T value1() { + public T value1() { return value1; } - public @Nullable T value2() { + public T value2() { return value2; } diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java index 2da8cecf8..8b36417fe 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java @@ -764,11 +764,11 @@ static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualToWhenPresent(Supplier<@Nulla } @SafeVarargs - static <T> IsIn<T> isIn(@Nullable T... values) { + static <T> IsIn<T> isIn(T... values) { return IsIn.of(values); } - static <T> IsIn<T> isIn(Collection<@Nullable T> values) { + static <T> IsIn<T> isIn(Collection<T> values) { return IsIn.of(values); } @@ -786,11 +786,11 @@ static <T> IsInWhenPresent<T> isInWhenPresent(@Nullable Collection<@Nullable T> } @SafeVarargs - static <T> IsNotIn<T> isNotIn(@Nullable T... values) { + static <T> IsNotIn<T> isNotIn(T... values) { return IsNotIn.of(values); } - static <T> IsNotIn<T> isNotIn(Collection<@Nullable T> values) { + static <T> IsNotIn<T> isNotIn(Collection<T> values) { return IsNotIn.of(values); } @@ -807,11 +807,11 @@ static <T> IsNotInWhenPresent<T> isNotInWhenPresent(@Nullable Collection<@Nullab return values == null ? IsNotInWhenPresent.empty() : IsNotInWhenPresent.of(values); } - static <T> IsBetween.Builder<T> isBetween(@Nullable T value1) { + static <T> IsBetween.Builder<T> isBetween(T value1) { return IsBetween.isBetween(value1); } - static <T> IsBetween.Builder<T> isBetween(Supplier<@Nullable T> valueSupplier1) { + static <T> IsBetween.Builder<T> isBetween(Supplier<T> valueSupplier1) { return isBetween(valueSupplier1.get()); } @@ -823,11 +823,11 @@ static <T> IsBetween.WhenPresentBuilder<T> isBetweenWhenPresent(Supplier<@Nullab return isBetweenWhenPresent(valueSupplier1.get()); } - static <T> IsNotBetween.Builder<T> isNotBetween(@Nullable T value1) { + static <T> IsNotBetween.Builder<T> isNotBetween(T value1) { return IsNotBetween.isNotBetween(value1); } - static <T> IsNotBetween.Builder<T> isNotBetween(Supplier<@Nullable T> valueSupplier1) { + static <T> IsNotBetween.Builder<T> isNotBetween(Supplier<T> valueSupplier1) { return isNotBetween(valueSupplier1.get()); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java index c30229d93..8a587262a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java @@ -17,8 +17,6 @@ import java.util.function.Supplier; -import org.jspecify.annotations.Nullable; - /** * Utility class supporting the "and" part of a between condition. This class supports builders, so it is mutable. * @@ -30,21 +28,19 @@ * the type of condition being built */ public abstract class AndGatherer<T, R> { - protected final @Nullable T value1; - protected @Nullable T value2; + protected final T value1; - protected AndGatherer(@Nullable T value1) { + protected AndGatherer(T value1) { this.value1 = value1; } - public R and(@Nullable T value2) { - this.value2 = value2; - return build(); + public R and(T value2) { + return build(value2); } - public R and(Supplier<@Nullable T> valueSupplier2) { + public R and(Supplier<T> valueSupplier2) { return and(valueSupplier2.get()); } - protected abstract R build(); + protected abstract R build(T value2); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/AndWhenPresentGatherer.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/AndWhenPresentGatherer.java new file mode 100644 index 000000000..d4d8f3d7c --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/AndWhenPresentGatherer.java @@ -0,0 +1,49 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.where.condition; + +import java.util.function.Supplier; + +import org.jspecify.annotations.Nullable; + +/** + * Utility class supporting the "and" part of a between when present condition. This class supports builders, + * so it is mutable. + * + * @author Jeff Butler + * + * @param <T> + * the type of field for the between condition + * @param <R> + * the type of condition being built + */ +public abstract class AndWhenPresentGatherer<T, R> { + protected final @Nullable T value1; + + protected AndWhenPresentGatherer(@Nullable T value1) { + this.value1 = value1; + } + + public R and(@Nullable T value2) { + return build(value2); + } + + public R and(Supplier<@Nullable T> valueSupplier2) { + return and(valueSupplier2.get()); + } + + protected abstract R build(@Nullable T value2); +} diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java index 5a87679eb..aebb34ca1 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java @@ -15,7 +15,7 @@ */ package org.mybatis.dynamic.sql.where.condition; -import java.util.Objects; +import java.util.NoSuchElementException; import java.util.function.BiPredicate; import java.util.function.Function; import java.util.function.Predicate; @@ -24,7 +24,17 @@ import org.mybatis.dynamic.sql.AbstractTwoValueCondition; public class IsBetween<T> extends AbstractTwoValueCondition<T> { - private static final IsBetween<?> EMPTY = new IsBetween<>(null, null) { + private static final IsBetween<?> EMPTY = new IsBetween<Object>(-1, -1) { + @Override + public Object value1() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public Object value2() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + @Override public boolean isEmpty() { return true; @@ -37,7 +47,7 @@ public static <T> IsBetween<T> empty() { return t; } - protected IsBetween(@Nullable T value1, @Nullable T value2) { + protected IsBetween(T value1, T value2) { super(value1, value2); } @@ -88,7 +98,7 @@ public <R> IsBetween<R> map(Function<? super T, ? extends R> mapper) { return map(mapper, mapper); } - public static <T> Builder<T> isBetween(@Nullable T value1) { + public static <T> Builder<T> isBetween(T value1) { return new Builder<>(value1); } @@ -97,24 +107,28 @@ public static <T> WhenPresentBuilder<T> isBetweenWhenPresent(@Nullable T value1) } public static class Builder<T> extends AndGatherer<T, IsBetween<T>> { - private Builder(@Nullable T value1) { + private Builder(T value1) { super(value1); } @Override - protected IsBetween<T> build() { + protected IsBetween<T> build(T value2) { return new IsBetween<>(value1, value2); } } - public static class WhenPresentBuilder<T> extends AndGatherer<T, IsBetween<T>> { + public static class WhenPresentBuilder<T> extends AndWhenPresentGatherer<T, IsBetween<T>> { private WhenPresentBuilder(@Nullable T value1) { super(value1); } @Override - protected IsBetween<T> build() { - return new IsBetween<>(value1, value2).filter(Objects::nonNull); + protected IsBetween<T> build(@Nullable T value2) { + if (value1 == null || value2 == null) { + return IsBetween.empty(); + } else { + return new IsBetween<>(value1, value2); + } } } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java index 2f748c18c..ed664aec1 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java @@ -15,7 +15,7 @@ */ package org.mybatis.dynamic.sql.where.condition; -import java.util.Objects; +import java.util.NoSuchElementException; import java.util.function.BiPredicate; import java.util.function.Function; import java.util.function.Predicate; @@ -24,7 +24,17 @@ import org.mybatis.dynamic.sql.AbstractTwoValueCondition; public class IsNotBetween<T> extends AbstractTwoValueCondition<T> { - private static final IsNotBetween<?> EMPTY = new IsNotBetween<>(null, null) { + private static final IsNotBetween<?> EMPTY = new IsNotBetween<Object>(-1, -1) { + @Override + public Object value1() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public Object value2() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + @Override public boolean isEmpty() { return true; @@ -37,7 +47,7 @@ public static <T> IsNotBetween<T> empty() { return t; } - protected IsNotBetween(@Nullable T value1, @Nullable T value2) { + protected IsNotBetween(T value1, T value2) { super(value1, value2); } @@ -89,7 +99,7 @@ public <R> IsNotBetween<R> map(Function<? super T, ? extends R> mapper) { return map(mapper, mapper); } - public static <T> Builder<T> isNotBetween(@Nullable T value1) { + public static <T> Builder<T> isNotBetween(T value1) { return new Builder<>(value1); } @@ -99,25 +109,29 @@ public static <T> WhenPresentBuilder<T> isNotBetweenWhenPresent(@Nullable T valu public static class Builder<T> extends AndGatherer<T, IsNotBetween<T>> { - private Builder(@Nullable T value1) { + private Builder(T value1) { super(value1); } @Override - protected IsNotBetween<T> build() { + protected IsNotBetween<T> build(T value2) { return new IsNotBetween<>(value1, value2); } } - public static class WhenPresentBuilder<T> extends AndGatherer<T, IsNotBetween<T>> { + public static class WhenPresentBuilder<T> extends AndWhenPresentGatherer<T, IsNotBetween<T>> { private WhenPresentBuilder(@Nullable T value1) { super(value1); } @Override - protected IsNotBetween<T> build() { - return new IsNotBetween<>(value1, value2).filter(Objects::nonNull); + protected IsNotBetween<T> build(@Nullable T value2) { + if (value1 == null || value2 == null) { + return IsNotBetween.empty(); + } else { + return new IsNotBetween<>(value1, value2); + } } } } diff --git a/src/test/java/issues/gh105/Issue105Test.java b/src/test/java/issues/gh105/Issue105Test.java index cf400e0a7..b5baa85e3 100644 --- a/src/test/java/issues/gh105/Issue105Test.java +++ b/src/test/java/issues/gh105/Issue105Test.java @@ -527,7 +527,7 @@ void testBetweenTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(age, isBetween(1).and((Integer) null).filter(Predicates.bothPresent()).map(i1 -> i1 + 1, i2 -> i2 + 2)) + .where(age, isBetweenWhenPresent(1).and((Integer) null).filter(Predicates.bothPresent()).map(i1 -> i1 + 1, i2 -> i2 + 2)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java index 3c6d64032..f35b61853 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java @@ -53,8 +53,8 @@ void testIsBetweenWhenPresent() { @Test void testIsBetweenWhenPresentNull() { IsBetween<Integer> cond = SqlBuilder.isBetweenWhenPresent(() -> (Integer) null).and(() -> null); - assertThat(cond.value1()).isNull(); - assertThat(cond.value2()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value1); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value2); assertThat(cond.isEmpty()).isTrue(); } @@ -85,8 +85,8 @@ void testIsNotBetweenWhenPresent() { @Test void testIsNotBetweenWhenPresentNull() { IsNotBetween<Integer> cond = SqlBuilder.isNotBetweenWhenPresent(() -> (Integer) null).and(() -> null); - assertThat(cond.value1()).isNull(); - assertThat(cond.value2()).isNull(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value1); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value2); assertThat(cond.isEmpty()).isTrue(); } From c907a423ab63f935555d20ee3b4182bbafd162de Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 3 Jan 2025 15:43:32 -0500 Subject: [PATCH 153/260] Refinements for null handling --- .../sql/insert/render/FieldAndValueAndParameters.java | 2 ++ .../org/mybatis/dynamic/sql/util/FragmentAndParameters.java | 2 ++ .../org/mybatis/dynamic/sql/util/ValueOrNullMapping.java | 4 ++-- .../mybatis/dynamic/sql/util/ValueWhenPresentMapping.java | 4 ++-- .../dynamic/sql/where/condition/IsInCaseInsensitive.java | 5 ++++- .../sql/where/condition/IsInCaseInsensitiveWhenPresent.java | 5 ++++- .../dynamic/sql/where/condition/IsLikeCaseInsensitive.java | 5 ++++- .../dynamic/sql/where/condition/IsNotInCaseInsensitive.java | 5 ++++- .../where/condition/IsNotInCaseInsensitiveWhenPresent.java | 5 ++++- .../sql/where/condition/IsNotLikeCaseInsensitive.java | 5 ++++- 10 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueAndParameters.java b/src/main/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueAndParameters.java index 2f98f0c3d..d923020c0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueAndParameters.java +++ b/src/main/java/org/mybatis/dynamic/sql/insert/render/FieldAndValueAndParameters.java @@ -65,6 +65,8 @@ public Builder withValuePhrase(String valuePhrase) { } public Builder withParameter(String key, @Nullable Object value) { + // the value can be null because a parameter type converter may return null + //noinspection DataFlowIssue parameters.put(key, value); return this; diff --git a/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java b/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java index cbbbf1e3b..3426accf8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/FragmentAndParameters.java @@ -72,6 +72,8 @@ public Builder withFragment(String fragment) { } public Builder withParameter(String key, @Nullable Object value) { + // the value can be null because a parameter type converter may return null + //noinspection DataFlowIssue parameters.put(key, value); return this; diff --git a/src/main/java/org/mybatis/dynamic/sql/util/ValueOrNullMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/ValueOrNullMapping.java index 8be5818e3..f39a706ac 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/ValueOrNullMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/ValueOrNullMapping.java @@ -28,7 +28,7 @@ public class ValueOrNullMapping<T> extends AbstractColumnMapping { // keep a reference to the column so we don't lose the type private final SqlColumn<T> localColumn; - private ValueOrNullMapping(SqlColumn<T> column, Supplier<T> valueSupplier) { + private ValueOrNullMapping(SqlColumn<T> column, Supplier<@Nullable T> valueSupplier) { super(column); this.valueSupplier = Objects.requireNonNull(valueSupplier); localColumn = Objects.requireNonNull(column); @@ -43,7 +43,7 @@ public <R> R accept(ColumnMappingVisitor<R> visitor) { return visitor.visit(this); } - public static <T> ValueOrNullMapping<T> of(SqlColumn<T> column, Supplier<T> valueSupplier) { + public static <T> ValueOrNullMapping<T> of(SqlColumn<T> column, Supplier<@Nullable T> valueSupplier) { return new ValueOrNullMapping<>(column, valueSupplier); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java index cf146651c..a9dae6c66 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java @@ -28,7 +28,7 @@ public class ValueWhenPresentMapping<T> extends AbstractColumnMapping { // keep a reference to the column so we don't lose the type private final SqlColumn<T> localColumn; - private ValueWhenPresentMapping(SqlColumn<T> column, Supplier<T> valueSupplier) { + private ValueWhenPresentMapping(SqlColumn<T> column, Supplier<@Nullable T> valueSupplier) { super(column); this.valueSupplier = Objects.requireNonNull(valueSupplier); localColumn = Objects.requireNonNull(column); @@ -47,7 +47,7 @@ public <R> R accept(ColumnMappingVisitor<R> visitor) { return visitor.visit(this); } - public static <T> ValueWhenPresentMapping<T> of(SqlColumn<T> column, Supplier<T> valueSupplier) { + public static <T> ValueWhenPresentMapping<T> of(SqlColumn<T> column, Supplier<@Nullable T> valueSupplier) { return new ValueWhenPresentMapping<>(column, valueSupplier); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java index d0fc67a23..6f14406fa 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java @@ -23,6 +23,7 @@ import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.util.StringUtilities; import org.mybatis.dynamic.sql.util.Validator; public class IsInCaseInsensitive extends AbstractListValueCondition<String> @@ -69,6 +70,8 @@ public static IsInCaseInsensitive of(String... values) { } public static IsInCaseInsensitive of(Collection<String> values) { - return new IsInCaseInsensitive(values).map(String::toUpperCase); + // Keep the null safe upper case utility for backwards compatibility + //noinspection DataFlowIssue + return new IsInCaseInsensitive(values).map(StringUtilities::safelyUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java index 64111df90..d366f0857 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java @@ -23,6 +23,7 @@ import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; +import org.mybatis.dynamic.sql.util.StringUtilities; import org.mybatis.dynamic.sql.util.Utilities; public class IsInCaseInsensitiveWhenPresent extends AbstractListValueCondition<String> @@ -65,6 +66,8 @@ public static IsInCaseInsensitiveWhenPresent of(@Nullable String... values) { } public static IsInCaseInsensitiveWhenPresent of(Collection<@Nullable String> values) { - return new IsInCaseInsensitiveWhenPresent(values).map(String::toUpperCase); + // Keep the null safe upper case utility for backwards compatibility + //noinspection DataFlowIssue + return new IsInCaseInsensitiveWhenPresent(values).map(StringUtilities::safelyUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java index e44a9f74c..ccf6699ee 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java @@ -20,6 +20,7 @@ import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; +import org.mybatis.dynamic.sql.util.StringUtilities; public class IsLikeCaseInsensitive extends AbstractSingleValueCondition<String> implements CaseInsensitiveVisitableCondition { @@ -66,6 +67,8 @@ public IsLikeCaseInsensitive map(UnaryOperator<String> mapper) { } public static IsLikeCaseInsensitive of(String value) { - return new IsLikeCaseInsensitive(value).map(String::toUpperCase); + // Keep the null safe upper case utility for backwards compatibility + //noinspection DataFlowIssue + return new IsLikeCaseInsensitive(value).map(StringUtilities::safelyUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java index 113de053d..b4c1e96a7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java @@ -23,6 +23,7 @@ import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.util.StringUtilities; import org.mybatis.dynamic.sql.util.Validator; public class IsNotInCaseInsensitive extends AbstractListValueCondition<String> @@ -69,6 +70,8 @@ public static IsNotInCaseInsensitive of(String... values) { } public static IsNotInCaseInsensitive of(Collection<String> values) { - return new IsNotInCaseInsensitive(values).map(String::toUpperCase); + // Keep the null safe upper case utility for backwards compatibility + //noinspection DataFlowIssue + return new IsNotInCaseInsensitive(values).map(StringUtilities::safelyUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java index c2b0a0e2f..5562b0ff4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java @@ -23,6 +23,7 @@ import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; +import org.mybatis.dynamic.sql.util.StringUtilities; import org.mybatis.dynamic.sql.util.Utilities; public class IsNotInCaseInsensitiveWhenPresent extends AbstractListValueCondition<String> @@ -65,6 +66,8 @@ public static IsNotInCaseInsensitiveWhenPresent of(@Nullable String... values) { } public static IsNotInCaseInsensitiveWhenPresent of(Collection<@Nullable String> values) { - return new IsNotInCaseInsensitiveWhenPresent(values).map(String::toUpperCase); + // Keep the null safe upper case utility for backwards compatibility + //noinspection DataFlowIssue + return new IsNotInCaseInsensitiveWhenPresent(values).map(StringUtilities::safelyUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java index ec073a162..5d9d8c3af 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java @@ -20,6 +20,7 @@ import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; +import org.mybatis.dynamic.sql.util.StringUtilities; public class IsNotLikeCaseInsensitive extends AbstractSingleValueCondition<String> implements CaseInsensitiveVisitableCondition { @@ -68,6 +69,8 @@ public IsNotLikeCaseInsensitive map(UnaryOperator<String> mapper) { } public static IsNotLikeCaseInsensitive of(String value) { - return new IsNotLikeCaseInsensitive(value).map(String::toUpperCase); + // Keep the null safe upper case utility for backwards compatibility + //noinspection DataFlowIssue + return new IsNotLikeCaseInsensitive(value).map(StringUtilities::safelyUpperCase); } } From 9b235702709e90d655be747bc8103333f16a8c52 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 3 Jan 2025 16:22:20 -0500 Subject: [PATCH 154/260] Doc updates --- CHANGELOG.md | 29 ++++++++++++++++++++++------- README.md | 8 ++++++-- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e103bd04..1faccde61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,8 +28,15 @@ worked to make these changes as minimal as possible. ### Adoption of JSpecify (https://jspecify.dev/) Following the lead of many other projects (including The Spring Framework), we have adopted JSpecify to fully -specify the null handling properties of this library. In general, the library does not expect that you will pass a null -value into any method. There are two exceptions to this rule: +document the null handling properties of this library. JSpecify is now a runtime dependency of this library - as is +recommended practice with JSpecify. + +This change should not impact the running of any existing code, but depending on your usage you may see new IDE or +tooling warnings based on the declared nullability of methods in the library. You may choose to ignore the +warnings and things should continue to function. Of course, we recommend that you do not ignore these warnings! + +In general, the library does not expect that you will pass a null value into any method. There are two exceptions to +this rule: 1. Some builder methods will accept a null value if the target object will properly handle null values through the use of java.util.Optional @@ -38,12 +45,20 @@ value into any method. There are two exceptions to this rule: As you might expect, standardizing null handling revealed some issues in the library that may impact you: -Case-insensitive conditions like "isLikeCaseInsensitive" will now throw a NullPointerException if you pass in null -values. +Fixing compiler warnings and errors: + +1. We expect that most of the warnings you encounter will be related to passing null values into a where condition. + These warnings should be resolved by changing your code to use the "WhenPresent" versions of methods as those + methods handle null values in a predictable way. +2. Java Classes that extend "AliasableSqlTable" will likely see IDE warnings about non-null type arguments. This can be + resolved by adding a "@NullMarked" annotation to the class or package. This issue does not affect Kotlin classes + that extend "AliasableSqlTable". + +Runtime behavior changes: -The where conditions (isEqualTo, isLessThan, etc.) can be filtered and result in an "empty" condition - -similar to java.util.Optional. Previously, calling a "value" method of the condition would return null. Now -those methods will throw "NoSuchElementException". This should not impact you in normal usage. +1. The where conditions (isEqualTo, isLessThan, etc.) can be filtered and result in an "empty" condition - + similar to java.util.Optional. Previously, calling a "value" method of the condition would return null. Now + those methods will throw "NoSuchElementException". This should not impact you in normal usage. ### Other important changes: diff --git a/README.md b/README.md index 812dc3b9d..3a536a47a 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,10 @@ The library test cases provide several complete examples of using the library in | Kotlin | Spring JDBC | Example using Kotlin utility classes for Spring JDBC Template | [../examples/kotlin/spring/canonical](src/test/kotlin/examples/kotlin/spring/canonical) | -## Requirements +## Requirements and Dependencies -The library has no dependencies. Version 2.x requires Java 17. Version 1.x requires Java 8. +Version 2.x requires Java 17 and has a required runtime dependency on JSpecify (https://jspecify.dev/). Version 1.x +requires Java 8 and has no required runtime dependencies. + +All versions have support for MyBatis3, Spring Framework, and Kotlin - all those dependencies are optional. The library +should work in those environments as the dependencies will be made available at runtime. From e15d3592ca8d4e0fe60d3c6593c01b35976fe1e9 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 3 Jan 2025 16:53:44 -0500 Subject: [PATCH 155/260] Revert test changes to check backwards compatibility --- .../examples/animal/data/AnimalDataTest.java | 18 ++++++- .../java/examples/animal/data/Length.java | 2 - ...onditionsWithPredicatesAnimalDataTest.java | 34 ++++++------ .../custom_render/JsonRenderingStrategy.java | 2 - .../joins/ItemMasterDynamicSQLSupport.java | 2 - .../examples/joins/UserDynamicSQLSupport.java | 2 - .../paging/LimitAndOffsetAdapter.java | 2 - .../sharding/TableCodesDynamicSqlSupport.java | 2 - .../spring/LastNameParameterConverter.java | 5 +- .../spring/YesNoParameterConverter.java | 6 +-- .../examples/type_conversion/ToBase64.java | 2 - src/test/java/issues/gh105/Issue105Test.java | 8 +-- .../mybatis/dynamic/sql/InvalidSQLTest.java | 5 +- .../sql/insert/InsertStatementTest.java | 17 +++--- .../sql/where/condition/FilterAndMapTest.java | 23 ++++---- .../sql/where/condition/SupplierTest.java | 54 +++++++++---------- .../custom/render/KCustomRenderingTest.kt | 2 +- 17 files changed, 92 insertions(+), 94 deletions(-) diff --git a/src/test/java/examples/animal/data/AnimalDataTest.java b/src/test/java/examples/animal/data/AnimalDataTest.java index b1d5844da..a883b4bd2 100644 --- a/src/test/java/examples/animal/data/AnimalDataTest.java +++ b/src/test/java/examples/animal/data/AnimalDataTest.java @@ -744,7 +744,7 @@ void testInCaseSensitiveCondition() { SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isInCaseInsensitive("yellow-bellied marmot", "verbet")) + .where(animalName, isInCaseInsensitive("yellow-bellied marmot", "verbet", null)) .build() .render(RenderingStrategies.MYBATIS3); @@ -785,6 +785,22 @@ void testNotInCaseSensitiveCondition() { } } + @Test + void testNotInCaseSensitiveConditionWithNull() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); + + SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) + .from(animalData) + .where(animalName, isNotInCaseInsensitive((String)null)) + .build() + .render(RenderingStrategies.MYBATIS3); + + List<AnimalData> animals = mapper.selectMany(selectStatement); + assertThat(animals).isEmpty(); + } + } + @Test void testNotInConditionWithEventuallyEmptyList() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { diff --git a/src/test/java/examples/animal/data/Length.java b/src/test/java/examples/animal/data/Length.java index 8358ecce6..a7a8abcb5 100644 --- a/src/test/java/examples/animal/data/Length.java +++ b/src/test/java/examples/animal/data/Length.java @@ -18,14 +18,12 @@ import java.sql.JDBCType; import java.util.Optional; -import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.function.AbstractTypeConvertingFunction; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -@NullMarked public class Length extends AbstractTypeConvertingFunction<Object, Integer, Length> { private Length(BasicColumn column) { super(column); diff --git a/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java b/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java index cdbc250d9..da59bffc7 100644 --- a/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java +++ b/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java @@ -78,7 +78,7 @@ void testAllIgnored() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isGreaterThanWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) // the where clause should not render + .where(id, isGreaterThan(NULL_INTEGER).filter(Objects::nonNull)) // the where clause should not render .orderBy(id) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() @@ -120,7 +120,7 @@ void testIgnoredBetweenRendered() { SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) .where(id, isEqualTo(3)) - .and(id, isNotEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) + .and(id, isNotEqualTo(NULL_INTEGER).filter(Objects::nonNull)) .or(id, isEqualTo(4).filter(Objects::nonNull)) .orderBy(id) .build() @@ -141,7 +141,7 @@ void testIgnoredInWhere() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThanWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull)) .and(id, isEqualTo(3).filter(Objects::nonNull)) .or(id, isEqualTo(4).filter(Objects::nonNull)) .orderBy(id) @@ -163,10 +163,10 @@ void testManyIgnored() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThanWhenPresent(NULL_INTEGER).filter(Objects::nonNull), and(id, isGreaterThanOrEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull))) - .and(id, isEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull), or(id, isEqualTo(3), and(id, isLessThanWhenPresent(NULL_INTEGER).filter(Objects::nonNull)))) - .or(id, isEqualTo(4).filter(Objects::nonNull), and(id, isGreaterThanOrEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull))) - .and(id, isNotEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull), and(id, isGreaterThanOrEqualTo(NULL_INTEGER).filter(Objects::nonNull))) + .and(id, isEqualTo(NULL_INTEGER).filter(Objects::nonNull), or(id, isEqualTo(3), and(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull)))) + .or(id, isEqualTo(4).filter(Objects::nonNull), and(id, isGreaterThanOrEqualTo(NULL_INTEGER).filter(Objects::nonNull))) + .and(id, isNotEqualTo(NULL_INTEGER).filter(Objects::nonNull)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -186,7 +186,7 @@ void testIgnoredInitialWhere() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThanWhenPresent(NULL_INTEGER).filter(Objects::nonNull), and(id, isEqualTo(3).filter(Objects::nonNull))) + .where(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull), and(id, isEqualTo(3).filter(Objects::nonNull))) .or(id, isEqualTo(4).filter(Objects::nonNull)) .orderBy(id) .build() @@ -226,7 +226,7 @@ void testEqualWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isEqualTo(NULL_INTEGER).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -266,7 +266,7 @@ void testNotEqualWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isNotEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isNotEqualTo(NULL_INTEGER).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -306,7 +306,7 @@ void testGreaterThanWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isGreaterThanWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isGreaterThan(NULL_INTEGER).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -346,7 +346,7 @@ void testGreaterThanOrEqualToWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isGreaterThanOrEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isGreaterThanOrEqualTo(NULL_INTEGER).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -385,7 +385,7 @@ void testLessThanWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThanWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -424,7 +424,7 @@ void testLessThanOrEqualToWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThanOrEqualToWhenPresent(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isLessThanOrEqualTo(NULL_INTEGER).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -862,7 +862,7 @@ void testIsLikeCaseInsensitiveWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isLikeCaseInsensitiveWhenPresent((String) null).filter(Objects::nonNull)) + .where(animalName, isLikeCaseInsensitive((String) null).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -902,7 +902,7 @@ void testIsNotLikeWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isNotLikeWhenPresent((String) null).filter(Objects::nonNull)) + .where(animalName, isNotLike((String) null).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -942,7 +942,7 @@ void testIsNotLikeCaseInsensitiveWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isNotLikeCaseInsensitiveWhenPresent((String) null).filter(Objects::nonNull)) + .where(animalName, isNotLikeCaseInsensitive((String) null).filter(Objects::nonNull)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() diff --git a/src/test/java/examples/custom_render/JsonRenderingStrategy.java b/src/test/java/examples/custom_render/JsonRenderingStrategy.java index 0f9838329..62c822e93 100644 --- a/src/test/java/examples/custom_render/JsonRenderingStrategy.java +++ b/src/test/java/examples/custom_render/JsonRenderingStrategy.java @@ -15,11 +15,9 @@ */ package examples.custom_render; -import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.MyBatis3RenderingStrategy; -@NullMarked public class JsonRenderingStrategy extends MyBatis3RenderingStrategy { @Override diff --git a/src/test/java/examples/joins/ItemMasterDynamicSQLSupport.java b/src/test/java/examples/joins/ItemMasterDynamicSQLSupport.java index 5e5b836fa..15bf72505 100644 --- a/src/test/java/examples/joins/ItemMasterDynamicSQLSupport.java +++ b/src/test/java/examples/joins/ItemMasterDynamicSQLSupport.java @@ -17,11 +17,9 @@ import java.sql.JDBCType; -import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.AliasableSqlTable; import org.mybatis.dynamic.sql.SqlColumn; -@NullMarked public final class ItemMasterDynamicSQLSupport { public static final ItemMaster itemMaster = new ItemMaster(); public static final SqlColumn<Integer> itemId = itemMaster.itemId; diff --git a/src/test/java/examples/joins/UserDynamicSQLSupport.java b/src/test/java/examples/joins/UserDynamicSQLSupport.java index 05bf6330e..883cd81e9 100644 --- a/src/test/java/examples/joins/UserDynamicSQLSupport.java +++ b/src/test/java/examples/joins/UserDynamicSQLSupport.java @@ -17,11 +17,9 @@ import java.sql.JDBCType; -import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.AliasableSqlTable; import org.mybatis.dynamic.sql.SqlColumn; -@NullMarked public class UserDynamicSQLSupport { public static final User user = new User(); public final SqlColumn<Integer> userId = user.userId; diff --git a/src/test/java/examples/paging/LimitAndOffsetAdapter.java b/src/test/java/examples/paging/LimitAndOffsetAdapter.java index 4bf136a8b..de4dafab7 100644 --- a/src/test/java/examples/paging/LimitAndOffsetAdapter.java +++ b/src/test/java/examples/paging/LimitAndOffsetAdapter.java @@ -20,7 +20,6 @@ import java.util.Objects; import java.util.function.Function; -import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.render.RenderingStrategies; import org.mybatis.dynamic.sql.select.SelectModel; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; @@ -41,7 +40,6 @@ * * @author Jeff Butler */ -@NullMarked public class LimitAndOffsetAdapter<R> { private final SelectModel selectModel; private final Function<SelectStatementProvider, R> mapperMethod; diff --git a/src/test/java/examples/sharding/TableCodesDynamicSqlSupport.java b/src/test/java/examples/sharding/TableCodesDynamicSqlSupport.java index 96d66c20a..6cec6e9c8 100644 --- a/src/test/java/examples/sharding/TableCodesDynamicSqlSupport.java +++ b/src/test/java/examples/sharding/TableCodesDynamicSqlSupport.java @@ -17,11 +17,9 @@ import java.sql.JDBCType; -import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.AliasableSqlTable; import org.mybatis.dynamic.sql.SqlColumn; -@NullMarked public final class TableCodesDynamicSqlSupport { public static final TableCodes tableCodes = new TableCodes(); public static final SqlColumn<Integer> id = tableCodes.id; diff --git a/src/test/java/examples/spring/LastNameParameterConverter.java b/src/test/java/examples/spring/LastNameParameterConverter.java index 51f972cf6..f69c83b3a 100644 --- a/src/test/java/examples/spring/LastNameParameterConverter.java +++ b/src/test/java/examples/spring/LastNameParameterConverter.java @@ -15,14 +15,13 @@ */ package examples.spring; -import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.ParameterTypeConverter; import org.springframework.core.convert.converter.Converter; public class LastNameParameterConverter implements ParameterTypeConverter<LastName, String>, Converter<LastName, String> { @Override - public @Nullable String convert(LastName source) { - return source.getName(); + public String convert(LastName source) { + return source == null ? null : source.getName(); } } diff --git a/src/test/java/examples/spring/YesNoParameterConverter.java b/src/test/java/examples/spring/YesNoParameterConverter.java index 166020620..131c0d84a 100644 --- a/src/test/java/examples/spring/YesNoParameterConverter.java +++ b/src/test/java/examples/spring/YesNoParameterConverter.java @@ -15,14 +15,12 @@ */ package examples.spring; -import org.jspecify.annotations.NonNull; -import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.ParameterTypeConverter; public class YesNoParameterConverter implements ParameterTypeConverter<Boolean, String> { @Override - public @Nullable String convert(@NonNull Boolean source) { - return source ? "Yes" : "No"; + public String convert(Boolean source) { + return source == null ? null : source ? "Yes" : "No"; } } diff --git a/src/test/java/examples/type_conversion/ToBase64.java b/src/test/java/examples/type_conversion/ToBase64.java index d6de2ff76..46cdb26ed 100644 --- a/src/test/java/examples/type_conversion/ToBase64.java +++ b/src/test/java/examples/type_conversion/ToBase64.java @@ -18,14 +18,12 @@ import java.sql.JDBCType; import java.util.Optional; -import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.function.AbstractTypeConvertingFunction; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -@NullMarked public class ToBase64 extends AbstractTypeConvertingFunction<byte[], String, ToBase64> { protected ToBase64(BasicColumn column) { diff --git a/src/test/java/issues/gh105/Issue105Test.java b/src/test/java/issues/gh105/Issue105Test.java index b5baa85e3..8fb16f22d 100644 --- a/src/test/java/issues/gh105/Issue105Test.java +++ b/src/test/java/issues/gh105/Issue105Test.java @@ -57,7 +57,7 @@ void testFuzzyLikeFirstNameNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(firstName, isLikeWhenPresent(fName).filter(Objects::nonNull).map(SearchUtils::addWildcards)) + .where(firstName, isLike(fName).filter(Objects::nonNull).map(SearchUtils::addWildcards)) .and(lastName, isLike(lName).filter(Objects::nonNull).map(SearchUtils::addWildcards)) .build() .render(RenderingStrategies.MYBATIS3); @@ -527,7 +527,7 @@ void testBetweenTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(age, isBetweenWhenPresent(1).and((Integer) null).filter(Predicates.bothPresent()).map(i1 -> i1 + 1, i2 -> i2 + 2)) + .where(age, isBetween(1).and((Integer) null).filter(Predicates.bothPresent()).map(i1 -> i1 + 1, i2 -> i2 + 2)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); @@ -735,7 +735,7 @@ void testLikeCaseInsensitiveTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(firstName, isLikeCaseInsensitiveWhenPresent((String) null).filter(Objects::nonNull).map(SearchUtils::addWildcards)) + .where(firstName, isLikeCaseInsensitive((String) null).filter(Objects::nonNull).map(SearchUtils::addWildcards)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); @@ -863,7 +863,7 @@ void testNotLikeCaseInsensitiveTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(firstName, isNotLikeCaseInsensitiveWhenPresent((String) null).filter(Objects::nonNull).map(SearchUtils::addWildcards)) + .where(firstName, isNotLikeCaseInsensitive((String) null).filter(Objects::nonNull).map(SearchUtils::addWildcards)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); diff --git a/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java b/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java index 4f96f14de..2464a4000 100644 --- a/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java @@ -27,7 +27,6 @@ import java.util.MissingResourceException; import java.util.Optional; -import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; @@ -262,9 +261,9 @@ void testInvalidValueAlias() { } static class TestRow { - private @Nullable Integer id; + private Integer id; - public @Nullable Integer getId() { + public Integer getId() { return id; } 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 ef0f94bfc..e991bef02 100644 --- a/src/test/java/org/mybatis/dynamic/sql/insert/InsertStatementTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/insert/InsertStatementTest.java @@ -20,7 +20,6 @@ import java.sql.JDBCType; -import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.SqlTable; @@ -117,12 +116,12 @@ void testSelectiveInsertStatementBuilder() { } static class TestRecord { - private @Nullable Integer id; - private @Nullable String firstName; - private @Nullable String lastName; - private @Nullable String occupation; + private Integer id; + private String firstName; + private String lastName; + private String occupation; - @Nullable Integer getId() { + Integer getId() { return id; } @@ -130,7 +129,7 @@ void setId(Integer id) { this.id = id; } - @Nullable String getFirstName() { + String getFirstName() { return firstName; } @@ -138,7 +137,7 @@ void setFirstName(String firstName) { this.firstName = firstName; } - @Nullable String getLastName() { + String getLastName() { return lastName; } @@ -146,7 +145,7 @@ void setLastName(String lastName) { this.lastName = lastName; } - @Nullable String getOccupation() { + String getOccupation() { return occupation; } diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java index cb05b28b7..bd5f2e2cd 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java @@ -22,7 +22,6 @@ import java.util.NoSuchElementException; import java.util.Objects; -import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.SqlBuilder; @@ -35,14 +34,16 @@ void testTypeConversion() { } @Test - void testTypeConversionWithEmptyDoesNotThrowException() { - SqlBuilder.isEqualToWhenPresent((String) null).map(Integer::parseInt); - assertThat(true).isTrue(); + void testTypeConversionWithNullThrowsException() { + IsEqualTo<String> cond = SqlBuilder.isEqualTo((String) null); + assertThatExceptionOfType(NumberFormatException.class).isThrownBy(() -> + cond.map(Integer::parseInt) + ); } @Test void testTypeConversionWithNullAndFilterDoesNotThrowException() { - IsEqualTo<Integer> cond = SqlBuilder.isEqualToWhenPresent((String) null).filter(Objects::nonNull).map(Integer::parseInt); + IsEqualTo<Integer> cond = SqlBuilder.isEqualTo((String) null).filter(Objects::nonNull).map(Integer::parseInt); assertThat(cond.isEmpty()).isTrue(); } @@ -431,7 +432,7 @@ void testIsInRenderableMapShouldReturnMappedObject() { IsIn<String> cond = SqlBuilder.isIn("Fred", "Wilma"); assertThat(cond.isEmpty()).isFalse(); IsIn<String> mapped = cond.map(String::toUpperCase); - List<@Nullable String> mappedValues = mapped.values().toList(); + List<String> mappedValues = mapped.values().toList(); assertThat(mappedValues).containsExactly("FRED", "WILMA"); } @@ -440,31 +441,31 @@ void testIsNotInRenderableMapShouldReturnMappedObject() { IsNotIn<String> cond = SqlBuilder.isNotIn("Fred", "Wilma"); assertThat(cond.isEmpty()).isFalse(); IsNotIn<String> mapped = cond.map(String::toUpperCase); - List<@Nullable String> mappedValues = mapped.values().toList(); + List<String> mappedValues = mapped.values().toList(); assertThat(mappedValues).containsExactly("FRED", "WILMA"); } @Test void testIsNotInCaseInsensitiveRenderableMapShouldReturnMappedObject() { IsNotInCaseInsensitive cond = SqlBuilder.isNotInCaseInsensitive("Fred ", "Wilma "); - List<@Nullable String> values = cond.values().toList(); + List<String> values = cond.values().toList(); assertThat(values).containsExactly("FRED ", "WILMA "); assertThat(cond.isEmpty()).isFalse(); IsNotInCaseInsensitive mapped = cond.map(String::trim); - List<@Nullable String> mappedValues = mapped.values().toList(); + List<String> mappedValues = mapped.values().toList(); assertThat(mappedValues).containsExactly("FRED", "WILMA"); } @Test void testIsInCaseInsensitiveRenderableMapShouldReturnMappedObject() { IsInCaseInsensitive cond = SqlBuilder.isInCaseInsensitive("Fred ", "Wilma "); - List<@Nullable String> values = cond.values().toList(); + List<String> values = cond.values().toList(); assertThat(values).containsExactly("FRED ", "WILMA "); assertThat(cond.isEmpty()).isFalse(); IsInCaseInsensitive mapped = cond.map(String::trim); - List<@Nullable String> mappedValues = mapped.values().toList(); + List<String> mappedValues = mapped.values().toList(); assertThat(mappedValues).containsExactly("FRED", "WILMA"); } diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java index f35b61853..e1362d48f 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java @@ -113,9 +113,9 @@ void testIsNotEqualTo() { @Test void testIsNotEqualToNull() { - IsNotEqualTo<Integer> cond = SqlBuilder.isNotEqualToWhenPresent(() -> null); - assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); - assertThat(cond.isEmpty()).isTrue(); + IsNotEqualTo<Integer> cond = SqlBuilder.isNotEqualTo(() -> (Integer) null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); } @Test @@ -141,9 +141,9 @@ void testIsGreaterThan() { @Test void testIsGreaterThanNull() { - IsGreaterThan<Integer> cond = SqlBuilder.isGreaterThanWhenPresent(() -> null); - assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); - assertThat(cond.isEmpty()).isTrue(); + IsGreaterThan<Integer> cond = SqlBuilder.isGreaterThan(() -> (Integer) null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); } @Test @@ -169,9 +169,9 @@ void testIsGreaterThanOrEqualTo() { @Test void testIsGreaterThanOrEqualToNull() { - IsGreaterThanOrEqualTo<Integer> cond = SqlBuilder.isGreaterThanOrEqualToWhenPresent(() -> null); - assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); - assertThat(cond.isEmpty()).isTrue(); + IsGreaterThanOrEqualTo<Integer> cond = SqlBuilder.isGreaterThanOrEqualTo(() -> (Integer) null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); } @Test @@ -197,9 +197,9 @@ void testIsLessThan() { @Test void testIsLessThanNull() { - IsLessThan<Integer> cond = SqlBuilder.isLessThanWhenPresent(() -> null); - assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); - assertThat(cond.isEmpty()).isTrue(); + IsLessThan<Integer> cond = SqlBuilder.isLessThan(() -> (Integer) null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); } @Test @@ -225,9 +225,9 @@ void testIsLessThanOrEqualTo() { @Test void testIsLessThanOrEqualToNull() { - IsLessThanOrEqualTo<Integer> cond = SqlBuilder.isLessThanOrEqualToWhenPresent(() -> null); - assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); - assertThat(cond.isEmpty()).isTrue(); + IsLessThanOrEqualTo<Integer> cond = SqlBuilder.isLessThanOrEqualTo(() -> (Integer) null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); } @Test @@ -253,9 +253,9 @@ void testIsLike() { @Test void testIsLikeNull() { - IsLike<String> cond = SqlBuilder.isLikeWhenPresent(() -> null); - assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); - assertThat(cond.isEmpty()).isTrue(); + IsLike<String> cond = SqlBuilder.isLike(() -> null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); } @Test @@ -267,9 +267,9 @@ void testIsLikeCaseInsensitive() { @Test void testIsLikeCaseInsensitiveNull() { - IsLikeCaseInsensitive cond = SqlBuilder.isLikeCaseInsensitiveWhenPresent(() -> null); - assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); - assertThat(cond.isEmpty()).isTrue(); + IsLikeCaseInsensitive cond = SqlBuilder.isLikeCaseInsensitive(() -> null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); } @Test @@ -309,9 +309,9 @@ void testIsNotLike() { @Test void testIsNotLikeNull() { - IsNotLike<String> cond = SqlBuilder.isNotLikeWhenPresent(() -> null); - assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); - assertThat(cond.isEmpty()).isTrue(); + IsNotLike<String> cond = SqlBuilder.isNotLike(() -> null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); } @Test @@ -337,9 +337,9 @@ void testIsNotLikeCaseInsensitive() { @Test void testIsNotLikeCaseInsensitiveNull() { - IsNotLikeCaseInsensitive cond = SqlBuilder.isNotLikeCaseInsensitiveWhenPresent(() -> null); - assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); - assertThat(cond.isEmpty()).isTrue(); + IsNotLikeCaseInsensitive cond = SqlBuilder.isNotLikeCaseInsensitive(() -> null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); } @Test diff --git a/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KCustomRenderingTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KCustomRenderingTest.kt index 47a6fcaed..d0c7e7a04 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KCustomRenderingTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KCustomRenderingTest.kt @@ -304,7 +304,7 @@ class KCustomRenderingTest { } } - private fun <T : Any> dereference(column: SqlColumn<T>, attribute: String) = + private fun <T> dereference(column: SqlColumn<T>, attribute: String) = SqlColumn.of<String>(column.name() + "->>'" + attribute + "'", column.table(), JDBCType.VARCHAR) companion object { From ea8354eb501287d3ec15f50131d1ea9fe8437d44 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 3 Jan 2025 17:04:01 -0500 Subject: [PATCH 156/260] Checkstyle --- .../java/org/mybatis/dynamic/sql/where/condition/IsBetween.java | 2 +- .../org/mybatis/dynamic/sql/where/condition/IsNotBetween.java | 2 +- .../data/OptionalConditionsWithPredicatesAnimalDataTest.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java index aebb34ca1..deeddb4c9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java @@ -125,7 +125,7 @@ private WhenPresentBuilder(@Nullable T value1) { @Override protected IsBetween<T> build(@Nullable T value2) { if (value1 == null || value2 == null) { - return IsBetween.empty(); + return empty(); } else { return new IsBetween<>(value1, value2); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java index ed664aec1..5700de2ac 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java @@ -128,7 +128,7 @@ private WhenPresentBuilder(@Nullable T value1) { @Override protected IsNotBetween<T> build(@Nullable T value2) { if (value1 == null || value2 == null) { - return IsNotBetween.empty(); + return empty(); } else { return new IsNotBetween<>(value1, value2); } diff --git a/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java b/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java index da59bffc7..a46190941 100644 --- a/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java +++ b/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java @@ -108,7 +108,7 @@ void testSelectByNull() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id > #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(selectStatement.getParameters()).containsEntry("p1", null), - () -> assertThat(animals).hasSize(0) + () -> assertThat(animals).isEmpty() ); } } From 6f9dcc4a85b0e851103df715f90af9b13607bb0d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 3 Jan 2025 22:23:39 +0000 Subject: [PATCH 157/260] Update dependency org.mybatis:mybatis to v3.5.19 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5ca0dbf75..2ace93179 100644 --- a/pom.xml +++ b/pom.xml @@ -103,7 +103,7 @@ <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> - <version>3.5.18</version> + <version>3.5.19</version> <scope>provided</scope> <optional>true</optional> </dependency> From fe120edad89011b269987ad4ce36ad4f9a40c1df Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 3 Jan 2025 17:25:22 -0500 Subject: [PATCH 158/260] Documentation --- CHANGELOG.md | 27 +++++++++++++++++-- .../dynamic/sql/ParameterTypeConverter.java | 8 ++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1faccde61..324cff2e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ worked to make these changes as minimal as possible. ### Adoption of JSpecify (https://jspecify.dev/) Following the lead of many other projects (including The Spring Framework), we have adopted JSpecify to fully -document the null handling properties of this library. JSpecify is now a runtime dependency of this library - as is +document the null handling properties of this library. JSpecify is now a runtime dependency - as is recommended practice with JSpecify. This change should not impact the running of any existing code, but depending on your usage you may see new IDE or @@ -43,7 +43,7 @@ this rule: 2. Methods with names that include "WhenPresent" will properly handle null parameters (for example, "isEqualToWhenPresent") -As you might expect, standardizing null handling revealed some issues in the library that may impact you: +As you might expect, standardizing null handling revealed some issues in the library that may impact you. Fixing compiler warnings and errors: @@ -53,12 +53,35 @@ Fixing compiler warnings and errors: 2. Java Classes that extend "AliasableSqlTable" will likely see IDE warnings about non-null type arguments. This can be resolved by adding a "@NullMarked" annotation to the class or package. This issue does not affect Kotlin classes that extend "AliasableSqlTable". +3. Similarly, if you have coded any functions for use with your queries, you can resolve most IDE warnings by adding + the "@NullMarked" annotation. +4. If you have coded any Kotlin functions that operate on a generic Java class from the library, then you should + change the type parameter definition to specify a non-nullable type. For example... + + ```kotlin + import org.mybatis.dynamic.sql.SqlColumn + + fun <T> foo(column: SqlColumn<T>) { + } + ``` + + Should change to: + + ```kotlin + import org.mybatis.dynamic.sql.SqlColumn + + fun <T : Any> foo(column: SqlColumn<T>) { + } + ``` Runtime behavior changes: 1. The where conditions (isEqualTo, isLessThan, etc.) can be filtered and result in an "empty" condition - similar to java.util.Optional. Previously, calling a "value" method of the condition would return null. Now those methods will throw "NoSuchElementException". This should not impact you in normal usage. +2. We have updated the "ParameterTypeConverter" used in Spring applications to maintain compatibility with Spring's + "Converter" interface. The primary change is that the framework will no longer call a type converter if the + input value is null. This should simplify the coding of converters and foster reuse with existing Spring converters. ### Other important changes: diff --git a/src/main/java/org/mybatis/dynamic/sql/ParameterTypeConverter.java b/src/main/java/org/mybatis/dynamic/sql/ParameterTypeConverter.java index a37212e22..4f4856e19 100644 --- a/src/main/java/org/mybatis/dynamic/sql/ParameterTypeConverter.java +++ b/src/main/java/org/mybatis/dynamic/sql/ParameterTypeConverter.java @@ -52,5 +52,13 @@ */ @FunctionalInterface public interface ParameterTypeConverter<S, T> { + /** + * Convert the value from one value to another. + * + * <p>The input value will never be null - the framework will automatically handle nulls. + * + * @param source value as specified in the condition, or after a map operation. Never null. + * @return Possibly null converted value. + */ @Nullable T convert(S source); } From 11a13a95996a5594b8aed2715179e71c626c557d Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 3 Jan 2025 17:33:38 -0500 Subject: [PATCH 159/260] Proper file endings --- .../org/mybatis/dynamic/sql/select/aggregate/package-info.java | 2 +- .../mybatis/dynamic/sql/select/caseexpression/package-info.java | 2 +- src/main/java/org/mybatis/dynamic/sql/util/Buildable.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/package-info.java b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/package-info.java index 36235945c..60e9e8918 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/package-info.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/package-info.java @@ -16,4 +16,4 @@ @NullMarked package org.mybatis.dynamic.sql.select.aggregate; -import org.jspecify.annotations.NullMarked; \ No newline at end of file +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/package-info.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/package-info.java index 951a3da74..a383bc305 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/package-info.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/package-info.java @@ -16,4 +16,4 @@ @NullMarked package org.mybatis.dynamic.sql.select.caseexpression; -import org.jspecify.annotations.NullMarked; \ No newline at end of file +import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/org/mybatis/dynamic/sql/util/Buildable.java b/src/main/java/org/mybatis/dynamic/sql/util/Buildable.java index d65130a6e..1dcbe70ea 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/Buildable.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/Buildable.java @@ -18,4 +18,4 @@ @FunctionalInterface public interface Buildable<T> { T build(); -} \ No newline at end of file +} From 4f81c0732ba13f9854df257ba90a5a80fb413534 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Sat, 4 Jan 2025 07:29:58 -0500 Subject: [PATCH 160/260] Test refinements --- src/test/java/examples/spring/LastNameParameterConverter.java | 4 +++- src/test/java/examples/spring/YesNoParameterConverter.java | 4 +++- .../kotlin/mybatis3/custom/render/KCustomRenderingTest.kt | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/test/java/examples/spring/LastNameParameterConverter.java b/src/test/java/examples/spring/LastNameParameterConverter.java index f69c83b3a..2a45753d7 100644 --- a/src/test/java/examples/spring/LastNameParameterConverter.java +++ b/src/test/java/examples/spring/LastNameParameterConverter.java @@ -15,13 +15,15 @@ */ package examples.spring; +import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.ParameterTypeConverter; import org.springframework.core.convert.converter.Converter; +@NullMarked public class LastNameParameterConverter implements ParameterTypeConverter<LastName, String>, Converter<LastName, String> { @Override public String convert(LastName source) { - return source == null ? null : source.getName(); + return source.getName(); } } diff --git a/src/test/java/examples/spring/YesNoParameterConverter.java b/src/test/java/examples/spring/YesNoParameterConverter.java index 131c0d84a..f86cc7b0f 100644 --- a/src/test/java/examples/spring/YesNoParameterConverter.java +++ b/src/test/java/examples/spring/YesNoParameterConverter.java @@ -15,12 +15,14 @@ */ package examples.spring; +import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.ParameterTypeConverter; +@NullMarked public class YesNoParameterConverter implements ParameterTypeConverter<Boolean, String> { @Override public String convert(Boolean source) { - return source == null ? null : source ? "Yes" : "No"; + return source ? "Yes" : "No"; } } diff --git a/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KCustomRenderingTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KCustomRenderingTest.kt index d0c7e7a04..47a6fcaed 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KCustomRenderingTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/custom/render/KCustomRenderingTest.kt @@ -304,7 +304,7 @@ class KCustomRenderingTest { } } - private fun <T> dereference(column: SqlColumn<T>, attribute: String) = + private fun <T : Any> dereference(column: SqlColumn<T>, attribute: String) = SqlColumn.of<String>(column.name() + "->>'" + attribute + "'", column.table(), JDBCType.VARCHAR) companion object { From 3347f36d42bed9ca31dab3a8ba0e61463e435950 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 4 Jan 2025 12:47:07 +0000 Subject: [PATCH 161/260] Update dependency org.assertj:assertj-core to v3.27.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 28fba05ab..6bfbfd73f 100644 --- a/pom.xml +++ b/pom.xml @@ -134,7 +134,7 @@ <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> - <version>3.27.1</version> + <version>3.27.2</version> <scope>test</scope> </dependency> <dependency> From c47621057dc404e1bae4ff0136de7d95693ca757 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 5 Jan 2025 23:05:43 +0000 Subject: [PATCH 162/260] Update dependency ch.qos.logback:logback-classic to v1.5.16 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6bfbfd73f..f4a851cfe 100644 --- a/pom.xml +++ b/pom.xml @@ -170,7 +170,7 @@ <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> - <version>1.5.15</version> + <version>1.5.16</version> <scope>test</scope> </dependency> <dependency> From 2b49071e15c5528ff421288a35d9ae2e944d3ab7 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 14 Jan 2025 21:10:35 +0000 Subject: [PATCH 163/260] Update dependency org.postgresql:postgresql to v42.7.5 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f4a851cfe..9cceda948 100644 --- a/pom.xml +++ b/pom.xml @@ -188,7 +188,7 @@ <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> - <version>42.7.4</version> + <version>42.7.5</version> <scope>test</scope> </dependency> <dependency> From e31ca9bcfce75bf1c24312de502d03c474c21b03 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 15 Jan 2025 12:41:13 -0500 Subject: [PATCH 164/260] Add example of implementing the MySQL "member of" operator --- pom.xml | 16 ++- .../config/TestContainersConfiguration.java | 1 + .../examples/mysql/MemberOfCondition.java | 39 ++++++ .../java/examples/mysql/MemberOfFunction.java | 51 ++++++++ src/test/java/examples/mysql/MySQLTest.java | 122 ++++++++++++++++++ 5 files changed, 227 insertions(+), 2 deletions(-) create mode 100644 src/test/java/examples/mysql/MemberOfCondition.java create mode 100644 src/test/java/examples/mysql/MemberOfFunction.java create mode 100644 src/test/java/examples/mysql/MySQLTest.java diff --git a/pom.xml b/pom.xml index 6bfbfd73f..0e1fd5314 100644 --- a/pom.xml +++ b/pom.xml @@ -175,13 +175,13 @@ </dependency> <dependency> <groupId>org.testcontainers</groupId> - <artifactId>postgresql</artifactId> + <artifactId>junit-jupiter</artifactId> <version>${test.containers.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.testcontainers</groupId> - <artifactId>junit-jupiter</artifactId> + <artifactId>postgresql</artifactId> <version>${test.containers.version}</version> <scope>test</scope> </dependency> @@ -203,6 +203,18 @@ <version>3.5.1</version> <scope>test</scope> </dependency> + <dependency> + <groupId>org.testcontainers</groupId> + <artifactId>mysql</artifactId> + <version>${test.containers.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.mysql</groupId> + <artifactId>mysql-connector-j</artifactId> + <version>9.1.0</version> + <scope>test</scope> + </dependency> </dependencies> <build> diff --git a/src/test/java/config/TestContainersConfiguration.java b/src/test/java/config/TestContainersConfiguration.java index 7a4e39450..77fd866b0 100644 --- a/src/test/java/config/TestContainersConfiguration.java +++ b/src/test/java/config/TestContainersConfiguration.java @@ -23,4 +23,5 @@ public interface TestContainersConfiguration { DockerImageName POSTGRES_LATEST = DockerImageName.parse("postgres:17.2"); DockerImageName MARIADB_LATEST = DockerImageName.parse("mariadb:11.6.2"); + DockerImageName MYSQL_LATEST = DockerImageName.parse("mysql:9.1.0"); } diff --git a/src/test/java/examples/mysql/MemberOfCondition.java b/src/test/java/examples/mysql/MemberOfCondition.java new file mode 100644 index 000000000..33b967556 --- /dev/null +++ b/src/test/java/examples/mysql/MemberOfCondition.java @@ -0,0 +1,39 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.mysql; + +import java.util.Objects; + +import org.jspecify.annotations.NullMarked; +import org.mybatis.dynamic.sql.AbstractNoValueCondition; + +@NullMarked +public class MemberOfCondition<T> extends AbstractNoValueCondition<T> { + private final String jsonArray; + + protected MemberOfCondition(String jsonArray) { + this.jsonArray = Objects.requireNonNull(jsonArray); + } + + @Override + public String operator() { + return "member of(" + jsonArray + ")"; + } + + public static <T> MemberOfCondition<T> memberOf(String jsonArray) { + return new MemberOfCondition<>(jsonArray); + } +} diff --git a/src/test/java/examples/mysql/MemberOfFunction.java b/src/test/java/examples/mysql/MemberOfFunction.java new file mode 100644 index 000000000..1035bf3e0 --- /dev/null +++ b/src/test/java/examples/mysql/MemberOfFunction.java @@ -0,0 +1,51 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.mysql; + +import java.util.Objects; + +import org.jspecify.annotations.NullMarked; +import org.mybatis.dynamic.sql.BasicColumn; +import org.mybatis.dynamic.sql.BindableColumn; +import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.select.function.AbstractTypeConvertingFunction; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; + +@NullMarked +public class MemberOfFunction<T> extends AbstractTypeConvertingFunction<T, Long, MemberOfFunction<T>> { + + private final String jsonArray; + + protected MemberOfFunction(BasicColumn column, String jsonArray) { + super(column); + this.jsonArray = Objects.requireNonNull(jsonArray); + } + + @Override + protected MemberOfFunction<T> copy() { + return new MemberOfFunction<>(column, jsonArray); + } + + @Override + public FragmentAndParameters render(RenderingContext renderingContext) { + return column.render(renderingContext) + .mapFragment(f -> f + " member of(" + jsonArray + ")"); + } + + public static <T> MemberOfFunction<T> memberOf(BindableColumn<T> column, String jsonArray) { + return new MemberOfFunction<>(column, jsonArray); + } +} diff --git a/src/test/java/examples/mysql/MySQLTest.java b/src/test/java/examples/mysql/MySQLTest.java new file mode 100644 index 000000000..54c43c34a --- /dev/null +++ b/src/test/java/examples/mysql/MySQLTest.java @@ -0,0 +1,122 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.mysql; + +import static examples.mysql.MemberOfCondition.memberOf; +import static examples.mysql.MemberOfFunction.memberOf; +import static examples.mariadb.ItemsDynamicSQLSupport.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; +import static org.mybatis.dynamic.sql.SqlBuilder.*; + +import java.util.List; +import java.util.Map; + +import config.TestContainersConfiguration; +import org.apache.ibatis.datasource.unpooled.UnpooledDataSource; +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.BeforeAll; +import org.junit.jupiter.api.Test; +import org.mybatis.dynamic.sql.render.RenderingStrategies; +import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; +import org.mybatis.dynamic.sql.util.mybatis3.CommonSelectMapper; +import org.testcontainers.containers.MySQLContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +@Testcontainers +class MySQLTest { + + @SuppressWarnings("resource") + @Container + private static final MySQLContainer<?> mysql = + new MySQLContainer<>(TestContainersConfiguration.MYSQL_LATEST) + .withInitScript("examples/mariadb/CreateDB.sql"); + + private static SqlSessionFactory sqlSessionFactory; + + @BeforeAll + static void setup() { + UnpooledDataSource ds = new UnpooledDataSource(mysql.getDriverClassName(), mysql.getJdbcUrl(), + mysql.getUsername(), mysql.getPassword()); + Environment environment = new Environment("test", new JdbcTransactionFactory(), ds); + Configuration config = new Configuration(environment); + config.addMapper(CommonSelectMapper.class); + sqlSessionFactory = new SqlSessionFactoryBuilder().build(config); + } + + @Test + void smokeTest() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description) + .from(items) + .orderBy(id) + .build() + .render(RenderingStrategies.MYBATIS3); + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + assertThat(rows).hasSize(20); + } + } + + @Test + void testMemberOfAsCondition() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, memberOf(id, "'[1, 2, 3]'").as("inList")) + .from(items) + .where(id, memberOf("'[1, 2, 3]'")) + .orderBy(id) + .build() + .render(RenderingStrategies.MYBATIS3); + + assertThat(selectStatement.getSelectStatement()) + .isEqualTo("select id, id member of('[1, 2, 3]') as inList from items where id member of('[1, 2, 3]') order by id"); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + assertThat(rows).hasSize(3); + assertThat(rows.get(2)).containsOnly(entry("id", 3), entry("inList", 1L)); + } + } + + @Test + void testMemberOfAsFunction() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, memberOf(id, "'[1, 2, 3]'").as("inList")) + .from(items) + .where(memberOf(id,"'[1, 2, 3]'"), isEqualTo(1L)) + .orderBy(id) + .build() + .render(RenderingStrategies.MYBATIS3); + + assertThat(selectStatement.getSelectStatement()) + .isEqualTo("select id, id member of('[1, 2, 3]') as inList from items where id member of('[1, 2, 3]') = #{parameters.p1} order by id"); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + assertThat(rows).hasSize(3); + assertThat(rows.get(2)).containsOnly(entry("id", 3), entry("inList", 1L)); + } + } +} From 905393608d7751cb2c811dd27c034e364b08f06f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 16 Jan 2025 13:00:24 +0000 Subject: [PATCH 165/260] Update dependency org.springframework:spring-jdbc to v6.2.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8d4ea5a51..2cb717486 100644 --- a/pom.xml +++ b/pom.xml @@ -101,7 +101,7 @@ <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> - <version>6.2.1</version> + <version>6.2.2</version> <scope>provided</scope> <optional>true</optional> </dependency> From 5b460778317d46a82cc52757b12a625b136386c4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 19 Jan 2025 09:05:17 +0000 Subject: [PATCH 166/260] Update dependency org.assertj:assertj-core to v3.27.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2cb717486..bc6ddf12f 100644 --- a/pom.xml +++ b/pom.xml @@ -134,7 +134,7 @@ <dependency> <groupId>org.assertj</groupId> <artifactId>assertj-core</artifactId> - <version>3.27.2</version> + <version>3.27.3</version> <scope>test</scope> </dependency> <dependency> From c1470caa8fe176ce6c9f9b79a6b7097b30aad522 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 21 Jan 2025 17:07:50 +0000 Subject: [PATCH 167/260] Update dependency com.mysql:mysql-connector-j to v9.2.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bc6ddf12f..ede046b79 100644 --- a/pom.xml +++ b/pom.xml @@ -212,7 +212,7 @@ <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> - <version>9.1.0</version> + <version>9.2.0</version> <scope>test</scope> </dependency> </dependencies> From f948c86f55e7f80f08cf213f98373dc3826b1179 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 22 Jan 2025 10:28:48 -0500 Subject: [PATCH 168/260] Use a built-in utility rather than our custom one --- src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java | 3 +-- src/main/java/org/mybatis/dynamic/sql/select/CountDSL.java | 3 +-- .../org/mybatis/dynamic/sql/select/QueryExpressionDSL.java | 5 ++--- src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java | 3 +-- src/main/java/org/mybatis/dynamic/sql/util/Utilities.java | 5 ----- 5 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java index 8dda9b10c..3724e5395 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java @@ -27,7 +27,6 @@ import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; import org.mybatis.dynamic.sql.util.Buildable; -import org.mybatis.dynamic.sql.util.Utilities; import org.mybatis.dynamic.sql.where.AbstractWhereFinisher; import org.mybatis.dynamic.sql.where.AbstractWhereStarter; import org.mybatis.dynamic.sql.where.EmbeddedWhereModel; @@ -51,7 +50,7 @@ private DeleteDSL(SqlTable table, @Nullable String tableAlias, Function<DeleteMo @Override public DeleteWhereBuilder where() { - whereBuilder = Utilities.buildIfNecessary(whereBuilder, DeleteWhereBuilder::new); + whereBuilder = Objects.requireNonNullElseGet(whereBuilder, DeleteWhereBuilder::new); return whereBuilder; } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/CountDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/CountDSL.java index a867c8bf8..48e790a03 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/CountDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/CountDSL.java @@ -25,7 +25,6 @@ import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; import org.mybatis.dynamic.sql.util.Buildable; -import org.mybatis.dynamic.sql.util.Utilities; import org.mybatis.dynamic.sql.where.AbstractWhereFinisher; import org.mybatis.dynamic.sql.where.EmbeddedWhereModel; @@ -54,7 +53,7 @@ private CountDSL(BasicColumn countColumn, SqlTable table, Function<SelectModel, @Override public CountWhereBuilder where() { - whereBuilder = Utilities.buildIfNecessary(whereBuilder, CountWhereBuilder::new); + whereBuilder = Objects.requireNonNullElseGet(whereBuilder, CountWhereBuilder::new); return whereBuilder; } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java index 0964ee3b3..4914f32b0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java @@ -37,7 +37,6 @@ import org.mybatis.dynamic.sql.select.join.JoinSpecification; import org.mybatis.dynamic.sql.select.join.JoinType; import org.mybatis.dynamic.sql.util.Buildable; -import org.mybatis.dynamic.sql.util.Utilities; import org.mybatis.dynamic.sql.where.AbstractWhereFinisher; import org.mybatis.dynamic.sql.where.AbstractWhereStarter; import org.mybatis.dynamic.sql.where.EmbeddedWhereModel; @@ -70,7 +69,7 @@ protected QueryExpressionDSL(FromGatherer<R> fromGatherer, SqlTable table, Strin @Override public QueryExpressionWhereBuilder where() { - whereBuilder = Utilities.buildIfNecessary(whereBuilder, QueryExpressionWhereBuilder::new); + whereBuilder = Objects.requireNonNullElseGet(whereBuilder, QueryExpressionWhereBuilder::new); return whereBuilder; } @@ -86,7 +85,7 @@ public QueryExpressionDSL<R> configureStatement(Consumer<StatementConfiguration> * @return The having builder */ protected QueryExpressionHavingBuilder having() { - havingBuilder = Utilities.buildIfNecessary(havingBuilder, QueryExpressionHavingBuilder::new); + havingBuilder = Objects.requireNonNullElseGet(havingBuilder, QueryExpressionHavingBuilder::new); return havingBuilder; } diff --git a/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java index c6fcd50d7..f33bbc074 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java @@ -39,7 +39,6 @@ import org.mybatis.dynamic.sql.util.NullMapping; import org.mybatis.dynamic.sql.util.SelectMapping; import org.mybatis.dynamic.sql.util.StringConstantMapping; -import org.mybatis.dynamic.sql.util.Utilities; import org.mybatis.dynamic.sql.util.ValueMapping; import org.mybatis.dynamic.sql.util.ValueOrNullMapping; import org.mybatis.dynamic.sql.util.ValueWhenPresentMapping; @@ -71,7 +70,7 @@ public <T> SetClauseFinisher<T> set(SqlColumn<T> column) { @Override public UpdateWhereBuilder where() { - whereBuilder = Utilities.buildIfNecessary(whereBuilder, UpdateWhereBuilder::new); + whereBuilder = Objects.requireNonNullElseGet(whereBuilder, UpdateWhereBuilder::new); return whereBuilder; } diff --git a/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java b/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java index e0aa47bc0..87ea18e12 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java @@ -17,17 +17,12 @@ import java.util.Collection; import java.util.Objects; -import java.util.function.Supplier; import java.util.stream.Stream; import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; public interface Utilities { - static <T> T buildIfNecessary(@Nullable T current, @NonNull Supplier<T> builder) { - return current == null ? builder.get() : current; - } - static long safelyUnbox(@Nullable Long l) { return l == null ? 0 : l; } From e8806852c76fee60738c9f6e21a4099136bed942 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 23 Jan 2025 11:17:37 -0500 Subject: [PATCH 169/260] Use existing utility method --- .../where/render/DefaultConditionVisitor.java | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java index 6a3fb038d..78bbc81e7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java @@ -47,19 +47,10 @@ private DefaultConditionVisitor(Builder<T> builder) { @Override public FragmentAndParameters visit(AbstractListValueCondition<T> condition) { - FragmentCollector fc = condition.values() - .map(this::toFragmentAndParameters) - .collect(FragmentCollector.collect()); - - String joinedFragments = - fc.collectFragments(Collectors.joining(",", "(", ")")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - String finalFragment = condition.operator() - + spaceBefore(joinedFragments); - - return FragmentAndParameters - .withFragment(finalFragment) - .withParameters(fc.parameters()) - .build(); + return condition.values().map(this::toFragmentAndParameters) + .collect(FragmentCollector.collect()) + .toFragmentAndParameters(Collectors.joining(",", //$NON-NLS-1$ + condition.operator() + " (", ")")); //$NON-NLS-1$ //$NON-NLS-2$ } @Override From e59d1a1bb29527b5a40d823b7abf93f2857d6dfd Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 23 Jan 2025 14:22:23 -0500 Subject: [PATCH 170/260] Initial implementation of for and wait This add forUpdate(), forShare(), etc. to the select DSL --- .../mybatis/dynamic/sql/select/SelectDSL.java | 41 +++ .../dynamic/sql/select/SelectModel.java | 26 ++ .../sql/select/render/SubQueryRenderer.java | 26 +- .../mybatis/dynamic/sql/util/Validator.java | 7 + .../dynamic/sql/util/messages.properties | 3 + .../java/examples/postgres/PostgresTest.java | 298 ++++++++++++++++++ .../postgres/TableCodeDynamicSqlSupport.java | 36 +++ .../resources/examples/postgres/dbInit.sql | 26 ++ 8 files changed, 452 insertions(+), 11 deletions(-) create mode 100644 src/test/java/examples/postgres/PostgresTest.java create mode 100644 src/test/java/examples/postgres/TableCodeDynamicSqlSupport.java create mode 100644 src/test/resources/examples/postgres/dbInit.sql diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java index 7f1fd239b..3626e7bbd 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java @@ -32,6 +32,7 @@ import org.mybatis.dynamic.sql.select.QueryExpressionDSL.FromGatherer; import org.mybatis.dynamic.sql.util.Buildable; import org.mybatis.dynamic.sql.util.ConfigurableStatement; +import org.mybatis.dynamic.sql.util.Validator; /** * Implements a SQL DSL for building select statements. @@ -50,6 +51,8 @@ public class SelectDSL<R> implements Buildable<R>, ConfigurableStatement<SelectD private @Nullable Long offset; private @Nullable Long fetchFirstRows; final StatementConfiguration statementConfiguration = new StatementConfiguration(); + private @Nullable String forClause; + private @Nullable String waitClause; private SelectDSL(Function<SelectModel, R> adapterFunction) { this.adapterFunction = Objects.requireNonNull(adapterFunction); @@ -122,6 +125,42 @@ public FetchFirstFinisher<R> fetchFirstWhenPresent(@Nullable Long fetchFirstRows return () -> this; } + public SelectDSL<R> forUpdate() { + Validator.assertNull(forClause, "ERROR.48"); //$NON-NLS-1$ + forClause = "for update"; //$NON-NLS-1$ + return this; + } + + public SelectDSL<R> forNoKeyUpdate() { + Validator.assertNull(forClause, "ERROR.48"); //$NON-NLS-1$ + forClause = "for no key update"; //$NON-NLS-1$ + return this; + } + + public SelectDSL<R> forShare() { + Validator.assertNull(forClause, "ERROR.48"); //$NON-NLS-1$ + forClause = "for share"; //$NON-NLS-1$ + return this; + } + + public SelectDSL<R> forKeyShare() { + Validator.assertNull(forClause, "ERROR.48"); //$NON-NLS-1$ + forClause = "for key share"; //$NON-NLS-1$ + return this; + } + + public SelectDSL<R> skipLocked() { + Validator.assertNull(waitClause, "ERROR.49"); //$NON-NLS-1$ + waitClause = "skip locked"; //$NON-NLS-1$ + return this; + } + + public SelectDSL<R> nowait() { + Validator.assertNull(waitClause, "ERROR.49"); //$NON-NLS-1$ + waitClause = "nowait"; //$NON-NLS-1$ + return this; + } + @Override public SelectDSL<R> configureStatement(Consumer<StatementConfiguration> consumer) { consumer.accept(statementConfiguration); @@ -134,6 +173,8 @@ public R build() { .withOrderByModel(orderByModel) .withPagingModel(buildPagingModel().orElse(null)) .withStatementConfiguration(statementConfiguration) + .withForClause(forClause) + .withWaitClause(waitClause) .build(); return adapterFunction.apply(selectModel); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java index fd4eecc0c..8367606d9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java @@ -18,8 +18,10 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.stream.Stream; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.render.RenderingStrategy; import org.mybatis.dynamic.sql.select.render.SelectRenderer; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; @@ -27,17 +29,29 @@ public class SelectModel extends AbstractSelectModel { private final List<QueryExpressionModel> queryExpressions; + private @Nullable final String forClause; + private @Nullable final String waitClause; private SelectModel(Builder builder) { super(builder); queryExpressions = Objects.requireNonNull(builder.queryExpressions); Validator.assertNotEmpty(queryExpressions, "ERROR.14"); //$NON-NLS-1$ + forClause = builder.forClause; + waitClause = builder.waitClause; } public Stream<QueryExpressionModel> queryExpressions() { return queryExpressions.stream(); } + public Optional<String> forClause() { + return Optional.ofNullable(forClause); + } + + public Optional<String> waitClause() { + return Optional.ofNullable(waitClause); + } + public SelectStatementProvider render(RenderingStrategy renderingStrategy) { return SelectRenderer.withSelectModel(this) .withRenderingStrategy(renderingStrategy) @@ -51,6 +65,8 @@ public static Builder withQueryExpressions(List<QueryExpressionModel> queryExpre public static class Builder extends AbstractBuilder<Builder> { private final List<QueryExpressionModel> queryExpressions = new ArrayList<>(); + private @Nullable String forClause; + private @Nullable String waitClause; public Builder withQueryExpression(QueryExpressionModel queryExpression) { this.queryExpressions.add(queryExpression); @@ -62,6 +78,16 @@ public Builder withQueryExpressions(List<QueryExpressionModel> queryExpressions) return this; } + public Builder withForClause(@Nullable String forClause) { + this.forClause = forClause; + return this; + } + + public Builder withWaitClause(@Nullable String waitClause) { + this.waitClause = waitClause; + return this; + } + @Override protected Builder getThis() { return this; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java index 6c4eb82ad..359e9c1f0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SubQueryRenderer.java @@ -16,7 +16,6 @@ package org.mybatis.dynamic.sql.select.render; import java.util.Objects; -import java.util.Optional; import java.util.stream.Collectors; import org.jspecify.annotations.Nullable; @@ -48,8 +47,21 @@ public FragmentAndParameters render() { .map(this::renderQueryExpression) .collect(FragmentCollector.collect()); - renderOrderBy().ifPresent(fragmentCollector::add); - renderPagingModel().ifPresent(fragmentCollector::add); + selectModel.orderByModel() + .map(this::renderOrderBy) + .ifPresent(fragmentCollector::add); + + selectModel.pagingModel() + .map(this::renderPagingModel) + .ifPresent(fragmentCollector::add); + + selectModel.forClause() + .map(FragmentAndParameters::fromFragment) + .ifPresent(fragmentCollector::add); + + selectModel.waitClause() + .map(FragmentAndParameters::fromFragment) + .ifPresent(fragmentCollector::add); return fragmentCollector.toFragmentAndParameters(Collectors.joining(" ", prefix, suffix)); //$NON-NLS-1$ } @@ -61,18 +73,10 @@ private FragmentAndParameters renderQueryExpression(QueryExpressionModel queryEx .render(); } - private Optional<FragmentAndParameters> renderOrderBy() { - return selectModel.orderByModel().map(this::renderOrderBy); - } - private FragmentAndParameters renderOrderBy(OrderByModel orderByModel) { return new OrderByRenderer(renderingContext).render(orderByModel); } - private Optional<FragmentAndParameters> renderPagingModel() { - return selectModel.pagingModel().map(this::renderPagingModel); - } - private FragmentAndParameters renderPagingModel(PagingModel pagingModel) { return new PagingModelRenderer.Builder() .withPagingModel(pagingModel) diff --git a/src/main/java/org/mybatis/dynamic/sql/util/Validator.java b/src/main/java/org/mybatis/dynamic/sql/util/Validator.java index 588f6e372..7563bfc70 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/Validator.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/Validator.java @@ -17,6 +17,7 @@ import java.util.Collection; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.exception.InvalidSqlException; public class Validator { @@ -49,4 +50,10 @@ public static void assertTrue(boolean condition, String messageNumber) { public static void assertTrue(boolean condition, String messageNumber, String p1) { assertFalse(!condition, messageNumber, p1); } + + public static void assertNull(@Nullable Object object, String messageNumber) { + if (object != null) { + throw new InvalidSqlException(Messages.getString(messageNumber)); + } + } } diff --git a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties index d99bd581e..3cf560a78 100644 --- a/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties +++ b/src/main/resources/org/mybatis/dynamic/sql/util/messages.properties @@ -64,4 +64,7 @@ ERROR.44={0} conditions must contain at least one value ERROR.45=You cannot call "on" in a Kotlin join expression more than once ERROR.46=At least one join criterion must render ERROR.47=A Kotlin case statement must specify a "then" clause for every "when" clause +ERROR.48=You cannot call more than one of "forUpdate", "forNoKeyUpdate", "forShare", or "forKeyShare" in a select \ + statement +ERROR.49=You cannot call more than one of "skipLocked", or "nowait" in a select statement INTERNAL.ERROR=Internal Error {0} diff --git a/src/test/java/examples/postgres/PostgresTest.java b/src/test/java/examples/postgres/PostgresTest.java new file mode 100644 index 000000000..f8da9c328 --- /dev/null +++ b/src/test/java/examples/postgres/PostgresTest.java @@ -0,0 +1,298 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.postgres; + +import static examples.postgres.TableCodeDynamicSqlSupport.*; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mybatis.dynamic.sql.SqlBuilder.*; + +import java.util.List; +import java.util.Map; + +import config.TestContainersConfiguration; +import org.apache.ibatis.datasource.unpooled.UnpooledDataSource; +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.BeforeAll; +import org.junit.jupiter.api.Test; +import org.mybatis.dynamic.sql.render.RenderingStrategies; +import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; +import org.mybatis.dynamic.sql.util.mybatis3.CommonSelectMapper; +import org.testcontainers.containers.PostgreSQLContainer; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +@Testcontainers +class PostgresTest { + + @SuppressWarnings("resource") + @Container + private static final PostgreSQLContainer<?> postgres = + new PostgreSQLContainer<>(TestContainersConfiguration.POSTGRES_LATEST) + .withInitScript("examples/postgres/dbInit.sql"); + + private static SqlSessionFactory sqlSessionFactory; + + @BeforeAll + static void setUp() { + UnpooledDataSource ds = new UnpooledDataSource(postgres.getDriverClassName(), postgres.getJdbcUrl(), + postgres.getUsername(), postgres.getPassword()); + Environment environment = new Environment("test", new JdbcTransactionFactory(), ds); + Configuration configuration = new Configuration(environment); + configuration.addMapper(CommonSelectMapper.class); + sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration); + } + + @Test + void testSelectForUpdate() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description) + .from(tableCode) + .orderBy(id) + .forUpdate() + .build() + .render(RenderingStrategies.MYBATIS3); + + assertThat(selectStatement.getSelectStatement()) + .isEqualTo("select id, description from TableCode order by id for update"); + List<Map<String, Object>> records = mapper.selectManyMappedRows(selectStatement); + assertThat(records).hasSize(4); + } + } + + @Test + void testSelectForUpdateNoWait() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description) + .from(tableCode) + .orderBy(id) + .forUpdate() + .nowait() + .build() + .render(RenderingStrategies.MYBATIS3); + + assertThat(selectStatement.getSelectStatement()) + .isEqualTo("select id, description from TableCode order by id for update nowait"); + List<Map<String, Object>> records = mapper.selectManyMappedRows(selectStatement); + assertThat(records).hasSize(4); + } + } + + @Test + void testSelectForUpdateSkipLocked() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description) + .from(tableCode) + .orderBy(id) + .forUpdate() + .skipLocked() + .build() + .render(RenderingStrategies.MYBATIS3); + + assertThat(selectStatement.getSelectStatement()) + .isEqualTo("select id, description from TableCode order by id for update skip locked"); + List<Map<String, Object>> records = mapper.selectManyMappedRows(selectStatement); + assertThat(records).hasSize(4); + } + } + + @Test + void testSelectForNoKeyUpdate() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description) + .from(tableCode) + .orderBy(id) + .forNoKeyUpdate() + .build() + .render(RenderingStrategies.MYBATIS3); + + assertThat(selectStatement.getSelectStatement()) + .isEqualTo("select id, description from TableCode order by id for no key update"); + List<Map<String, Object>> records = mapper.selectManyMappedRows(selectStatement); + assertThat(records).hasSize(4); + } + } + + @Test + void testSelectForNoKeyUpdateNoWait() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description) + .from(tableCode) + .orderBy(id) + .forNoKeyUpdate() + .nowait() + .build() + .render(RenderingStrategies.MYBATIS3); + + assertThat(selectStatement.getSelectStatement()) + .isEqualTo("select id, description from TableCode order by id for no key update nowait"); + List<Map<String, Object>> records = mapper.selectManyMappedRows(selectStatement); + assertThat(records).hasSize(4); + } + } + + @Test + void testSelectForNoKeyUpdateSkipLocked() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description) + .from(tableCode) + .orderBy(id) + .forNoKeyUpdate() + .skipLocked() + .build() + .render(RenderingStrategies.MYBATIS3); + + assertThat(selectStatement.getSelectStatement()) + .isEqualTo("select id, description from TableCode order by id for no key update skip locked"); + List<Map<String, Object>> records = mapper.selectManyMappedRows(selectStatement); + assertThat(records).hasSize(4); + } + } + + @Test + void testSelectForShare() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description) + .from(tableCode) + .orderBy(id) + .forShare() + .build() + .render(RenderingStrategies.MYBATIS3); + + assertThat(selectStatement.getSelectStatement()) + .isEqualTo("select id, description from TableCode order by id for share"); + List<Map<String, Object>> records = mapper.selectManyMappedRows(selectStatement); + assertThat(records).hasSize(4); + } + } + + @Test + void testSelectForShareNoWait() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description) + .from(tableCode) + .orderBy(id) + .forShare() + .nowait() + .build() + .render(RenderingStrategies.MYBATIS3); + + assertThat(selectStatement.getSelectStatement()) + .isEqualTo("select id, description from TableCode order by id for share nowait"); + List<Map<String, Object>> records = mapper.selectManyMappedRows(selectStatement); + assertThat(records).hasSize(4); + } + } + + @Test + void testSelectForShareSkipLocked() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description) + .from(tableCode) + .orderBy(id) + .forShare() + .skipLocked() + .build() + .render(RenderingStrategies.MYBATIS3); + + assertThat(selectStatement.getSelectStatement()) + .isEqualTo("select id, description from TableCode order by id for share skip locked"); + List<Map<String, Object>> records = mapper.selectManyMappedRows(selectStatement); + assertThat(records).hasSize(4); + } + } + + @Test + void testSelectForKeyShare() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description) + .from(tableCode) + .orderBy(id) + .forKeyShare() + .build() + .render(RenderingStrategies.MYBATIS3); + + assertThat(selectStatement.getSelectStatement()) + .isEqualTo("select id, description from TableCode order by id for key share"); + List<Map<String, Object>> records = mapper.selectManyMappedRows(selectStatement); + assertThat(records).hasSize(4); + } + } + + @Test + void testSelectForKeyShareNoWait() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description) + .from(tableCode) + .orderBy(id) + .forKeyShare() + .nowait() + .build() + .render(RenderingStrategies.MYBATIS3); + + assertThat(selectStatement.getSelectStatement()) + .isEqualTo("select id, description from TableCode order by id for key share nowait"); + List<Map<String, Object>> records = mapper.selectManyMappedRows(selectStatement); + assertThat(records).hasSize(4); + } + } + + @Test + void testSelectForKeyShareSkipLocked() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description) + .from(tableCode) + .orderBy(id) + .forKeyShare() + .skipLocked() + .build() + .render(RenderingStrategies.MYBATIS3); + + assertThat(selectStatement.getSelectStatement()) + .isEqualTo("select id, description from TableCode order by id for key share skip locked"); + List<Map<String, Object>> records = mapper.selectManyMappedRows(selectStatement); + assertThat(records).hasSize(4); + } + } +} diff --git a/src/test/java/examples/postgres/TableCodeDynamicSqlSupport.java b/src/test/java/examples/postgres/TableCodeDynamicSqlSupport.java new file mode 100644 index 000000000..c2fd0deef --- /dev/null +++ b/src/test/java/examples/postgres/TableCodeDynamicSqlSupport.java @@ -0,0 +1,36 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.postgres; + +import java.sql.JDBCType; + +import org.mybatis.dynamic.sql.SqlColumn; +import org.mybatis.dynamic.sql.SqlTable; + +public final class TableCodeDynamicSqlSupport { + public static final TableCode tableCode = new TableCode(); + public static final SqlColumn<Integer> id = tableCode.id; + public static final SqlColumn<String> description = tableCode.description; + + public static class TableCode extends SqlTable { + public final SqlColumn<Integer> id = column("id", JDBCType.INTEGER); + public final SqlColumn<String> description = column("description", JDBCType.VARCHAR); + + public TableCode() { + super("TableCode"); + } + } +} diff --git a/src/test/resources/examples/postgres/dbInit.sql b/src/test/resources/examples/postgres/dbInit.sql new file mode 100644 index 000000000..03ba34cac --- /dev/null +++ b/src/test/resources/examples/postgres/dbInit.sql @@ -0,0 +1,26 @@ +-- +-- Copyright 2016-2025 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 +-- +-- https://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. +-- + +create table TableCode ( + id int not null, + description varchar(30) not null, + primary key (id) +); + +insert into TableCode (id, description) values(1, 'One'); +insert into TableCode (id, description) values(2, 'Two'); +insert into TableCode (id, description) values(3, 'Three'); +insert into TableCode (id, description) values(4, 'Four'); From aefb1151179ac9f0694aecdfc108067bbaad1791 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 24 Jan 2025 10:36:24 -0500 Subject: [PATCH 171/260] Consolidate the Se;ectDSL functions into a reusable interface --- .../sql/select/QueryExpressionDSL.java | 104 +++++------------- .../sql/select/SelectDSLOperations.java | 79 +++++++++++++ 2 files changed, 106 insertions(+), 77 deletions(-) create mode 100644 src/main/java/org/mybatis/dynamic/sql/select/SelectDSLOperations.java diff --git a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java index 0964ee3b3..fcb8bdf67 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java @@ -44,7 +44,7 @@ public class QueryExpressionDSL<R> extends AbstractQueryExpressionDSL<QueryExpressionDSL<R>.QueryExpressionWhereBuilder, QueryExpressionDSL<R>> - implements Buildable<R>, PagingDSL<R> { + implements Buildable<R>, SelectDSLOperations<R> { private final @Nullable String connector; private final SelectDSL<R> selectDSL; @@ -196,23 +196,13 @@ protected QueryExpressionModel buildModel() { } @Override - public PagingDSL.LimitFinisher<R> limitWhenPresent(@Nullable Long limit) { - return selectDSL.limitWhenPresent(limit); - } - - @Override - public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(@Nullable Long offset) { - return selectDSL.offsetWhenPresent(offset); - } - - @Override - public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { - return selectDSL.fetchFirstWhenPresent(fetchFirstRows); + protected QueryExpressionDSL<R> getThis() { + return this; } @Override - protected QueryExpressionDSL<R> getThis() { - return this; + public SelectDSL<R> getSelectDSL() { + return selectDSL; } public static class FromGatherer<R> { @@ -277,7 +267,7 @@ public FromGatherer<R> build() { } public class QueryExpressionWhereBuilder extends AbstractWhereFinisher<QueryExpressionWhereBuilder> - implements Buildable<R>, PagingDSL<R> { + implements Buildable<R>, SelectDSLOperations<R> { private QueryExpressionWhereBuilder() { super(QueryExpressionDSL.this); } @@ -306,21 +296,6 @@ public GroupByFinisher groupBy(Collection<? extends BasicColumn> columns) { return QueryExpressionDSL.this.groupBy(columns); } - @Override - public PagingDSL.LimitFinisher<R> limitWhenPresent(@Nullable Long limit) { - return QueryExpressionDSL.this.limitWhenPresent(limit); - } - - @Override - public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(@Nullable Long offset) { - return QueryExpressionDSL.this.offsetWhenPresent(offset); - } - - @Override - public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { - return QueryExpressionDSL.this.fetchFirstWhenPresent(fetchFirstRows); - } - @Override public R build() { return QueryExpressionDSL.this.build(); @@ -331,6 +306,11 @@ protected QueryExpressionWhereBuilder getThis() { return this; } + @Override + public SelectDSL<R> getSelectDSL() { + return QueryExpressionDSL.this.getSelectDSL(); + } + protected EmbeddedWhereModel buildWhereModel() { return super.buildModel(); } @@ -358,7 +338,7 @@ public <T> JoinSpecificationFinisher on(BindableColumn<T> joinColumn, VisitableC public class JoinSpecificationFinisher extends AbstractBooleanExpressionDSL<JoinSpecificationFinisher> implements AbstractWhereStarter<QueryExpressionWhereBuilder, JoinSpecificationFinisher>, Buildable<R>, - PagingDSL<R> { + SelectDSLOperations<R> { private final TableExpression table; private final JoinType joinType; @@ -487,28 +467,18 @@ public SelectDSL<R> orderBy(Collection<? extends SortSpecification> columns) { } @Override - public PagingDSL.LimitFinisher<R> limitWhenPresent(@Nullable Long limit) { - return QueryExpressionDSL.this.limitWhenPresent(limit); - } - - @Override - public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(@Nullable Long offset) { - return QueryExpressionDSL.this.offsetWhenPresent(offset); - } - - @Override - public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { - return QueryExpressionDSL.this.fetchFirstWhenPresent(fetchFirstRows); + protected JoinSpecificationFinisher getThis() { + return this; } @Override - protected JoinSpecificationFinisher getThis() { - return this; + public SelectDSL<R> getSelectDSL() { + return QueryExpressionDSL.this.getSelectDSL(); } } public class GroupByFinisher extends AbstractHavingStarter<QueryExpressionHavingBuilder> - implements Buildable<R>, PagingDSL<R> { + implements Buildable<R>, SelectDSLOperations<R> { public SelectDSL<R> orderBy(SortSpecification... columns) { return orderBy(Arrays.asList(columns)); } @@ -531,23 +501,13 @@ public UnionBuilder unionAll() { } @Override - public PagingDSL.LimitFinisher<R> limitWhenPresent(@Nullable Long limit) { - return QueryExpressionDSL.this.limitWhenPresent(limit); - } - - @Override - public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(@Nullable Long offset) { - return QueryExpressionDSL.this.offsetWhenPresent(offset); + public QueryExpressionHavingBuilder having() { + return QueryExpressionDSL.this.having(); } @Override - public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { - return QueryExpressionDSL.this.fetchFirstWhenPresent(fetchFirstRows); - } - - @Override - public QueryExpressionHavingBuilder having() { - return QueryExpressionDSL.this.having(); + public SelectDSL<R> getSelectDSL() { + return QueryExpressionDSL.this.getSelectDSL(); } } @@ -585,22 +545,7 @@ public FromGatherer<R> selectDistinct(List<BasicColumn> selectList) { } public class QueryExpressionHavingBuilder extends AbstractHavingFinisher<QueryExpressionHavingBuilder> - implements Buildable<R>, PagingDSL<R> { - - @Override - public PagingDSL.LimitFinisher<R> limitWhenPresent(@Nullable Long limit) { - return QueryExpressionDSL.this.limitWhenPresent(limit); - } - - @Override - public PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(@Nullable Long offset) { - return QueryExpressionDSL.this.offsetWhenPresent(offset); - } - - @Override - public PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { - return QueryExpressionDSL.this.fetchFirstWhenPresent(fetchFirstRows); - } + implements Buildable<R>, SelectDSLOperations<R> { public SelectDSL<R> orderBy(SortSpecification... columns) { return orderBy(Arrays.asList(columns)); @@ -631,5 +576,10 @@ protected QueryExpressionHavingBuilder getThis() { protected HavingModel buildHavingModel() { return super.buildModel(); } + + @Override + public SelectDSL<R> getSelectDSL() { + return QueryExpressionDSL.this.getSelectDSL(); + } } } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSLOperations.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSLOperations.java new file mode 100644 index 000000000..7f7c8b129 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSLOperations.java @@ -0,0 +1,79 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.select; + +import org.jspecify.annotations.Nullable; + +public interface SelectDSLOperations<R> { + default PagingDSL.LimitFinisher<R> limit(long limit) { + return getSelectDSL().limit(limit); + } + + default PagingDSL.LimitFinisher<R> limitWhenPresent(@Nullable Long limit) { + return getSelectDSL().limitWhenPresent(limit); + } + + default PagingDSL.OffsetFirstFinisher<R> offset(long offset) { + return getSelectDSL().offset(offset); + } + + default PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(@Nullable Long offset) { + return getSelectDSL().offsetWhenPresent(offset); + } + + default PagingDSL.FetchFirstFinisher<R> fetchFirst(long fetchFirstRows) { + return getSelectDSL().fetchFirst(fetchFirstRows); + } + + default PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { + return getSelectDSL().fetchFirstWhenPresent(fetchFirstRows); + } + + default SelectDSL<R> forUpdate() { + return getSelectDSL().forUpdate(); + } + + default SelectDSL<R> forNoKeyUpdate() { + return getSelectDSL().forNoKeyUpdate(); + } + + default SelectDSL<R> forShare() { + return getSelectDSL().forShare(); + } + + default SelectDSL<R> forKeyShare() { + return getSelectDSL().forKeyShare(); + } + + default SelectDSL<R> skipLocked() { + return getSelectDSL().skipLocked(); + } + + default SelectDSL<R> nowait() { + return getSelectDSL().nowait(); + } + + /** + * Gain access to the SelectDSL instance. + * + * <p>This is a leak of an implementation detail into the public API. The tradeoff is that it + * significantly reduces copy/paste code of SelectDSL methods into all the different inner classes of + * QueryExpressionDSL where they would be needed. + * + * @return the SelectDSL instance associated with this interface instance + */ + SelectDSL<R> getSelectDSL(); +} From 066c1c57ce4e061a5948a0aab3b54a6ea4644f2f Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 24 Jan 2025 14:52:08 -0500 Subject: [PATCH 172/260] Remove PagingDSL - no longer needed --- .../dynamic/sql/select/MultiSelectDSL.java | 63 +++++++++++------ .../mybatis/dynamic/sql/select/PagingDSL.java | 59 ---------------- .../mybatis/dynamic/sql/select/SelectDSL.java | 69 ++++++++++++++----- .../select/SelectDSLForAndWaitOperations.java | 53 ++++++++++++++ .../sql/select/SelectDSLOperations.java | 49 ++----------- .../mybatis/dynamic/sql/InvalidSQLTest.java | 59 ++++++++++++++-- 6 files changed, 209 insertions(+), 143 deletions(-) delete mode 100644 src/main/java/org/mybatis/dynamic/sql/select/PagingDSL.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/select/SelectDSLForAndWaitOperations.java diff --git a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java index 308107c30..63ceb4e0a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java @@ -29,8 +29,7 @@ import org.mybatis.dynamic.sql.util.Buildable; import org.mybatis.dynamic.sql.util.ConfigurableStatement; -public class MultiSelectDSL implements Buildable<MultiSelectModel>, ConfigurableStatement<MultiSelectDSL>, - PagingDSL<MultiSelectModel> { +public class MultiSelectDSL implements Buildable<MultiSelectModel>, ConfigurableStatement<MultiSelectDSL> { private final List<UnionQuery> unionQueries = new ArrayList<>(); private final SelectModel initialSelect; private @Nullable OrderByModel orderByModel; @@ -62,22 +61,31 @@ public MultiSelectDSL orderBy(Collection<? extends SortSpecification> columns) { return this; } - @Override - public LimitFinisher<MultiSelectModel> limitWhenPresent(@Nullable Long limit) { + public LimitFinisher limit(long limit) { + return limitWhenPresent(limit); + } + + public LimitFinisher limitWhenPresent(@Nullable Long limit) { this.limit = limit; - return new LocalLimitFinisher(); + return new LimitFinisher(); } - @Override - public OffsetFirstFinisher<MultiSelectModel> offsetWhenPresent(@Nullable Long offset) { + public OffsetFirstFinisher offset(long offset) { + return offsetWhenPresent(offset); + } + + public OffsetFirstFinisher offsetWhenPresent(@Nullable Long offset) { this.offset = offset; - return new LocalOffsetFirstFinisher(); + return new OffsetFirstFinisher(); } - @Override - public FetchFirstFinisher<MultiSelectModel> fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { + public FetchFirstFinisher fetchFirst(long fetchFirstRows) { + return fetchFirstWhenPresent(fetchFirstRows); + } + + public FetchFirstFinisher fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { this.fetchFirstRows = fetchFirstRows; - return () -> this; + return new FetchFirstFinisher(); } @Override @@ -105,25 +113,40 @@ public MultiSelectDSL configureStatement(Consumer<StatementConfiguration> consum return this; } - abstract class BaseBuildable implements Buildable<MultiSelectModel> { + public class OffsetFirstFinisher implements Buildable<MultiSelectModel> { + public FetchFirstFinisher fetchFirst(long fetchFirstRows) { + return fetchFirstWhenPresent(fetchFirstRows); + } + + public FetchFirstFinisher fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { + MultiSelectDSL.this.fetchFirstRows = fetchFirstRows; + return new FetchFirstFinisher(); + } + @Override public MultiSelectModel build() { return MultiSelectDSL.this.build(); } } - class LocalOffsetFirstFinisher extends BaseBuildable implements OffsetFirstFinisher<MultiSelectModel> { + public class LimitFinisher implements Buildable<MultiSelectModel> { + public MultiSelectDSL offset(long offset) { + return offsetWhenPresent(offset); + } + + public MultiSelectDSL offsetWhenPresent(@Nullable Long offset) { + MultiSelectDSL.this.offset = offset; + return MultiSelectDSL.this; + } + @Override - public FetchFirstFinisher<MultiSelectModel> fetchFirstWhenPresent(Long fetchFirstRows) { - MultiSelectDSL.this.fetchFirstRows = fetchFirstRows; - return () -> MultiSelectDSL.this; + public MultiSelectModel build() { + return MultiSelectDSL.this.build(); } } - class LocalLimitFinisher extends BaseBuildable implements LimitFinisher<MultiSelectModel> { - @Override - public Buildable<MultiSelectModel> offsetWhenPresent(Long offset) { - MultiSelectDSL.this.offset = offset; + public class FetchFirstFinisher { + public MultiSelectDSL rowsOnly() { return MultiSelectDSL.this; } } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/PagingDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/PagingDSL.java deleted file mode 100644 index 7c6f004fd..000000000 --- a/src/main/java/org/mybatis/dynamic/sql/select/PagingDSL.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2016-2025 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 - * - * https://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.select; - -import org.mybatis.dynamic.sql.util.Buildable; - -public interface PagingDSL<T> { - default LimitFinisher<T> limit(long limit) { - return limitWhenPresent(limit); - } - - LimitFinisher<T> limitWhenPresent(Long limit); - - default OffsetFirstFinisher<T> offset(long offset) { - return offsetWhenPresent(offset); - } - - OffsetFirstFinisher<T> offsetWhenPresent(Long offset); - - default FetchFirstFinisher<T> fetchFirst(long fetchFirstRows) { - return fetchFirstWhenPresent(fetchFirstRows); - } - - FetchFirstFinisher<T> fetchFirstWhenPresent(Long fetchFirstRows); - - interface LimitFinisher<T> extends Buildable<T> { - default Buildable<T> offset(long offset) { - return offsetWhenPresent(offset); - } - - Buildable<T> offsetWhenPresent(Long offset); - } - - interface OffsetFirstFinisher<T> extends Buildable<T> { - default FetchFirstFinisher<T> fetchFirst(long fetchFirstRows) { - return fetchFirstWhenPresent(fetchFirstRows); - } - - FetchFirstFinisher<T> fetchFirstWhenPresent(Long fetchFirstRows); - } - - @FunctionalInterface - interface FetchFirstFinisher<T> { - Buildable<T> rowsOnly(); - } -} diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java index 3626e7bbd..6b52d3c3f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java @@ -42,7 +42,7 @@ * @param <R> * the type of model produced by this builder, typically SelectModel */ -public class SelectDSL<R> implements Buildable<R>, ConfigurableStatement<SelectDSL<R>>, PagingDSL<R> { +public class SelectDSL<R> implements Buildable<R>, ConfigurableStatement<SelectDSL<R>> { private final Function<SelectModel, R> adapterFunction; private final List<QueryExpressionDSL<R>> queryExpressions = new ArrayList<>(); @@ -110,19 +110,31 @@ void orderBy(Collection<? extends SortSpecification> columns) { orderByModel = OrderByModel.of(columns); } - public LimitFinisher<R> limitWhenPresent(@Nullable Long limit) { + public LimitFinisher limit(long limit) { + return limitWhenPresent(limit); + } + + public LimitFinisher limitWhenPresent(@Nullable Long limit) { this.limit = limit; - return new LocalLimitFinisher(); + return new LimitFinisher(); + } + + public OffsetFirstFinisher offset(long offset) { + return offsetWhenPresent(offset); } - public OffsetFirstFinisher<R> offsetWhenPresent(@Nullable Long offset) { + public OffsetFirstFinisher offsetWhenPresent(@Nullable Long offset) { this.offset = offset; - return new LocalOffsetFirstFinisher(); + return new OffsetFirstFinisher(); } - public FetchFirstFinisher<R> fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { + public FetchFirstFinisher fetchFirst(long fetchFirstRows) { + return fetchFirstWhenPresent(fetchFirstRows); + } + + public FetchFirstFinisher fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { this.fetchFirstRows = fetchFirstRows; - return () -> this; + return new FetchFirstFinisher(); } public SelectDSL<R> forUpdate() { @@ -193,25 +205,50 @@ private Optional<PagingModel> buildPagingModel() { .build(); } - abstract class BaseBuildable implements Buildable<R> { + public class OffsetFirstFinisher implements SelectDSLForAndWaitOperations<R>, Buildable<R> { + public FetchFirstFinisher fetchFirst(long fetchFirstRows) { + return fetchFirstWhenPresent(fetchFirstRows); + } + + public FetchFirstFinisher fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { + SelectDSL.this.fetchFirstRows = fetchFirstRows; + return new FetchFirstFinisher(); + } + + @Override + public SelectDSL<R> getSelectDSL() { + return SelectDSL.this; + } + @Override public R build() { return SelectDSL.this.build(); } } - class LocalOffsetFirstFinisher extends BaseBuildable implements OffsetFirstFinisher<R> { + public class LimitFinisher implements SelectDSLForAndWaitOperations<R>, Buildable<R> { + public SelectDSL<R> offset(long offset) { + return offsetWhenPresent(offset); + } + + public SelectDSL<R> offsetWhenPresent(@Nullable Long offset) { + SelectDSL.this.offset = offset; + return SelectDSL.this; + } + @Override - public FetchFirstFinisher<R> fetchFirstWhenPresent(Long fetchFirstRows) { - SelectDSL.this.fetchFirstRows = fetchFirstRows; - return () -> SelectDSL.this; + public SelectDSL<R> getSelectDSL() { + return SelectDSL.this; } - } - class LocalLimitFinisher extends BaseBuildable implements LimitFinisher<R> { @Override - public Buildable<R> offsetWhenPresent(Long offset) { - SelectDSL.this.offset = offset; + public R build() { + return SelectDSL.this.build(); + } + } + + public class FetchFirstFinisher { + public SelectDSL<R> rowsOnly() { return SelectDSL.this; } } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSLForAndWaitOperations.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSLForAndWaitOperations.java new file mode 100644 index 000000000..e4dc45d97 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSLForAndWaitOperations.java @@ -0,0 +1,53 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.select; + +public interface SelectDSLForAndWaitOperations<R> { + default SelectDSL<R> forUpdate() { + return getSelectDSL().forUpdate(); + } + + default SelectDSL<R> forNoKeyUpdate() { + return getSelectDSL().forNoKeyUpdate(); + } + + default SelectDSL<R> forShare() { + return getSelectDSL().forShare(); + } + + default SelectDSL<R> forKeyShare() { + return getSelectDSL().forKeyShare(); + } + + default SelectDSL<R> skipLocked() { + return getSelectDSL().skipLocked(); + } + + default SelectDSL<R> nowait() { + return getSelectDSL().nowait(); + } + + /** + * Gain access to the SelectDSL instance. + * + * <p>This is a leak of an implementation detail into the public API. The tradeoff is that it + * significantly reduces copy/paste code of SelectDSL methods into all the different inner classes of + * QueryExpressionDSL where they would be needed. + * + * @return the SelectDSL instance associated with this interface instance + */ + SelectDSL<R> getSelectDSL(); +} diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSLOperations.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSLOperations.java index 7f7c8b129..02f862c3b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSLOperations.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSLOperations.java @@ -17,63 +17,28 @@ import org.jspecify.annotations.Nullable; -public interface SelectDSLOperations<R> { - default PagingDSL.LimitFinisher<R> limit(long limit) { +public interface SelectDSLOperations<R> extends SelectDSLForAndWaitOperations<R> { + default SelectDSL<R>.LimitFinisher limit(long limit) { return getSelectDSL().limit(limit); } - default PagingDSL.LimitFinisher<R> limitWhenPresent(@Nullable Long limit) { + default SelectDSL<R>.LimitFinisher limitWhenPresent(@Nullable Long limit) { return getSelectDSL().limitWhenPresent(limit); } - default PagingDSL.OffsetFirstFinisher<R> offset(long offset) { + default SelectDSL<R>.OffsetFirstFinisher offset(long offset) { return getSelectDSL().offset(offset); } - default PagingDSL.OffsetFirstFinisher<R> offsetWhenPresent(@Nullable Long offset) { + default SelectDSL<R>.OffsetFirstFinisher offsetWhenPresent(@Nullable Long offset) { return getSelectDSL().offsetWhenPresent(offset); } - default PagingDSL.FetchFirstFinisher<R> fetchFirst(long fetchFirstRows) { + default SelectDSL<R>.FetchFirstFinisher fetchFirst(long fetchFirstRows) { return getSelectDSL().fetchFirst(fetchFirstRows); } - default PagingDSL.FetchFirstFinisher<R> fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { + default SelectDSL<R>.FetchFirstFinisher fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { return getSelectDSL().fetchFirstWhenPresent(fetchFirstRows); } - - default SelectDSL<R> forUpdate() { - return getSelectDSL().forUpdate(); - } - - default SelectDSL<R> forNoKeyUpdate() { - return getSelectDSL().forNoKeyUpdate(); - } - - default SelectDSL<R> forShare() { - return getSelectDSL().forShare(); - } - - default SelectDSL<R> forKeyShare() { - return getSelectDSL().forKeyShare(); - } - - default SelectDSL<R> skipLocked() { - return getSelectDSL().skipLocked(); - } - - default SelectDSL<R> nowait() { - return getSelectDSL().nowait(); - } - - /** - * Gain access to the SelectDSL instance. - * - * <p>This is a leak of an implementation detail into the public API. The tradeoff is that it - * significantly reduces copy/paste code of SelectDSL methods into all the different inner classes of - * QueryExpressionDSL where they would be needed. - * - * @return the SelectDSL instance associated with this interface instance - */ - SelectDSL<R> getSelectDSL(); } diff --git a/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java b/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java index 2464a4000..8e8981567 100644 --- a/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/InvalidSQLTest.java @@ -17,16 +17,14 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.mybatis.dynamic.sql.SqlBuilder.insert; -import static org.mybatis.dynamic.sql.SqlBuilder.insertInto; -import static org.mybatis.dynamic.sql.SqlBuilder.update; -import static org.mybatis.dynamic.sql.SqlBuilder.value; +import static org.mybatis.dynamic.sql.SqlBuilder.*; import java.util.Collections; import java.util.List; import java.util.MissingResourceException; import java.util.Optional; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.common.OrderByModel; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; @@ -260,10 +258,59 @@ void testInvalidValueAlias() { .withMessage(Messages.getString("ERROR.38")); } + @Test + void testInvalidDoubleForUpdate() { + var dsl = select(id).from(person).limit(2).forUpdate(); + assertThatExceptionOfType(InvalidSqlException.class).isThrownBy(dsl::forUpdate) + .withMessage(Messages.getString("ERROR.48")); + } + + @Test + void testInvalidDoubleForShare() { + var dsl = select(id).from(person).offset(2).forShare(); + assertThatExceptionOfType(InvalidSqlException.class).isThrownBy(dsl::forShare) + .withMessage(Messages.getString("ERROR.48")); + } + + @Test + void testInvalidDoubleForKeyShare() { + var dsl = select(id).from(person).forKeyShare(); + assertThatExceptionOfType(InvalidSqlException.class).isThrownBy(dsl::forKeyShare) + .withMessage(Messages.getString("ERROR.48")); + } + + @Test + void testInvalidDoubleForNoKeyUpdate() { + var dsl = select(id).from(person).where(id, isEqualTo(1)).forNoKeyUpdate(); + assertThatExceptionOfType(InvalidSqlException.class).isThrownBy(dsl::forNoKeyUpdate) + .withMessage(Messages.getString("ERROR.48")); + } + + @Test + void testInvalidDoubleForNoKeyUpdateAfterJoin() { + var dsl = select(id).from(person).join(person).on(id, isEqualTo(id)).skipLocked(); + assertThatExceptionOfType(InvalidSqlException.class).isThrownBy(dsl::skipLocked) + .withMessage(Messages.getString("ERROR.49")); + } + + @Test + void testInvalidDoubleForNoKeyUpdateAfterGroupBy() { + var dsl = select(id).from(person).groupBy(id).nowait(); + assertThatExceptionOfType(InvalidSqlException.class).isThrownBy(dsl::nowait) + .withMessage(Messages.getString("ERROR.49")); + } + + @Test + void testInvalidDoubleForNoKeyUpdateAfterHaving() { + var dsl = select(id).from(person).groupBy(id).having(id, isEqualTo(2)).nowait(); + assertThatExceptionOfType(InvalidSqlException.class).isThrownBy(dsl::nowait) + .withMessage(Messages.getString("ERROR.49")); + } + static class TestRow { - private Integer id; + private @Nullable Integer id; - public Integer getId() { + public @Nullable Integer getId() { return id; } From 1acab1b120b36ef1c76f4069c8c59e3b4056e563 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 24 Jan 2025 15:42:51 -0500 Subject: [PATCH 173/260] Sonar fixes --- .../java/org/mybatis/dynamic/sql/select/SelectModel.java | 4 ++-- .../column/comparison/ColumnComparisonMapper.java | 7 ++----- src/test/java/examples/joins/JoinMapper.java | 9 +++------ .../java/examples/springbatch/mapper/PersonMapper.java | 9 +++------ 4 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java index 8367606d9..ec277760b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectModel.java @@ -29,8 +29,8 @@ public class SelectModel extends AbstractSelectModel { private final List<QueryExpressionModel> queryExpressions; - private @Nullable final String forClause; - private @Nullable final String waitClause; + private final @Nullable String forClause; + private final @Nullable String waitClause; private SelectModel(Builder builder) { super(builder); diff --git a/src/test/java/examples/column/comparison/ColumnComparisonMapper.java b/src/test/java/examples/column/comparison/ColumnComparisonMapper.java index f20fc9a84..a8acf0c88 100644 --- a/src/test/java/examples/column/comparison/ColumnComparisonMapper.java +++ b/src/test/java/examples/column/comparison/ColumnComparisonMapper.java @@ -18,7 +18,6 @@ import java.util.List; import org.apache.ibatis.annotations.Result; -import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.SelectProvider; import org.mybatis.dynamic.sql.select.SelectDSLCompleter; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; @@ -28,10 +27,8 @@ public interface ColumnComparisonMapper { @SelectProvider(type=SqlProviderAdapter.class, method="select") - @Results({ - @Result(column="number1", property="number1", id=true), - @Result(column="number2", property="number2", id=true) - }) + @Result(column="number1", property="number1", id=true) + @Result(column="number2", property="number2", id=true) List<ColumnComparisonRecord> selectMany(SelectStatementProvider selectStatement); default List<ColumnComparisonRecord> select(SelectDSLCompleter completer) { diff --git a/src/test/java/examples/joins/JoinMapper.java b/src/test/java/examples/joins/JoinMapper.java index 447546035..0ce4cc42c 100644 --- a/src/test/java/examples/joins/JoinMapper.java +++ b/src/test/java/examples/joins/JoinMapper.java @@ -19,7 +19,6 @@ import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.ResultMap; -import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.SelectProvider; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.mybatis.dynamic.sql.util.SqlProviderAdapter; @@ -30,10 +29,8 @@ public interface JoinMapper { List<OrderMaster> selectMany(SelectStatementProvider selectStatement); @SelectProvider(type=SqlProviderAdapter.class, method="select") - @Results ({ - @Result(column="user_id", property="userId"), - @Result(column="user_name", property="userName"), - @Result(column="parent_id", property="parentId") - }) + @Result(column="user_id", property="userId") + @Result(column="user_name", property="userName") + @Result(column="parent_id", property="parentId") List<User> selectUsers(SelectStatementProvider selectStatement); } diff --git a/src/test/java/examples/springbatch/mapper/PersonMapper.java b/src/test/java/examples/springbatch/mapper/PersonMapper.java index 12d6837ee..a1db34626 100644 --- a/src/test/java/examples/springbatch/mapper/PersonMapper.java +++ b/src/test/java/examples/springbatch/mapper/PersonMapper.java @@ -20,7 +20,6 @@ import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Result; -import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.SelectProvider; import org.mybatis.dynamic.sql.util.mybatis3.CommonCountMapper; import org.mybatis.dynamic.sql.util.mybatis3.CommonInsertMapper; @@ -33,10 +32,8 @@ public interface PersonMapper extends CommonCountMapper, CommonInsertMapper<PersonRecord>, CommonUpdateMapper { @SelectProvider(type=SpringBatchProviderAdapter.class, method="select") - @Results({ - @Result(column="id", property="id", id=true), - @Result(column="first_name", property="firstName"), - @Result(column="last_name", property="lastName") - }) + @Result(column="id", property="id", id=true) + @Result(column="first_name", property="firstName") + @Result(column="last_name", property="lastName") List<PersonRecord> selectMany(Map<String, Object> parameterValues); } From 12e3de04b7c1eee0974dbca52d751b8da6adf7e1 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 24 Jan 2025 16:13:32 -0500 Subject: [PATCH 174/260] Add Kotlin Support for new select items --- .../sql/util/kotlin/KotlinSelectBuilder.kt | 24 ++++++++++ .../sql/util/kotlin/model/ModelBuilderTest.kt | 46 +++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSelectBuilder.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSelectBuilder.kt index bd115230d..4c80f9d8c 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSelectBuilder.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/KotlinSelectBuilder.kt @@ -76,6 +76,30 @@ class KotlinSelectBuilder(private val fromGatherer: QueryExpressionDSL.FromGathe fun unionAll(unionAll: KotlinUnionBuilder.() -> Unit): Unit = unionAll(KotlinUnionBuilder(getDsl().unionAll())) + fun forUpdate() { + getDsl().forUpdate() + } + + fun forNoKeyUpdate() { + getDsl().forNoKeyUpdate() + } + + fun forShare() { + getDsl().forShare() + } + + fun forKeyShare() { + getDsl().forKeyShare() + } + + fun skipLocked() { + getDsl().skipLocked() + } + + fun nowait() { + getDsl().nowait() + } + override fun build(): SelectModel = getDsl().build() override fun getDsl(): KQueryExpressionDSL = invalidIfNull(dsl, "ERROR.27") //$NON-NLS-1$ diff --git a/src/test/kotlin/org/mybatis/dynamic/sql/util/kotlin/model/ModelBuilderTest.kt b/src/test/kotlin/org/mybatis/dynamic/sql/util/kotlin/model/ModelBuilderTest.kt index 878bad3b9..d4394a500 100644 --- a/src/test/kotlin/org/mybatis/dynamic/sql/util/kotlin/model/ModelBuilderTest.kt +++ b/src/test/kotlin/org/mybatis/dynamic/sql/util/kotlin/model/ModelBuilderTest.kt @@ -46,4 +46,50 @@ class ModelBuilderTest { assertThat(provider.selectStatement).isEqualTo("select distinct id, description from Table where id = :p1") } + + @Test + fun testSelectBuilderForUpdate() { + val provider = select(id, description) { + from(table) + where { id isEqualTo 3 } + forUpdate() + skipLocked() + }.render(RenderingStrategies.SPRING_NAMED_PARAMETER) + + assertThat(provider.selectStatement).isEqualTo("select id, description from Table where id = :p1 for update skip locked") + } + + @Test + fun testSelectBuilderForShare() { + val provider = select(id, description) { + from(table) + where { id isEqualTo 3 } + forShare() + nowait() + }.render(RenderingStrategies.SPRING_NAMED_PARAMETER) + + assertThat(provider.selectStatement).isEqualTo("select id, description from Table where id = :p1 for share nowait") + } + + @Test + fun testSelectBuilderForKeyShare() { + val provider = select(id, description) { + from(table) + where { id isEqualTo 3 } + forKeyShare() + }.render(RenderingStrategies.SPRING_NAMED_PARAMETER) + + assertThat(provider.selectStatement).isEqualTo("select id, description from Table where id = :p1 for key share") + } + + @Test + fun testSelectBuilderForKeyNoKeyUpdate() { + val provider = select(id, description) { + from(table) + where { id isEqualTo 3 } + forNoKeyUpdate() + }.render(RenderingStrategies.SPRING_NAMED_PARAMETER) + + assertThat(provider.selectStatement).isEqualTo("select id, description from Table where id = :p1 for no key update") + } } From 22ccb063f5f9a5c2a5f3bbc16112d5790ce1042c Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 24 Jan 2025 16:20:19 -0500 Subject: [PATCH 175/260] Use interfaces when possible --- .../dynamic/sql/select/AbstractHavingStarter.java | 14 +++++++------- .../org/mybatis/dynamic/sql/select/HavingDSL.java | 4 ++-- .../dynamic/sql/select/QueryExpressionDSL.java | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingStarter.java b/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingStarter.java index 264e8046e..c8375bbd3 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingStarter.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingStarter.java @@ -25,14 +25,14 @@ import org.mybatis.dynamic.sql.SqlCriterion; import org.mybatis.dynamic.sql.VisitableCondition; -public abstract class AbstractHavingStarter<F extends AbstractHavingFinisher<?>> { +public interface AbstractHavingStarter<F extends AbstractHavingFinisher<?>> { - public <T> F having(BindableColumn<T> column, VisitableCondition<T> condition, + default <T> F having(BindableColumn<T> column, VisitableCondition<T> condition, AndOrCriteriaGroup... subCriteria) { return having(column, condition, Arrays.asList(subCriteria)); } - public <T> F having(BindableColumn<T> column, VisitableCondition<T> condition, + default <T> F having(BindableColumn<T> column, VisitableCondition<T> condition, List<AndOrCriteriaGroup> subCriteria) { SqlCriterion sqlCriterion = ColumnAndConditionCriterion.withColumn(column) .withCondition(condition) @@ -42,11 +42,11 @@ public <T> F having(BindableColumn<T> column, VisitableCondition<T> condition, return initialize(sqlCriterion); } - public F having(SqlCriterion initialCriterion, AndOrCriteriaGroup... subCriteria) { + default F having(SqlCriterion initialCriterion, AndOrCriteriaGroup... subCriteria) { return having(initialCriterion, Arrays.asList(subCriteria)); } - public F having(SqlCriterion initialCriterion, List<AndOrCriteriaGroup> subCriteria) { + default F having(SqlCriterion initialCriterion, List<AndOrCriteriaGroup> subCriteria) { SqlCriterion sqlCriterion = new CriteriaGroup.Builder() .withInitialCriterion(initialCriterion) .withSubCriteria(subCriteria) @@ -55,9 +55,9 @@ public F having(SqlCriterion initialCriterion, List<AndOrCriteriaGroup> subCrite return initialize(sqlCriterion); } - protected abstract F having(); + F having(); - public F applyHaving(HavingApplier havingApplier) { + default F applyHaving(HavingApplier havingApplier) { F finisher = having(); havingApplier.accept(finisher); return finisher; diff --git a/src/main/java/org/mybatis/dynamic/sql/select/HavingDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/HavingDSL.java index 34be15f62..58ca01184 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/HavingDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/HavingDSL.java @@ -17,11 +17,11 @@ import org.mybatis.dynamic.sql.util.Buildable; -public class HavingDSL extends AbstractHavingStarter<HavingDSL.StandaloneHavingFinisher> { +public class HavingDSL implements AbstractHavingStarter<HavingDSL.StandaloneHavingFinisher> { private final StandaloneHavingFinisher havingFinisher = new StandaloneHavingFinisher(); @Override - protected StandaloneHavingFinisher having() { + public StandaloneHavingFinisher having() { return havingFinisher; } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java index fcb8bdf67..afb6cda0c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java @@ -477,8 +477,8 @@ public SelectDSL<R> getSelectDSL() { } } - public class GroupByFinisher extends AbstractHavingStarter<QueryExpressionHavingBuilder> - implements Buildable<R>, SelectDSLOperations<R> { + public class GroupByFinisher implements AbstractHavingStarter<QueryExpressionHavingBuilder>, + Buildable<R>, SelectDSLOperations<R> { public SelectDSL<R> orderBy(SortSpecification... columns) { return orderBy(Arrays.asList(columns)); } From 2a1b8dad8d92e8522f415233d7dec1b16c3b32d2 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 24 Jan 2025 16:41:36 -0500 Subject: [PATCH 176/260] Docs --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 324cff2e8..3c12f44da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -96,6 +96,10 @@ Runtime behavior changes: rendering if a null value is passed in - The JOIN syntax is updated and now allows full boolean expressions like a WHERE clause. The prior JOIN syntax is deprecated and will be removed in a future release. +- Add support for locking options in select statements (for update, for share, etc.) This is not an abstraction of + these concepts for different databases it simply adds known clauses to a generated SQL statement. You should always + test to make sure these functions work in your target database. Currently, we support, and test, the options + supported by PostgreSQL. ## Release 1.5.2 - June 3, 2024 From fb9de67ceed411adbb46d842d7b6e6d3fa4db4c7 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Sat, 25 Jan 2025 17:09:40 -0500 Subject: [PATCH 177/260] Fully qualify the inner classes to stop CPD false positives --- .../mybatis/dynamic/sql/select/MultiSelectDSL.java | 12 ++++++------ .../org/mybatis/dynamic/sql/select/SelectDSL.java | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java index 63ceb4e0a..124fe095b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/MultiSelectDSL.java @@ -61,29 +61,29 @@ public MultiSelectDSL orderBy(Collection<? extends SortSpecification> columns) { return this; } - public LimitFinisher limit(long limit) { + public MultiSelectDSL.LimitFinisher limit(long limit) { return limitWhenPresent(limit); } - public LimitFinisher limitWhenPresent(@Nullable Long limit) { + public MultiSelectDSL.LimitFinisher limitWhenPresent(@Nullable Long limit) { this.limit = limit; return new LimitFinisher(); } - public OffsetFirstFinisher offset(long offset) { + public MultiSelectDSL.OffsetFirstFinisher offset(long offset) { return offsetWhenPresent(offset); } - public OffsetFirstFinisher offsetWhenPresent(@Nullable Long offset) { + public MultiSelectDSL.OffsetFirstFinisher offsetWhenPresent(@Nullable Long offset) { this.offset = offset; return new OffsetFirstFinisher(); } - public FetchFirstFinisher fetchFirst(long fetchFirstRows) { + public MultiSelectDSL.FetchFirstFinisher fetchFirst(long fetchFirstRows) { return fetchFirstWhenPresent(fetchFirstRows); } - public FetchFirstFinisher fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { + public MultiSelectDSL.FetchFirstFinisher fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { this.fetchFirstRows = fetchFirstRows; return new FetchFirstFinisher(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java index 6b52d3c3f..2c2963772 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java @@ -110,29 +110,29 @@ void orderBy(Collection<? extends SortSpecification> columns) { orderByModel = OrderByModel.of(columns); } - public LimitFinisher limit(long limit) { + public SelectDSL<R>.LimitFinisher limit(long limit) { return limitWhenPresent(limit); } - public LimitFinisher limitWhenPresent(@Nullable Long limit) { + public SelectDSL<R>.LimitFinisher limitWhenPresent(@Nullable Long limit) { this.limit = limit; return new LimitFinisher(); } - public OffsetFirstFinisher offset(long offset) { + public SelectDSL<R>.OffsetFirstFinisher offset(long offset) { return offsetWhenPresent(offset); } - public OffsetFirstFinisher offsetWhenPresent(@Nullable Long offset) { + public SelectDSL<R>.OffsetFirstFinisher offsetWhenPresent(@Nullable Long offset) { this.offset = offset; return new OffsetFirstFinisher(); } - public FetchFirstFinisher fetchFirst(long fetchFirstRows) { + public SelectDSL<R>.FetchFirstFinisher fetchFirst(long fetchFirstRows) { return fetchFirstWhenPresent(fetchFirstRows); } - public FetchFirstFinisher fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { + public SelectDSL<R>.FetchFirstFinisher fetchFirstWhenPresent(@Nullable Long fetchFirstRows) { this.fetchFirstRows = fetchFirstRows; return new FetchFirstFinisher(); } From bd3c2b3c4143cb9226867ca7037447ee44a81431 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 09:37:32 +0000 Subject: [PATCH 178/260] Update kotlin monorepo to v2.1.10 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ede046b79..b5b71b37c 100644 --- a/pom.xml +++ b/pom.xml @@ -69,7 +69,7 @@ <module.name>org.mybatis.dynamic.sql</module.name> - <kotlin.version>2.1.0</kotlin.version> + <kotlin.version>2.1.10</kotlin.version> <kotlin.compiler.jvmTarget>17</kotlin.compiler.jvmTarget> <kotlin.compiler.languageVersion>2.0</kotlin.compiler.languageVersion> <kotlin.compiler.apiVersion>2.0</kotlin.compiler.apiVersion> From 67940fcd3a29206ed781772969982bf3f8b592ea Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 4 Feb 2025 13:02:48 -0500 Subject: [PATCH 179/260] No need to create an intermediate list --- .../sql/update/render/UpdateRenderer.java | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) 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 2a3599788..b0a6a24b1 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 @@ -15,7 +15,6 @@ */ package org.mybatis.dynamic.sql.update.render; -import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @@ -77,23 +76,15 @@ private FragmentAndParameters calculateUpdateStatementStart() { } private FragmentAndParameters calculateSetPhrase() { - List<Optional<FragmentAndParameters>> fragmentsAndParameters = updateModel.columnMappings() + FragmentCollector fragmentsCollector = updateModel.columnMappings() .map(m -> m.accept(visitor)) - .toList(); - - Validator.assertFalse(fragmentsAndParameters.stream().noneMatch(Optional::isPresent), - "ERROR.18"); //$NON-NLS-1$ - - FragmentCollector fragmentCollector = fragmentsAndParameters.stream() .flatMap(Optional::stream) .collect(FragmentCollector.collect()); - return toSetPhrase(fragmentCollector); - } + Validator.assertFalse(fragmentsCollector.isEmpty(), "ERROR.18"); //$NON-NLS-1$ - private FragmentAndParameters toSetPhrase(FragmentCollector fragmentCollector) { - return fragmentCollector.toFragmentAndParameters( - Collectors.joining(", ", "set ", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + return fragmentsCollector.toFragmentAndParameters( + Collectors.joining(", ", "set ", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } private Optional<FragmentAndParameters> calculateWhereClause() { From aecb63a0ff4c7ca45fedcf40fb57ebbf488bb1d7 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 4 Feb 2025 13:03:37 -0500 Subject: [PATCH 180/260] Typo --- .../mybatis/dynamic/sql/update/render/UpdateRenderer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 b0a6a24b1..ee0f74961 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 @@ -76,14 +76,14 @@ private FragmentAndParameters calculateUpdateStatementStart() { } private FragmentAndParameters calculateSetPhrase() { - FragmentCollector fragmentsCollector = updateModel.columnMappings() + FragmentCollector fragmentCollector = updateModel.columnMappings() .map(m -> m.accept(visitor)) .flatMap(Optional::stream) .collect(FragmentCollector.collect()); - Validator.assertFalse(fragmentsCollector.isEmpty(), "ERROR.18"); //$NON-NLS-1$ + Validator.assertFalse(fragmentCollector.isEmpty(), "ERROR.18"); //$NON-NLS-1$ - return fragmentsCollector.toFragmentAndParameters( + return fragmentCollector.toFragmentAndParameters( Collectors.joining(", ", "set ", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } From 59599cf21e4b5c2a1b8ec52b2262ef136e989592 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 10 Feb 2025 16:19:26 -0500 Subject: [PATCH 181/260] Simplify column and condition renderer --- .../render/ColumnAndConditionRenderer.java | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java index 73f456981..6035c143b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java @@ -15,45 +15,43 @@ */ package org.mybatis.dynamic.sql.where.render; -import static org.mybatis.dynamic.sql.util.StringUtilities.spaceBefore; - import java.util.Objects; +import java.util.stream.Collectors; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.VisitableCondition; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; +import org.mybatis.dynamic.sql.util.FragmentCollector; public class ColumnAndConditionRenderer<T> { private final BindableColumn<T> column; private final VisitableCondition<T> condition; private final RenderingContext renderingContext; + private final DefaultConditionVisitor<T> visitor; private ColumnAndConditionRenderer(Builder<T> builder) { column = Objects.requireNonNull(builder.column); condition = Objects.requireNonNull(builder.condition); renderingContext = Objects.requireNonNull(builder.renderingContext); - } - - public FragmentAndParameters render() { - FragmentAndParameters renderedLeftColumn = column.alias() - .map(FragmentAndParameters::fromFragment) - .orElseGet(() -> column.render(renderingContext)); - - DefaultConditionVisitor<T> visitor = DefaultConditionVisitor.withColumn(column) + visitor = DefaultConditionVisitor.withColumn(column) .withRenderingContext(renderingContext) .build(); + } - FragmentAndParameters renderedCondition = condition.accept(visitor); - - String finalFragment = condition.overrideRenderedLeftColumn(renderedLeftColumn.fragment()) - + spaceBefore(renderedCondition.fragment()); + public FragmentAndParameters render() { + FragmentCollector fc = new FragmentCollector(); + fc.add(renderLeftColumn()); + fc.add(condition.accept(visitor)); + return fc.toFragmentAndParameters(Collectors.joining(" ")); //$NON-NLS-1$ + } - return FragmentAndParameters.withFragment(finalFragment) - .withParameters(renderedLeftColumn.parameters()) - .withParameters(renderedCondition.parameters()) - .build(); + private FragmentAndParameters renderLeftColumn() { + return column.alias() + .map(FragmentAndParameters::fromFragment) + .orElseGet(() -> column.render(renderingContext)) + .mapFragment(condition::overrideRenderedLeftColumn); } public static class Builder<T> { From 716ed066b665738f9d5c3a44e3c56e744052dcbb Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 10 Feb 2025 16:52:13 -0500 Subject: [PATCH 182/260] Collect Fragments and Parameters as we go --- .../dynamic/sql/util/FragmentCollector.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/util/FragmentCollector.java b/src/main/java/org/mybatis/dynamic/sql/util/FragmentCollector.java index bdf7371ba..410d7a035 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/FragmentCollector.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/FragmentCollector.java @@ -16,6 +16,7 @@ package org.mybatis.dynamic.sql.util; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -23,7 +24,8 @@ import java.util.stream.Collector; public class FragmentCollector { - final List<FragmentAndParameters> fragments = new ArrayList<>(); + final List<String> fragments = new ArrayList<>(); + final Map<String, Object> parameters = new HashMap<>(); public FragmentCollector() { super(); @@ -34,20 +36,22 @@ private FragmentCollector(FragmentAndParameters initialFragment) { } public void add(FragmentAndParameters fragmentAndParameters) { - fragments.add(fragmentAndParameters); + fragments.add(fragmentAndParameters.fragment()); + parameters.putAll(fragmentAndParameters.parameters()); } public FragmentCollector merge(FragmentCollector other) { fragments.addAll(other.fragments); + parameters.putAll(other.parameters); return this; } public Optional<String> firstFragment() { - return fragments.stream().findFirst().map(FragmentAndParameters::fragment); + return fragments.stream().findFirst(); } public String collectFragments(Collector<CharSequence, ?, String> fragmentCollector) { - return fragments.stream().map(FragmentAndParameters::fragment).collect(fragmentCollector); + return fragments.stream().collect(fragmentCollector); } public FragmentAndParameters toFragmentAndParameters(Collector<CharSequence, ?, String> fragmentCollector) { @@ -57,9 +61,7 @@ public FragmentAndParameters toFragmentAndParameters(Collector<CharSequence, ?, } public Map<String, Object> parameters() { - return fragments.stream() - .map(FragmentAndParameters::parameters) - .collect(HashMap::new, HashMap::putAll, HashMap::putAll); + return Collections.unmodifiableMap(parameters); } public boolean hasMultipleFragments() { From 910d28f554bd356acc61e318506752ca15be02ea Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Feb 2025 20:29:43 +0000 Subject: [PATCH 183/260] Update dependency org.mariadb.jdbc:mariadb-java-client to v3.5.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b5b71b37c..ffbbe3895 100644 --- a/pom.xml +++ b/pom.xml @@ -200,7 +200,7 @@ <dependency> <groupId>org.mariadb.jdbc</groupId> <artifactId>mariadb-java-client</artifactId> - <version>3.5.1</version> + <version>3.5.2</version> <scope>test</scope> </dependency> <dependency> From b92c8dbc9cb5e6cba4c6c985b91ba2fc189a04e8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 13 Feb 2025 16:25:56 +0000 Subject: [PATCH 184/260] Update dependency org.springframework:spring-jdbc to v6.2.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ffbbe3895..b4786712c 100644 --- a/pom.xml +++ b/pom.xml @@ -101,7 +101,7 @@ <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> - <version>6.2.2</version> + <version>6.2.3</version> <scope>provided</scope> <optional>true</optional> </dependency> From 6ee6ce67ad12cb23c4e6de7f1d1b151a199a6de9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 19 Feb 2025 23:13:42 +0000 Subject: [PATCH 185/260] Update testcontainers-java monorepo to v1.20.5 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b4786712c..53cdace6e 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ <sonar.tests>src/test/java,src/test/kotlin</sonar.tests> <kotlin.code.style>official</kotlin.code.style> - <test.containers.version>1.20.4</test.containers.version> + <test.containers.version>1.20.5</test.containers.version> <osgi.export>org.mybatis.dynamic.sql.*;version=${project.version};-noimport:=true</osgi.export> <!-- Reproducible Builds --> From 57a757c59e287f6d129d547c6c74c1972f4cea54 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 21 Feb 2025 15:51:47 +0000 Subject: [PATCH 186/260] Update junit5 monorepo to v5.12.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 53cdace6e..7a741e456 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ <java.release.version>17</java.release.version> <java.test.version>17</java.test.version> <java.test.release.version>17</java.test.release.version> - <junit.jupiter.version>5.11.4</junit.jupiter.version> + <junit.jupiter.version>5.12.0</junit.jupiter.version> <spring.batch.version>5.2.1</spring.batch.version> <checkstyle.config>checkstyle-override.xml</checkstyle.config> From c263366641c018af76cbb753830107db1fccf0d6 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Sat, 22 Feb 2025 13:06:19 -0500 Subject: [PATCH 187/260] Fix Nullability Error A type converter could return null. This was not properly handled by the ValueWhenPresentMapping. --- .../sql/util/ValueWhenPresentMapping.java | 6 ++-- .../spring/LastNameParameterConverter.java | 9 ++++-- .../examples/spring/PersonTemplateTest.java | 28 +++++++++++++++++++ .../examples/simple/CreateSimpleDB.sql | 2 +- 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java b/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java index a9dae6c66..5420c644e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/ValueWhenPresentMapping.java @@ -35,11 +35,11 @@ private ValueWhenPresentMapping(SqlColumn<T> column, Supplier<@Nullable T> value } public Optional<Object> value() { - return Optional.ofNullable(valueSupplier.get()).map(this::convert); + return Optional.ofNullable(valueSupplier.get()).flatMap(this::convert); } - private @Nullable Object convert(@Nullable T value) { - return localColumn.convertParameterType(value); + private Optional<Object> convert(T value) { + return Optional.ofNullable(localColumn.convertParameterType(value)); } @Override diff --git a/src/test/java/examples/spring/LastNameParameterConverter.java b/src/test/java/examples/spring/LastNameParameterConverter.java index 2a45753d7..e8d57d4cd 100644 --- a/src/test/java/examples/spring/LastNameParameterConverter.java +++ b/src/test/java/examples/spring/LastNameParameterConverter.java @@ -16,6 +16,7 @@ package examples.spring; import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.ParameterTypeConverter; import org.springframework.core.convert.converter.Converter; @@ -23,7 +24,11 @@ public class LastNameParameterConverter implements ParameterTypeConverter<LastName, String>, Converter<LastName, String> { @Override - public String convert(LastName source) { - return source.getName(); + public @Nullable String convert(LastName source) { + if ("Slate".equals(source.getName())) { + return null; + } else { + return source.getName(); + } } } diff --git a/src/test/java/examples/spring/PersonTemplateTest.java b/src/test/java/examples/spring/PersonTemplateTest.java index 3934d3125..8376dcef7 100644 --- a/src/test/java/examples/spring/PersonTemplateTest.java +++ b/src/test/java/examples/spring/PersonTemplateTest.java @@ -31,6 +31,8 @@ import org.mybatis.dynamic.sql.insert.GeneralInsertModel; import org.mybatis.dynamic.sql.insert.InsertModel; import org.mybatis.dynamic.sql.insert.MultiRowInsertModel; +import org.mybatis.dynamic.sql.insert.render.GeneralInsertStatementProvider; +import org.mybatis.dynamic.sql.render.RenderingStrategies; import org.mybatis.dynamic.sql.select.SelectModel; import org.mybatis.dynamic.sql.update.UpdateModel; import org.mybatis.dynamic.sql.util.Buildable; @@ -379,6 +381,32 @@ void testInsertSelective() { assertThat(rows).isEqualTo(1); } + @Test + void testGeneralInsertWhenTypeConverterReturnsNull() { + + GeneralInsertStatementProvider insertStatement = insertInto(person) + .set(id).toValue(100) + .set(firstName).toValue("Joe") + .set(lastName).toValueWhenPresent(LastName.of("Slate")) + .set(birthDate).toValue(new Date()) + .set(employed).toValue(true) + .set(occupation).toValue("Quarry Owner") + .set(addressId).toValue(1) + .build() + .render(RenderingStrategies.SPRING_NAMED_PARAMETER); + + assertThat(insertStatement.getInsertStatement()) + .isEqualTo("insert into Person (id, first_name, birth_date, employed, occupation, address_id) values (:p1, :p2, :p3, :p4, :p5, :p6)"); + int rows = template.generalInsert(insertStatement); + assertThat(rows).isEqualTo(1); + + Buildable<SelectModel> selectStatement = select(id, firstName, lastName, birthDate, employed, occupation, addressId) + .from(person) + .where(id, isEqualTo(100)); + Optional<PersonRecord> newRecord = template.selectOne(selectStatement, personRowMapper); + assertThat(newRecord).hasValueSatisfying(r -> assertThat(r.getLastName().getName()).isNull()); + } + @Test void testUpdateByPrimaryKey() { diff --git a/src/test/resources/examples/simple/CreateSimpleDB.sql b/src/test/resources/examples/simple/CreateSimpleDB.sql index a60c51ef9..c335c4215 100644 --- a/src/test/resources/examples/simple/CreateSimpleDB.sql +++ b/src/test/resources/examples/simple/CreateSimpleDB.sql @@ -30,7 +30,7 @@ create table Address ( create table Person ( id int not null, first_name varchar(30) not null, - last_name varchar(30) not null, + last_name varchar(30) null, birth_date date not null, employed varchar(3) not null, occupation varchar(30) null, From d761dd55b7d000e2305a3b87d15e532fc43dd73c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 22:31:55 +0000 Subject: [PATCH 188/260] Update dependency ch.qos.logback:logback-classic to v1.5.17 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7a741e456..be8a7a259 100644 --- a/pom.xml +++ b/pom.xml @@ -170,7 +170,7 @@ <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> - <version>1.5.16</version> + <version>1.5.17</version> <scope>test</scope> </dependency> <dependency> From 7a283ee9157d6c6ec7687f3730dbc1a8c07b82a6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 4 Mar 2025 23:33:03 +0000 Subject: [PATCH 189/260] Update testcontainers-java monorepo to v1.20.6 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index be8a7a259..584b5daa6 100644 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ <sonar.tests>src/test/java,src/test/kotlin</sonar.tests> <kotlin.code.style>official</kotlin.code.style> - <test.containers.version>1.20.5</test.containers.version> + <test.containers.version>1.20.6</test.containers.version> <osgi.export>org.mybatis.dynamic.sql.*;version=${project.version};-noimport:=true</osgi.export> <!-- Reproducible Builds --> From 1ae2e43d103aa5f538477530fd7cc9b27304e891 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 5 Mar 2025 14:29:25 -0500 Subject: [PATCH 190/260] Allow Conditions Increased Control over Rendering --- .../AbstractColumnComparisonCondition.java | 15 +- .../sql/AbstractListValueCondition.java | 30 +++- .../dynamic/sql/AbstractNoValueCondition.java | 13 +- .../sql/AbstractSingleValueCondition.java | 21 ++- .../sql/AbstractSubselectCondition.java | 18 ++- .../sql/AbstractTwoValueCondition.java | 27 +++- .../mybatis/dynamic/sql/ConditionVisitor.java | 30 ---- .../dynamic/sql/VisitableCondition.java | 21 +-- .../SimpleCaseWhenConditionRenderer.java | 8 +- .../CaseInsensitiveVisitableCondition.java | 9 +- .../render/ColumnAndConditionRenderer.java | 15 +- .../where/render/DefaultConditionVisitor.java | 137 ------------------ .../java/examples/mysql/IsLikeEscape.java | 71 +++++++++ src/test/java/examples/mysql/MySQLTest.java | 21 +++ 14 files changed, 198 insertions(+), 238 deletions(-) delete mode 100644 src/main/java/org/mybatis/dynamic/sql/ConditionVisitor.java delete mode 100644 src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java create mode 100644 src/test/java/examples/mysql/IsLikeEscape.java diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractColumnComparisonCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractColumnComparisonCondition.java index ff6923ecb..502025401 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractColumnComparisonCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractColumnComparisonCondition.java @@ -15,6 +15,11 @@ */ package org.mybatis.dynamic.sql; +import static org.mybatis.dynamic.sql.util.StringUtilities.spaceBefore; + +import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; + public abstract class AbstractColumnComparisonCondition<T> implements VisitableCondition<T> { protected final BasicColumn rightColumn; @@ -23,14 +28,10 @@ protected AbstractColumnComparisonCondition(BasicColumn rightColumn) { this.rightColumn = rightColumn; } - public BasicColumn rightColumn() { - return rightColumn; - } + public abstract String operator(); @Override - public <R> R accept(ConditionVisitor<T, R> visitor) { - return visitor.visit(this); + public FragmentAndParameters renderCondition(RenderingContext renderingContext, BindableColumn<T> leftColumn) { + return rightColumn.render(renderingContext).mapFragment(f -> operator() + spaceBefore(f)); } - - public abstract String operator(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java index 21230c821..eeed434ab 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java @@ -23,6 +23,11 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.mybatis.dynamic.sql.render.RenderedParameterInfo; +import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; +import org.mybatis.dynamic.sql.util.FragmentCollector; + public abstract class AbstractListValueCondition<T> implements VisitableCondition<T> { protected final Collection<T> values; @@ -39,19 +44,14 @@ public boolean isEmpty() { return values.isEmpty(); } - @Override - public <R> R accept(ConditionVisitor<T, R> visitor) { - return visitor.visit(this); - } - private <R> Collection<R> applyMapper(Function<? super T, ? extends R> mapper) { Objects.requireNonNull(mapper); - return values.stream().map(mapper).collect(Collectors.toList()); + return values().map(mapper).collect(Collectors.toList()); } private Collection<T> applyFilter(Predicate<? super T> predicate) { Objects.requireNonNull(predicate); - return values.stream().filter(predicate).toList(); + return values().filter(predicate).toList(); } protected <S extends AbstractListValueCondition<T>> S filterSupport(Predicate<? super T> predicate, @@ -84,4 +84,20 @@ protected <R, S extends AbstractListValueCondition<R>> S mapSupport(Function<? s public abstract AbstractListValueCondition<T> filter(Predicate<? super T> predicate); public abstract String operator(); + + @Override + public FragmentAndParameters renderCondition(RenderingContext renderingContext, BindableColumn<T> leftColumn) { + return values().map(v -> toFragmentAndParameters(v, renderingContext, leftColumn)) + .collect(FragmentCollector.collect()) + .toFragmentAndParameters(Collectors.joining(",", //$NON-NLS-1$ + operator() + " (", ")")); //$NON-NLS-1$ //$NON-NLS-2$ + } + + private FragmentAndParameters toFragmentAndParameters(T value, RenderingContext renderingContext, + BindableColumn<T> leftColumn) { + RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo(leftColumn); + return FragmentAndParameters.withFragment(parameterInfo.renderedPlaceHolder()) + .withParameter(parameterInfo.parameterMapKey(), leftColumn.convertParameterType(value)) + .build(); + } } diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java index a60f2a843..02f6e25f4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java @@ -18,12 +18,10 @@ import java.util.function.BooleanSupplier; import java.util.function.Supplier; -public abstract class AbstractNoValueCondition<T> implements VisitableCondition<T> { +import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; - @Override - public <R> R accept(ConditionVisitor<T, R> visitor) { - return visitor.visit(this); - } +public abstract class AbstractNoValueCondition<T> implements VisitableCondition<T> { protected <S extends AbstractNoValueCondition<?>> S filterSupport(BooleanSupplier booleanSupplier, Supplier<S> emptySupplier, S self) { @@ -35,4 +33,9 @@ protected <S extends AbstractNoValueCondition<?>> S filterSupport(BooleanSupplie } public abstract String operator(); + + @Override + public FragmentAndParameters renderCondition(RenderingContext renderingContext, BindableColumn<T> leftColumn) { + return FragmentAndParameters.fromFragment(operator()); + } } diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java index 13d4dc8e1..a361c4ed0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java @@ -15,10 +15,16 @@ */ package org.mybatis.dynamic.sql; +import static org.mybatis.dynamic.sql.util.StringUtilities.spaceBefore; + import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; +import org.mybatis.dynamic.sql.render.RenderedParameterInfo; +import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; + public abstract class AbstractSingleValueCondition<T> implements VisitableCondition<T> { protected final T value; @@ -30,11 +36,6 @@ public T value() { return value; } - @Override - public <R> R accept(ConditionVisitor<T, R> visitor) { - return visitor.visit(this); - } - protected <S extends AbstractSingleValueCondition<T>> S filterSupport(Predicate<? super T> predicate, Supplier<S> emptySupplier, S self) { if (isEmpty()) { @@ -64,4 +65,14 @@ protected <R, S extends AbstractSingleValueCondition<R>> S mapSupport(Function<? public abstract AbstractSingleValueCondition<T> filter(Predicate<? super T> predicate); public abstract String operator(); + + @Override + public FragmentAndParameters renderCondition(RenderingContext renderingContext, BindableColumn<T> leftColumn) { + RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo(leftColumn); + String finalFragment = operator() + spaceBefore(parameterInfo.renderedPlaceHolder()); + + return FragmentAndParameters.withFragment(finalFragment) + .withParameter(parameterInfo.parameterMapKey(), leftColumn.convertParameterType(value())) + .build(); + } } diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractSubselectCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractSubselectCondition.java index 4408f279c..3254fbd2d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractSubselectCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractSubselectCondition.java @@ -15,8 +15,11 @@ */ package org.mybatis.dynamic.sql; +import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.SelectModel; +import org.mybatis.dynamic.sql.select.render.SubQueryRenderer; import org.mybatis.dynamic.sql.util.Buildable; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; public abstract class AbstractSubselectCondition<T> implements VisitableCondition<T> { private final SelectModel selectModel; @@ -25,14 +28,15 @@ protected AbstractSubselectCondition(Buildable<SelectModel> selectModelBuilder) this.selectModel = selectModelBuilder.build(); } - public SelectModel selectModel() { - return selectModel; - } + public abstract String operator(); @Override - public <R> R accept(ConditionVisitor<T, R> visitor) { - return visitor.visit(this); + public FragmentAndParameters renderCondition(RenderingContext renderingContext, BindableColumn<T> leftColumn) { + return SubQueryRenderer.withSelectModel(selectModel) + .withRenderingContext(renderingContext) + .withPrefix(operator() + " (") //$NON-NLS-1$ + .withSuffix(")") //$NON-NLS-1$ + .build() + .render(); } - - public abstract String operator(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java index c36fe186d..fe34333a2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java @@ -15,12 +15,18 @@ */ package org.mybatis.dynamic.sql; +import static org.mybatis.dynamic.sql.util.StringUtilities.spaceBefore; + import java.util.function.BiFunction; import java.util.function.BiPredicate; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; +import org.mybatis.dynamic.sql.render.RenderedParameterInfo; +import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; + public abstract class AbstractTwoValueCondition<T> implements VisitableCondition<T> { protected final T value1; protected final T value2; @@ -38,11 +44,6 @@ public T value2() { return value2; } - @Override - public <R> R accept(ConditionVisitor<T, R> visitor) { - return visitor.visit(this); - } - protected <S extends AbstractTwoValueCondition<T>> S filterSupport(BiPredicate<? super T, ? super T> predicate, Supplier<S> emptySupplier, S self) { if (isEmpty()) { @@ -90,4 +91,20 @@ protected <R, S extends AbstractTwoValueCondition<R>> S mapSupport(Function<? su public abstract String operator1(); public abstract String operator2(); + + @Override + public FragmentAndParameters renderCondition(RenderingContext renderingContext, BindableColumn<T> leftColumn) { + RenderedParameterInfo parameterInfo1 = renderingContext.calculateParameterInfo(leftColumn); + RenderedParameterInfo parameterInfo2 = renderingContext.calculateParameterInfo(leftColumn); + + String finalFragment = operator1() + + spaceBefore(parameterInfo1.renderedPlaceHolder()) + + spaceBefore(operator2()) + + spaceBefore(parameterInfo2.renderedPlaceHolder()); + + return FragmentAndParameters.withFragment(finalFragment) + .withParameter(parameterInfo1.parameterMapKey(), leftColumn.convertParameterType(value1())) + .withParameter(parameterInfo2.parameterMapKey(), leftColumn.convertParameterType(value2())) + .build(); + } } diff --git a/src/main/java/org/mybatis/dynamic/sql/ConditionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/ConditionVisitor.java deleted file mode 100644 index 99a4fd36c..000000000 --- a/src/main/java/org/mybatis/dynamic/sql/ConditionVisitor.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2016-2025 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 - * - * https://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; - -public interface ConditionVisitor<T, R> { - R visit(AbstractListValueCondition<T> condition); - - R visit(AbstractNoValueCondition<T> condition); - - R visit(AbstractSingleValueCondition<T> condition); - - R visit(AbstractTwoValueCondition<T> condition); - - R visit(AbstractSubselectCondition<T> condition); - - R visit(AbstractColumnComparisonCondition<T> condition); -} diff --git a/src/main/java/org/mybatis/dynamic/sql/VisitableCondition.java b/src/main/java/org/mybatis/dynamic/sql/VisitableCondition.java index fc974b932..d201ae4dd 100644 --- a/src/main/java/org/mybatis/dynamic/sql/VisitableCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/VisitableCondition.java @@ -16,10 +16,17 @@ package org.mybatis.dynamic.sql; import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; @FunctionalInterface public interface VisitableCondition<T> { - <R> R accept(ConditionVisitor<T, R> visitor); + FragmentAndParameters renderCondition(RenderingContext renderingContext, BindableColumn<T> leftColumn); + + default FragmentAndParameters renderLeftColumn(RenderingContext renderingContext, BindableColumn<T> leftColumn) { + return leftColumn.alias() + .map(FragmentAndParameters::fromFragment) + .orElseGet(() -> leftColumn.render(renderingContext)); + } /** * Subclasses can override this to inform the renderer if the condition should not be included @@ -46,16 +53,4 @@ default boolean isEmpty() { * returns false. */ default void renderingSkipped() {} - - /** - * This method is called during rendering. Its purpose is to allow conditions to change - * the value of the rendered left column. This is primarily used in the case-insensitive conditions - * where we surround the rendered column with "upper(" and ")". - * - * @param renderedLeftColumn the rendered left column - * @return the altered column - by default no change is applied - */ - default String overrideRenderedLeftColumn(String renderedLeftColumn) { - return renderedLeftColumn; - } } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseWhenConditionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseWhenConditionRenderer.java index 702f1a0ad..cb13434d3 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseWhenConditionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseWhenConditionRenderer.java @@ -28,20 +28,14 @@ import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.FragmentCollector; import org.mybatis.dynamic.sql.util.Validator; -import org.mybatis.dynamic.sql.where.render.DefaultConditionVisitor; public class SimpleCaseWhenConditionRenderer<T> implements SimpleCaseWhenConditionVisitor<T, FragmentAndParameters> { private final RenderingContext renderingContext; private final BindableColumn<T> column; - private final DefaultConditionVisitor<T> conditionVisitor; public SimpleCaseWhenConditionRenderer(RenderingContext renderingContext, BindableColumn<T> column) { this.renderingContext = Objects.requireNonNull(renderingContext); this.column = Objects.requireNonNull(column); - conditionVisitor = new DefaultConditionVisitor.Builder<T>() - .withColumn(column) - .withRenderingContext(renderingContext) - .build(); } @Override @@ -68,7 +62,7 @@ private boolean shouldRender(VisitableCondition<T> condition) { } private FragmentAndParameters renderCondition(VisitableCondition<T> condition) { - return condition.accept(conditionVisitor); + return condition.renderCondition(renderingContext, column); } private FragmentAndParameters renderBasicValue(T value) { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveVisitableCondition.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveVisitableCondition.java index c0eef325a..9315b68fa 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveVisitableCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveVisitableCondition.java @@ -15,12 +15,17 @@ */ package org.mybatis.dynamic.sql.where.condition; +import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.VisitableCondition; +import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; public interface CaseInsensitiveVisitableCondition extends VisitableCondition<String> { @Override - default String overrideRenderedLeftColumn(String renderedLeftColumn) { - return "upper(" + renderedLeftColumn + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + default FragmentAndParameters renderLeftColumn(RenderingContext renderingContext, + BindableColumn<String> leftColumn) { + return VisitableCondition.super.renderLeftColumn(renderingContext, leftColumn) + .mapFragment(s -> "upper(" + s + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java index 6035c143b..d640c0796 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java @@ -29,31 +29,20 @@ public class ColumnAndConditionRenderer<T> { private final BindableColumn<T> column; private final VisitableCondition<T> condition; private final RenderingContext renderingContext; - private final DefaultConditionVisitor<T> visitor; private ColumnAndConditionRenderer(Builder<T> builder) { column = Objects.requireNonNull(builder.column); condition = Objects.requireNonNull(builder.condition); renderingContext = Objects.requireNonNull(builder.renderingContext); - visitor = DefaultConditionVisitor.withColumn(column) - .withRenderingContext(renderingContext) - .build(); } public FragmentAndParameters render() { FragmentCollector fc = new FragmentCollector(); - fc.add(renderLeftColumn()); - fc.add(condition.accept(visitor)); + fc.add(condition.renderLeftColumn(renderingContext, column)); + fc.add(condition.renderCondition(renderingContext, column)); return fc.toFragmentAndParameters(Collectors.joining(" ")); //$NON-NLS-1$ } - private FragmentAndParameters renderLeftColumn() { - return column.alias() - .map(FragmentAndParameters::fromFragment) - .orElseGet(() -> column.render(renderingContext)) - .mapFragment(condition::overrideRenderedLeftColumn); - } - public static class Builder<T> { private @Nullable BindableColumn<T> column; private @Nullable VisitableCondition<T> condition; diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java b/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java deleted file mode 100644 index 78bbc81e7..000000000 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/DefaultConditionVisitor.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2016-2025 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 - * - * https://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.where.render; - -import static org.mybatis.dynamic.sql.util.StringUtilities.spaceBefore; - -import java.util.Objects; -import java.util.stream.Collectors; - -import org.jspecify.annotations.Nullable; -import org.mybatis.dynamic.sql.AbstractColumnComparisonCondition; -import org.mybatis.dynamic.sql.AbstractListValueCondition; -import org.mybatis.dynamic.sql.AbstractNoValueCondition; -import org.mybatis.dynamic.sql.AbstractSingleValueCondition; -import org.mybatis.dynamic.sql.AbstractSubselectCondition; -import org.mybatis.dynamic.sql.AbstractTwoValueCondition; -import org.mybatis.dynamic.sql.BindableColumn; -import org.mybatis.dynamic.sql.ConditionVisitor; -import org.mybatis.dynamic.sql.render.RenderedParameterInfo; -import org.mybatis.dynamic.sql.render.RenderingContext; -import org.mybatis.dynamic.sql.select.render.SubQueryRenderer; -import org.mybatis.dynamic.sql.util.FragmentAndParameters; -import org.mybatis.dynamic.sql.util.FragmentCollector; - -public class DefaultConditionVisitor<T> implements ConditionVisitor<T, FragmentAndParameters> { - - private final BindableColumn<T> column; - private final RenderingContext renderingContext; - - private DefaultConditionVisitor(Builder<T> builder) { - column = Objects.requireNonNull(builder.column); - renderingContext = Objects.requireNonNull(builder.renderingContext); - } - - @Override - public FragmentAndParameters visit(AbstractListValueCondition<T> condition) { - return condition.values().map(this::toFragmentAndParameters) - .collect(FragmentCollector.collect()) - .toFragmentAndParameters(Collectors.joining(",", //$NON-NLS-1$ - condition.operator() + " (", ")")); //$NON-NLS-1$ //$NON-NLS-2$ - } - - @Override - public FragmentAndParameters visit(AbstractNoValueCondition<T> condition) { - return FragmentAndParameters.fromFragment(condition.operator()); - } - - @Override - public FragmentAndParameters visit(AbstractSingleValueCondition<T> condition) { - RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo(column); - String finalFragment = condition.operator() - + spaceBefore(parameterInfo.renderedPlaceHolder()); - - return FragmentAndParameters.withFragment(finalFragment) - .withParameter(parameterInfo.parameterMapKey(), convertValue(condition.value())) - .build(); - } - - @Override - public FragmentAndParameters visit(AbstractTwoValueCondition<T> condition) { - RenderedParameterInfo parameterInfo1 = renderingContext.calculateParameterInfo(column); - RenderedParameterInfo parameterInfo2 = renderingContext.calculateParameterInfo(column); - - String finalFragment = condition.operator1() - + spaceBefore(parameterInfo1.renderedPlaceHolder()) - + spaceBefore(condition.operator2()) - + spaceBefore(parameterInfo2.renderedPlaceHolder()); - - return FragmentAndParameters.withFragment(finalFragment) - .withParameter(parameterInfo1.parameterMapKey(), convertValue(condition.value1())) - .withParameter(parameterInfo2.parameterMapKey(), convertValue(condition.value2())) - .build(); - } - - @Override - public FragmentAndParameters visit(AbstractSubselectCondition<T> condition) { - return SubQueryRenderer.withSelectModel(condition.selectModel()) - .withRenderingContext(renderingContext) - .withPrefix(condition.operator() + " (") //$NON-NLS-1$ - .withSuffix(")") //$NON-NLS-1$ - .build() - .render(); - } - - @Override - public FragmentAndParameters visit(AbstractColumnComparisonCondition<T> condition) { - return condition.rightColumn().render(renderingContext) - .mapFragment(f -> condition.operator() + spaceBefore(f)); - } - - private @Nullable Object convertValue(T value) { - return column.convertParameterType(value); - } - - private FragmentAndParameters toFragmentAndParameters(T value) { - RenderedParameterInfo parameterInfo = renderingContext.calculateParameterInfo(column); - return FragmentAndParameters.withFragment(parameterInfo.renderedPlaceHolder()) - .withParameter(parameterInfo.parameterMapKey(), convertValue(value)) - .build(); - } - - public static <T> Builder<T> withColumn(BindableColumn<T> column) { - return new Builder<T>().withColumn(column); - } - - public static class Builder<T> { - private @Nullable BindableColumn<T> column; - private @Nullable RenderingContext renderingContext; - - public Builder<T> withColumn(BindableColumn<T> column) { - this.column = column; - return this; - } - - public Builder<T> withRenderingContext(RenderingContext renderingContext) { - this.renderingContext = renderingContext; - return this; - } - - public DefaultConditionVisitor<T> build() { - return new DefaultConditionVisitor<>(this); - } - } -} diff --git a/src/test/java/examples/mysql/IsLikeEscape.java b/src/test/java/examples/mysql/IsLikeEscape.java new file mode 100644 index 000000000..28e3045c2 --- /dev/null +++ b/src/test/java/examples/mysql/IsLikeEscape.java @@ -0,0 +1,71 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.mysql; + +import java.util.NoSuchElementException; +import java.util.function.Function; + +import org.jspecify.annotations.NullMarked; +import org.mybatis.dynamic.sql.BindableColumn; +import org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; +import org.mybatis.dynamic.sql.where.condition.IsLike; + +@NullMarked +public class IsLikeEscape<T> extends IsLike<T> { + private static final IsLikeEscape<?> EMPTY = new IsLikeEscape<Object>(-1, "") { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public boolean isEmpty() { + return true; + } + }; + + public static <T> IsLikeEscape<T> empty() { + @SuppressWarnings("unchecked") + IsLikeEscape<T> t = (IsLikeEscape<T>) EMPTY; + return t; + } + + private final String escapeString; + + protected IsLikeEscape(T value, String escapeString) { + super(value); + this.escapeString = escapeString; + } + + @Override + public FragmentAndParameters renderCondition(RenderingContext renderingContext, BindableColumn<T> leftColumn) { + return super.renderCondition(renderingContext, leftColumn).mapFragment(this::addEscape); + } + + private String addEscape(String s) { + return s + " ESCAPE '" + escapeString + "'"; + } + + @Override + public <R> IsLike<R> map(Function<? super T, ? extends R> mapper) { + return mapSupport(mapper, v -> new IsLikeEscape<>(v, escapeString), IsLikeEscape::empty); + } + + public static <T> IsLikeEscape<T> isLike(T value, String escapeString) { + return new IsLikeEscape<>(value, escapeString); + } +} diff --git a/src/test/java/examples/mysql/MySQLTest.java b/src/test/java/examples/mysql/MySQLTest.java index 54c43c34a..20dd9fd39 100644 --- a/src/test/java/examples/mysql/MySQLTest.java +++ b/src/test/java/examples/mysql/MySQLTest.java @@ -119,4 +119,25 @@ void testMemberOfAsFunction() { assertThat(rows.get(2)).containsOnly(entry("id", 3), entry("inList", 1L)); } } + + @Test + void testIsLikeEscape() { + try (SqlSession session = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = session.getMapper(CommonSelectMapper.class); + + SelectStatementProvider selectStatement = select(id, description) + .from(items) + .where(description, IsLikeEscape.isLike("Item 1%", "#").map(s -> s)) + .orderBy(id) + .build() + .render(RenderingStrategies.MYBATIS3); + + assertThat(selectStatement.getSelectStatement()) + .isEqualTo("select id, description from items where description like #{parameters.p1,jdbcType=VARCHAR} ESCAPE '#' order by id"); + + List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); + assertThat(rows).hasSize(11); + assertThat(rows.get(2)).containsOnly(entry("id", 11), entry("description", "Item 11")); + } + } } From 0cfecd75f30a46898b5cab77d566f436830f51b3 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 5 Mar 2025 15:53:31 -0500 Subject: [PATCH 191/260] Rename VisitableCondition to RenderableCondition Conditions are no longer rendered via a Visitor, so the new name makes more sense --- .../dynamic/sql/RenderableCondition.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/main/java/org/mybatis/dynamic/sql/RenderableCondition.java diff --git a/src/main/java/org/mybatis/dynamic/sql/RenderableCondition.java b/src/main/java/org/mybatis/dynamic/sql/RenderableCondition.java new file mode 100644 index 000000000..4ca7a17f2 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/RenderableCondition.java @@ -0,0 +1,56 @@ +/* + * Copyright 2016-2025 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 + * + * https://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 org.mybatis.dynamic.sql.render.RenderingContext; +import org.mybatis.dynamic.sql.util.FragmentAndParameters; + +@FunctionalInterface +public interface RenderableCondition<T> { + FragmentAndParameters renderCondition(RenderingContext renderingContext, BindableColumn<T> leftColumn); + + default FragmentAndParameters renderLeftColumn(RenderingContext renderingContext, BindableColumn<T> leftColumn) { + return leftColumn.alias() + .map(FragmentAndParameters::fromFragment) + .orElseGet(() -> leftColumn.render(renderingContext)); + } + + /** + * Subclasses can override this to inform the renderer if the condition should not be included + * in the rendered SQL. Typically, conditions will not render if they are empty. + * + * @return true if the condition should render. + */ + default boolean shouldRender(RenderingContext renderingContext) { + return !isEmpty(); + } + + /** + * Subclasses can override this to indicate whether the condition is considered empty. This is primarily used in + * map and filter operations - the map and filter functions will not be applied if the condition is empty. + * + * @return true if the condition is empty. + */ + default boolean isEmpty() { + return false; + } + + /** + * This method will be called during rendering when {@link RenderableCondition#shouldRender(RenderingContext)} + * returns false. + */ + default void renderingSkipped() {} +} From bc4becaebee9ba07ef3f525e9537e6cdf05e9aec Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 5 Mar 2025 15:54:21 -0500 Subject: [PATCH 192/260] Rename VisitableCondition to RenderableCondition Conditions are no longer rendered via a Visitor, so the new name makes more sense --- CHANGELOG.md | 4 ++ .../AbstractColumnComparisonCondition.java | 2 +- .../sql/AbstractListValueCondition.java | 2 +- .../dynamic/sql/AbstractNoValueCondition.java | 2 +- .../sql/AbstractSingleValueCondition.java | 2 +- .../sql/AbstractSubselectCondition.java | 2 +- .../sql/AbstractTwoValueCondition.java | 2 +- .../sql/ColumnAndConditionCriterion.java | 8 +-- .../org/mybatis/dynamic/sql/SqlBuilder.java | 20 +++---- .../dynamic/sql/VisitableCondition.java | 54 ++++++------------- .../common/AbstractBooleanExpressionDSL.java | 12 ++--- .../sql/select/AbstractHavingStarter.java | 6 +-- .../sql/select/QueryExpressionDSL.java | 11 ++-- .../dynamic/sql/select/aggregate/Sum.java | 6 +-- .../ConditionBasedWhenCondition.java | 8 +-- .../caseexpression/SearchedCaseDSL.java | 6 +-- .../select/caseexpression/SimpleCaseDSL.java | 16 +++--- .../SimpleCaseWhenConditionRenderer.java | 6 +-- .../sql/where/AbstractWhereStarter.java | 6 +-- .../CaseInsensitiveVisitableCondition.java | 6 +-- .../render/ColumnAndConditionRenderer.java | 8 +-- .../util/kotlin/GroupingCriteriaCollector.kt | 4 +- .../dynamic/sql/util/kotlin/JoinCollector.kt | 4 +- .../sql/util/kotlin/elements/CaseDSLs.kt | 4 +- .../sql/util/kotlin/elements/SqlElements.kt | 4 +- 25 files changed, 95 insertions(+), 110 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c12f44da..8b333e3ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -100,6 +100,10 @@ Runtime behavior changes: these concepts for different databases it simply adds known clauses to a generated SQL statement. You should always test to make sure these functions work in your target database. Currently, we support, and test, the options supported by PostgreSQL. +- Rendering for all the conditions (isEqualTo, etc.) has changed. This should be transparent to most users unless you + have coded a direct implementation of `VisitableCondition`. The change makes it easier to code custom conditions that + are not supported by the library out of the box. The statement renderers now call methods `renderCondition` and + `renderLeftColumn` that you can override to implement any rendering you need. ## Release 1.5.2 - June 3, 2024 diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractColumnComparisonCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractColumnComparisonCondition.java index 502025401..65e45aafe 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractColumnComparisonCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractColumnComparisonCondition.java @@ -20,7 +20,7 @@ import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -public abstract class AbstractColumnComparisonCondition<T> implements VisitableCondition<T> { +public abstract class AbstractColumnComparisonCondition<T> implements RenderableCondition<T> { protected final BasicColumn rightColumn; diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java index eeed434ab..23f48e6f4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java @@ -28,7 +28,7 @@ import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.FragmentCollector; -public abstract class AbstractListValueCondition<T> implements VisitableCondition<T> { +public abstract class AbstractListValueCondition<T> implements RenderableCondition<T> { protected final Collection<T> values; protected AbstractListValueCondition(Collection<T> values) { diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java index 02f6e25f4..c0e103baf 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java @@ -21,7 +21,7 @@ import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -public abstract class AbstractNoValueCondition<T> implements VisitableCondition<T> { +public abstract class AbstractNoValueCondition<T> implements RenderableCondition<T> { protected <S extends AbstractNoValueCondition<?>> S filterSupport(BooleanSupplier booleanSupplier, Supplier<S> emptySupplier, S self) { diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java index a361c4ed0..9c8248d02 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java @@ -25,7 +25,7 @@ import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -public abstract class AbstractSingleValueCondition<T> implements VisitableCondition<T> { +public abstract class AbstractSingleValueCondition<T> implements RenderableCondition<T> { protected final T value; protected AbstractSingleValueCondition(T value) { diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractSubselectCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractSubselectCondition.java index 3254fbd2d..dcfbd4b3c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractSubselectCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractSubselectCondition.java @@ -21,7 +21,7 @@ import org.mybatis.dynamic.sql.util.Buildable; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -public abstract class AbstractSubselectCondition<T> implements VisitableCondition<T> { +public abstract class AbstractSubselectCondition<T> implements RenderableCondition<T> { private final SelectModel selectModel; protected AbstractSubselectCondition(Buildable<SelectModel> selectModelBuilder) { diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java index fe34333a2..865f7db0b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java @@ -27,7 +27,7 @@ import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -public abstract class AbstractTwoValueCondition<T> implements VisitableCondition<T> { +public abstract class AbstractTwoValueCondition<T> implements RenderableCondition<T> { protected final T value1; protected final T value2; diff --git a/src/main/java/org/mybatis/dynamic/sql/ColumnAndConditionCriterion.java b/src/main/java/org/mybatis/dynamic/sql/ColumnAndConditionCriterion.java index 646e695c2..053c18f64 100644 --- a/src/main/java/org/mybatis/dynamic/sql/ColumnAndConditionCriterion.java +++ b/src/main/java/org/mybatis/dynamic/sql/ColumnAndConditionCriterion.java @@ -21,7 +21,7 @@ public class ColumnAndConditionCriterion<T> extends SqlCriterion { private final BindableColumn<T> column; - private final VisitableCondition<T> condition; + private final RenderableCondition<T> condition; private ColumnAndConditionCriterion(Builder<T> builder) { super(builder); @@ -33,7 +33,7 @@ public BindableColumn<T> column() { return column; } - public VisitableCondition<T> condition() { + public RenderableCondition<T> condition() { return condition; } @@ -48,14 +48,14 @@ public static <T> Builder<T> withColumn(BindableColumn<T> column) { public static class Builder<T> extends AbstractBuilder<Builder<T>> { private @Nullable BindableColumn<T> column; - private @Nullable VisitableCondition<T> condition; + private @Nullable RenderableCondition<T> condition; public Builder<T> withColumn(BindableColumn<T> column) { this.column = column; return this; } - public Builder<T> withCondition(VisitableCondition<T> condition) { + public Builder<T> withCondition(RenderableCondition<T> condition) { this.condition = condition; return this; } diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java index 8b36417fe..1e27db93d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java @@ -250,7 +250,7 @@ static WhereDSL.StandaloneWhereFinisher where() { return new WhereDSL().where(); } - static <T> WhereDSL.StandaloneWhereFinisher where(BindableColumn<T> column, VisitableCondition<T> condition, + static <T> WhereDSL.StandaloneWhereFinisher where(BindableColumn<T> column, RenderableCondition<T> condition, AndOrCriteriaGroup... subCriteria) { return new WhereDSL().where(column, condition, subCriteria); } @@ -263,7 +263,7 @@ static WhereDSL.StandaloneWhereFinisher where(ExistsPredicate existsPredicate, A return new WhereDSL().where(existsPredicate, subCriteria); } - static <T> HavingDSL.StandaloneHavingFinisher having(BindableColumn<T> column, VisitableCondition<T> condition, + static <T> HavingDSL.StandaloneHavingFinisher having(BindableColumn<T> column, RenderableCondition<T> condition, AndOrCriteriaGroup... subCriteria) { return new HavingDSL().having(column, condition, subCriteria); } @@ -273,12 +273,12 @@ static HavingDSL.StandaloneHavingFinisher having(SqlCriterion initialCriterion, } // where condition connectors - static <T> CriteriaGroup group(BindableColumn<T> column, VisitableCondition<T> condition, + static <T> CriteriaGroup group(BindableColumn<T> column, RenderableCondition<T> condition, AndOrCriteriaGroup... subCriteria) { return group(column, condition, Arrays.asList(subCriteria)); } - static <T> CriteriaGroup group(BindableColumn<T> column, VisitableCondition<T> condition, + static <T> CriteriaGroup group(BindableColumn<T> column, RenderableCondition<T> condition, List<AndOrCriteriaGroup> subCriteria) { return new CriteriaGroup.Builder() .withInitialCriterion(new ColumnAndConditionCriterion.Builder<T>().withColumn(column) @@ -316,12 +316,12 @@ static CriteriaGroup group(List<AndOrCriteriaGroup> subCriteria) { .build(); } - static <T> NotCriterion not(BindableColumn<T> column, VisitableCondition<T> condition, + static <T> NotCriterion not(BindableColumn<T> column, RenderableCondition<T> condition, AndOrCriteriaGroup... subCriteria) { return not(column, condition, Arrays.asList(subCriteria)); } - static <T> NotCriterion not(BindableColumn<T> column, VisitableCondition<T> condition, + static <T> NotCriterion not(BindableColumn<T> column, RenderableCondition<T> condition, List<AndOrCriteriaGroup> subCriteria) { return new NotCriterion.Builder() .withInitialCriterion(new ColumnAndConditionCriterion.Builder<T>().withColumn(column) @@ -359,7 +359,7 @@ static NotCriterion not(List<AndOrCriteriaGroup> subCriteria) { .build(); } - static <T> AndOrCriteriaGroup or(BindableColumn<T> column, VisitableCondition<T> condition, + static <T> AndOrCriteriaGroup or(BindableColumn<T> column, RenderableCondition<T> condition, AndOrCriteriaGroup... subCriteria) { return new AndOrCriteriaGroup.Builder() .withInitialCriterion(ColumnAndConditionCriterion.withColumn(column) @@ -394,7 +394,7 @@ static AndOrCriteriaGroup or(List<AndOrCriteriaGroup> subCriteria) { .build(); } - static <T> AndOrCriteriaGroup and(BindableColumn<T> column, VisitableCondition<T> condition, + static <T> AndOrCriteriaGroup and(BindableColumn<T> column, RenderableCondition<T> condition, AndOrCriteriaGroup... subCriteria) { return new AndOrCriteriaGroup.Builder() .withInitialCriterion(ColumnAndConditionCriterion.withColumn(column) @@ -430,7 +430,7 @@ static AndOrCriteriaGroup and(List<AndOrCriteriaGroup> subCriteria) { } // join support - static <T> ColumnAndConditionCriterion<T> on(BindableColumn<T> joinColumn, VisitableCondition<T> joinCondition) { + static <T> ColumnAndConditionCriterion<T> on(BindableColumn<T> joinColumn, RenderableCondition<T> joinCondition) { return ColumnAndConditionCriterion.withColumn(joinColumn) .withCondition(joinCondition) .build(); @@ -506,7 +506,7 @@ static Sum<Object> sum(BasicColumn column) { return Sum.of(column); } - static <T> Sum<T> sum(BindableColumn<T> column, VisitableCondition<T> condition) { + static <T> Sum<T> sum(BindableColumn<T> column, RenderableCondition<T> condition) { return Sum.of(column, condition); } diff --git a/src/main/java/org/mybatis/dynamic/sql/VisitableCondition.java b/src/main/java/org/mybatis/dynamic/sql/VisitableCondition.java index d201ae4dd..9969c3997 100644 --- a/src/main/java/org/mybatis/dynamic/sql/VisitableCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/VisitableCondition.java @@ -16,41 +16,21 @@ package org.mybatis.dynamic.sql; import org.mybatis.dynamic.sql.render.RenderingContext; -import org.mybatis.dynamic.sql.util.FragmentAndParameters; -@FunctionalInterface -public interface VisitableCondition<T> { - FragmentAndParameters renderCondition(RenderingContext renderingContext, BindableColumn<T> leftColumn); - - default FragmentAndParameters renderLeftColumn(RenderingContext renderingContext, BindableColumn<T> leftColumn) { - return leftColumn.alias() - .map(FragmentAndParameters::fromFragment) - .orElseGet(() -> leftColumn.render(renderingContext)); - } - - /** - * Subclasses can override this to inform the renderer if the condition should not be included - * in the rendered SQL. Typically, conditions will not render if they are empty. - * - * @return true if the condition should render. - */ - default boolean shouldRender(RenderingContext renderingContext) { - return !isEmpty(); - } - - /** - * Subclasses can override this to indicate whether the condition is considered empty. This is primarily used in - * map and filter operations - the map and filter functions will not be applied if the condition is empty. - * - * @return true if the condition is empty. - */ - default boolean isEmpty() { - return false; - } - - /** - * This method will be called during rendering when {@link VisitableCondition#shouldRender(RenderingContext)} - * returns false. - */ - default void renderingSkipped() {} -} +/** + * Deprecated interface. + * + * <p>Conditions are no longer rendered with a visitor, so the name is misleading. This change makes it far easier + * to implement custom conditions for functionality not supplied out of the box by the library. + * + * <p>If you created any direct implementations of this interface, you will need to change the rendering functions. + * The library now calls {@link RenderableCondition#renderCondition(RenderingContext, BindableColumn)} and + * {@link RenderableCondition#renderLeftColumn(RenderingContext, BindableColumn)} instead of the previous methods + * like <code>operator</code>, <code>value</code>, etc. Subclasses of the supplied abstract conditions should continue + * to function as before. + * + * @param <T> the Java type related to the column this condition relates to. Used primarily for compiler type checking + * @deprecated since 2.0.0. Please use {@link RenderableCondition} instead. + */ +@Deprecated(since = "2.0.0", forRemoval = true) +public interface VisitableCondition<T> extends RenderableCondition<T> { } diff --git a/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionDSL.java index c671b39a9..2f817fb5f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionDSL.java @@ -26,20 +26,20 @@ import org.mybatis.dynamic.sql.CriteriaGroup; import org.mybatis.dynamic.sql.ExistsCriterion; import org.mybatis.dynamic.sql.ExistsPredicate; +import org.mybatis.dynamic.sql.RenderableCondition; import org.mybatis.dynamic.sql.SqlCriterion; -import org.mybatis.dynamic.sql.VisitableCondition; import org.mybatis.dynamic.sql.util.Validator; public abstract class AbstractBooleanExpressionDSL<T extends AbstractBooleanExpressionDSL<T>> { private @Nullable SqlCriterion initialCriterion; protected final List<AndOrCriteriaGroup> subCriteria = new ArrayList<>(); - public <S> T and(BindableColumn<S> column, VisitableCondition<S> condition, + public <S> T and(BindableColumn<S> column, RenderableCondition<S> condition, AndOrCriteriaGroup... subCriteria) { return and(column, condition, Arrays.asList(subCriteria)); } - public <S> T and(BindableColumn<S> column, VisitableCondition<S> condition, + public <S> T and(BindableColumn<S> column, RenderableCondition<S> condition, List<AndOrCriteriaGroup> subCriteria) { addSubCriteria("and", buildCriterion(column, condition), subCriteria); //$NON-NLS-1$ return getThis(); @@ -68,12 +68,12 @@ public T and(List<AndOrCriteriaGroup> criteria) { return getThis(); } - public <S> T or(BindableColumn<S> column, VisitableCondition<S> condition, + public <S> T or(BindableColumn<S> column, RenderableCondition<S> condition, AndOrCriteriaGroup... subCriteria) { return or(column, condition, Arrays.asList(subCriteria)); } - public <S> T or(BindableColumn<S> column, VisitableCondition<S> condition, + public <S> T or(BindableColumn<S> column, RenderableCondition<S> condition, List<AndOrCriteriaGroup> subCriteria) { addSubCriteria("or", buildCriterion(column, condition), subCriteria); //$NON-NLS-1$ return getThis(); @@ -102,7 +102,7 @@ public T or(List<AndOrCriteriaGroup> criteria) { return getThis(); } - private <R> SqlCriterion buildCriterion(BindableColumn<R> column, VisitableCondition<R> condition) { + private <R> SqlCriterion buildCriterion(BindableColumn<R> column, RenderableCondition<R> condition) { return ColumnAndConditionCriterion.withColumn(column).withCondition(condition).build(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingStarter.java b/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingStarter.java index c8375bbd3..1090fb064 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingStarter.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/AbstractHavingStarter.java @@ -22,17 +22,17 @@ import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.ColumnAndConditionCriterion; import org.mybatis.dynamic.sql.CriteriaGroup; +import org.mybatis.dynamic.sql.RenderableCondition; import org.mybatis.dynamic.sql.SqlCriterion; -import org.mybatis.dynamic.sql.VisitableCondition; public interface AbstractHavingStarter<F extends AbstractHavingFinisher<?>> { - default <T> F having(BindableColumn<T> column, VisitableCondition<T> condition, + default <T> F having(BindableColumn<T> column, RenderableCondition<T> condition, AndOrCriteriaGroup... subCriteria) { return having(column, condition, Arrays.asList(subCriteria)); } - default <T> F having(BindableColumn<T> column, VisitableCondition<T> condition, + default <T> F having(BindableColumn<T> column, RenderableCondition<T> condition, List<AndOrCriteriaGroup> subCriteria) { SqlCriterion sqlCriterion = ColumnAndConditionCriterion.withColumn(column) .withCondition(condition) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java index b61f5e98a..70ad2617d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java @@ -28,10 +28,10 @@ import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.ColumnAndConditionCriterion; import org.mybatis.dynamic.sql.CriteriaGroup; +import org.mybatis.dynamic.sql.RenderableCondition; import org.mybatis.dynamic.sql.SortSpecification; import org.mybatis.dynamic.sql.SqlTable; import org.mybatis.dynamic.sql.TableExpression; -import org.mybatis.dynamic.sql.VisitableCondition; import org.mybatis.dynamic.sql.common.AbstractBooleanExpressionDSL; import org.mybatis.dynamic.sql.configuration.StatementConfiguration; import org.mybatis.dynamic.sql.select.join.JoinSpecification; @@ -324,11 +324,11 @@ public JoinSpecificationStarter(TableExpression joinTable, JoinType joinType) { this.joinType = joinType; } - public <T> JoinSpecificationFinisher on(BindableColumn<T> joinColumn, VisitableCondition<T> joinCondition) { + public <T> JoinSpecificationFinisher on(BindableColumn<T> joinColumn, RenderableCondition<T> joinCondition) { return new JoinSpecificationFinisher(joinTable, joinColumn, joinCondition, joinType); } - public <T> JoinSpecificationFinisher on(BindableColumn<T> joinColumn, VisitableCondition<T> onJoinCondition, + public <T> JoinSpecificationFinisher on(BindableColumn<T> joinColumn, RenderableCondition<T> onJoinCondition, AndOrCriteriaGroup... subCriteria) { return new JoinSpecificationFinisher(joinTable, joinColumn, onJoinCondition, joinType, subCriteria); } @@ -343,7 +343,7 @@ public class JoinSpecificationFinisher private final JoinType joinType; public <T> JoinSpecificationFinisher(TableExpression table, BindableColumn<T> joinColumn, - VisitableCondition<T> joinCondition, JoinType joinType) { + RenderableCondition<T> joinCondition, JoinType joinType) { this.table = table; this.joinType = joinType; addJoinSpecificationSupplier(this::buildJoinSpecification); @@ -356,7 +356,8 @@ public <T> JoinSpecificationFinisher(TableExpression table, BindableColumn<T> jo } public <T> JoinSpecificationFinisher(TableExpression table, BindableColumn<T> joinColumn, - VisitableCondition<T> joinCondition, JoinType joinType, AndOrCriteriaGroup... subCriteria) { + RenderableCondition<T> joinCondition, JoinType joinType, + AndOrCriteriaGroup... subCriteria) { this.table = table; this.joinType = joinType; addJoinSpecificationSupplier(this::buildJoinSpecification); diff --git a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Sum.java b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Sum.java index 6b9cd657e..7ccfd7854 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Sum.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/aggregate/Sum.java @@ -19,7 +19,7 @@ import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; -import org.mybatis.dynamic.sql.VisitableCondition; +import org.mybatis.dynamic.sql.RenderableCondition; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.function.AbstractUniTypeFunction; import org.mybatis.dynamic.sql.util.FragmentAndParameters; @@ -34,7 +34,7 @@ private Sum(BasicColumn column) { renderer = rc -> column.render(rc).mapFragment(this::applyAggregate); } - private Sum(BindableColumn<T> column, VisitableCondition<T> condition) { + private Sum(BindableColumn<T> column, RenderableCondition<T> condition) { super(column); renderer = rc -> { Validator.assertTrue(condition.shouldRender(rc), "ERROR.37", "sum"); //$NON-NLS-1$ //$NON-NLS-2$ @@ -76,7 +76,7 @@ public static Sum<Object> of(BasicColumn column) { return new Sum<>(column); } - public static <T> Sum<T> of(BindableColumn<T> column, VisitableCondition<T> condition) { + public static <T> Sum<T> of(BindableColumn<T> column, RenderableCondition<T> condition) { return new Sum<>(column, condition); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/ConditionBasedWhenCondition.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/ConditionBasedWhenCondition.java index fe3178bff..78f841b1d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/ConditionBasedWhenCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/ConditionBasedWhenCondition.java @@ -20,17 +20,17 @@ import java.util.stream.Stream; import org.mybatis.dynamic.sql.BasicColumn; -import org.mybatis.dynamic.sql.VisitableCondition; +import org.mybatis.dynamic.sql.RenderableCondition; public class ConditionBasedWhenCondition<T> extends SimpleCaseWhenCondition<T> { - private final List<VisitableCondition<T>> conditions = new ArrayList<>(); + private final List<RenderableCondition<T>> conditions = new ArrayList<>(); - public ConditionBasedWhenCondition(List<VisitableCondition<T>> conditions, BasicColumn thenValue) { + public ConditionBasedWhenCondition(List<RenderableCondition<T>> conditions, BasicColumn thenValue) { super(thenValue); this.conditions.addAll(conditions); } - public Stream<VisitableCondition<T>> conditions() { + public Stream<RenderableCondition<T>> conditions() { return conditions.stream(); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseDSL.java index 0c0c6ea87..c86bf7ff0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SearchedCaseDSL.java @@ -25,20 +25,20 @@ import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.ColumnAndConditionCriterion; import org.mybatis.dynamic.sql.CriteriaGroup; +import org.mybatis.dynamic.sql.RenderableCondition; import org.mybatis.dynamic.sql.SqlCriterion; -import org.mybatis.dynamic.sql.VisitableCondition; import org.mybatis.dynamic.sql.common.AbstractBooleanExpressionDSL; public class SearchedCaseDSL implements ElseDSL<SearchedCaseDSL.SearchedCaseEnder> { private final List<SearchedCaseWhenCondition> whenConditions = new ArrayList<>(); private @Nullable BasicColumn elseValue; - public <T> WhenDSL when(BindableColumn<T> column, VisitableCondition<T> condition, + public <T> WhenDSL when(BindableColumn<T> column, RenderableCondition<T> condition, AndOrCriteriaGroup... subCriteria) { return when(column, condition, Arrays.asList(subCriteria)); } - public <T> WhenDSL when(BindableColumn<T> column, VisitableCondition<T> condition, + public <T> WhenDSL when(BindableColumn<T> column, RenderableCondition<T> condition, List<AndOrCriteriaGroup> subCriteria) { SqlCriterion sqlCriterion = ColumnAndConditionCriterion.withColumn(column) .withCondition(condition) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseDSL.java b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseDSL.java index 488f20060..be2e1e908 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/caseexpression/SimpleCaseDSL.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; -import org.mybatis.dynamic.sql.VisitableCondition; +import org.mybatis.dynamic.sql.RenderableCondition; public class SimpleCaseDSL<T> implements ElseDSL<SimpleCaseDSL<T>.SimpleCaseEnder> { private final BindableColumn<T> column; @@ -35,13 +35,13 @@ private SimpleCaseDSL(BindableColumn<T> column) { } @SafeVarargs - public final ConditionBasedWhenFinisher when(VisitableCondition<T> condition, - VisitableCondition<T>... subsequentConditions) { + public final ConditionBasedWhenFinisher when(RenderableCondition<T> condition, + RenderableCondition<T>... subsequentConditions) { return when(condition, Arrays.asList(subsequentConditions)); } - public ConditionBasedWhenFinisher when(VisitableCondition<T> condition, - List<VisitableCondition<T>> subsequentConditions) { + public ConditionBasedWhenFinisher when(RenderableCondition<T> condition, + List<RenderableCondition<T>> subsequentConditions) { return new ConditionBasedWhenFinisher(condition, subsequentConditions); } @@ -70,10 +70,10 @@ public SimpleCaseModel<T> end() { } public class ConditionBasedWhenFinisher implements ThenDSL<SimpleCaseDSL<T>> { - private final List<VisitableCondition<T>> conditions = new ArrayList<>(); + private final List<RenderableCondition<T>> conditions = new ArrayList<>(); - private ConditionBasedWhenFinisher(VisitableCondition<T> condition, - List<VisitableCondition<T>> subsequentConditions) { + private ConditionBasedWhenFinisher(RenderableCondition<T> condition, + List<RenderableCondition<T>> subsequentConditions) { conditions.add(condition); conditions.addAll(subsequentConditions); } diff --git a/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseWhenConditionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseWhenConditionRenderer.java index cb13434d3..1bb6e2adc 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseWhenConditionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/render/SimpleCaseWhenConditionRenderer.java @@ -19,7 +19,7 @@ import java.util.stream.Collectors; import org.mybatis.dynamic.sql.BindableColumn; -import org.mybatis.dynamic.sql.VisitableCondition; +import org.mybatis.dynamic.sql.RenderableCondition; import org.mybatis.dynamic.sql.render.RenderedParameterInfo; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.caseexpression.BasicWhenCondition; @@ -57,11 +57,11 @@ public FragmentAndParameters visit(BasicWhenCondition<T> whenCondition) { .toFragmentAndParameters(Collectors.joining(", ")); //$NON-NLS-1$ } - private boolean shouldRender(VisitableCondition<T> condition) { + private boolean shouldRender(RenderableCondition<T> condition) { return condition.shouldRender(renderingContext); } - private FragmentAndParameters renderCondition(VisitableCondition<T> condition) { + private FragmentAndParameters renderCondition(RenderableCondition<T> condition) { return condition.renderCondition(renderingContext, column); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereStarter.java b/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereStarter.java index 3a037e5e9..17efa091e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereStarter.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/AbstractWhereStarter.java @@ -25,8 +25,8 @@ import org.mybatis.dynamic.sql.CriteriaGroup; import org.mybatis.dynamic.sql.ExistsCriterion; import org.mybatis.dynamic.sql.ExistsPredicate; +import org.mybatis.dynamic.sql.RenderableCondition; import org.mybatis.dynamic.sql.SqlCriterion; -import org.mybatis.dynamic.sql.VisitableCondition; import org.mybatis.dynamic.sql.util.ConfigurableStatement; /** @@ -39,11 +39,11 @@ public interface AbstractWhereStarter<F extends AbstractWhereFinisher<?>, D extends AbstractWhereStarter<F, D>> extends ConfigurableStatement<D> { - default <T> F where(BindableColumn<T> column, VisitableCondition<T> condition, AndOrCriteriaGroup... subCriteria) { + default <T> F where(BindableColumn<T> column, RenderableCondition<T> condition, AndOrCriteriaGroup... subCriteria) { return where(column, condition, Arrays.asList(subCriteria)); } - default <T> F where(BindableColumn<T> column, VisitableCondition<T> condition, + default <T> F where(BindableColumn<T> column, RenderableCondition<T> condition, List<AndOrCriteriaGroup> subCriteria) { SqlCriterion sqlCriterion = ColumnAndConditionCriterion.withColumn(column) .withCondition(condition) diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveVisitableCondition.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveVisitableCondition.java index 9315b68fa..9224ad594 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveVisitableCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveVisitableCondition.java @@ -16,16 +16,16 @@ package org.mybatis.dynamic.sql.where.condition; import org.mybatis.dynamic.sql.BindableColumn; -import org.mybatis.dynamic.sql.VisitableCondition; +import org.mybatis.dynamic.sql.RenderableCondition; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -public interface CaseInsensitiveVisitableCondition extends VisitableCondition<String> { +public interface CaseInsensitiveVisitableCondition extends RenderableCondition<String> { @Override default FragmentAndParameters renderLeftColumn(RenderingContext renderingContext, BindableColumn<String> leftColumn) { - return VisitableCondition.super.renderLeftColumn(renderingContext, leftColumn) + return RenderableCondition.super.renderLeftColumn(renderingContext, leftColumn) .mapFragment(s -> "upper(" + s + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java b/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java index d640c0796..c094bca1b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/render/ColumnAndConditionRenderer.java @@ -20,14 +20,14 @@ import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.BindableColumn; -import org.mybatis.dynamic.sql.VisitableCondition; +import org.mybatis.dynamic.sql.RenderableCondition; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; import org.mybatis.dynamic.sql.util.FragmentCollector; public class ColumnAndConditionRenderer<T> { private final BindableColumn<T> column; - private final VisitableCondition<T> condition; + private final RenderableCondition<T> condition; private final RenderingContext renderingContext; private ColumnAndConditionRenderer(Builder<T> builder) { @@ -45,7 +45,7 @@ public FragmentAndParameters render() { public static class Builder<T> { private @Nullable BindableColumn<T> column; - private @Nullable VisitableCondition<T> condition; + private @Nullable RenderableCondition<T> condition; private @Nullable RenderingContext renderingContext; public Builder<T> withColumn(BindableColumn<T> column) { @@ -53,7 +53,7 @@ public Builder<T> withColumn(BindableColumn<T> column) { return this; } - public Builder<T> withCondition(VisitableCondition<T> condition) { + public Builder<T> withCondition(RenderableCondition<T> condition) { this.condition = condition; return this; } diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/GroupingCriteriaCollector.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/GroupingCriteriaCollector.kt index 841539eeb..0aaaff460 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/GroupingCriteriaCollector.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/GroupingCriteriaCollector.kt @@ -22,9 +22,9 @@ import org.mybatis.dynamic.sql.ColumnAndConditionCriterion import org.mybatis.dynamic.sql.CriteriaGroup import org.mybatis.dynamic.sql.ExistsCriterion import org.mybatis.dynamic.sql.NotCriterion +import org.mybatis.dynamic.sql.RenderableCondition import org.mybatis.dynamic.sql.SqlBuilder import org.mybatis.dynamic.sql.SqlCriterion -import org.mybatis.dynamic.sql.VisitableCondition typealias GroupingCriteriaReceiver = GroupingCriteriaCollector.() -> Unit @@ -229,7 +229,7 @@ open class GroupingCriteriaCollector : SubCriteriaCollector() { * * @param condition the condition to be applied to this column, in this scope */ - operator fun <T : Any> BindableColumn<T>.invoke(condition: VisitableCondition<T>) { + operator fun <T : Any> BindableColumn<T>.invoke(condition: RenderableCondition<T>) { initialCriterion = ColumnAndConditionCriterion.withColumn(this) .withCondition(condition) .build() diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt index f85927682..c65b37a7a 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/JoinCollector.kt @@ -16,8 +16,8 @@ package org.mybatis.dynamic.sql.util.kotlin import org.mybatis.dynamic.sql.BindableColumn +import org.mybatis.dynamic.sql.RenderableCondition import org.mybatis.dynamic.sql.SqlBuilder -import org.mybatis.dynamic.sql.VisitableCondition typealias JoinReceiver = JoinCollector.() -> Unit @@ -38,7 +38,7 @@ class JoinCollector { } } -class RightColumnCollector<T : Any>(private val joinConditionConsumer: (VisitableCondition<T>) -> Unit) { +class RightColumnCollector<T : Any>(private val joinConditionConsumer: (RenderableCondition<T>) -> Unit) { infix fun equalTo(rightColumn: BindableColumn<T>) = joinConditionConsumer.invoke(SqlBuilder.isEqualTo(rightColumn)) infix fun equalTo(value: T) = joinConditionConsumer.invoke(SqlBuilder.isEqualTo(value)) diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CaseDSLs.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CaseDSLs.kt index bc04a992d..ce33f27b7 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CaseDSLs.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/CaseDSLs.kt @@ -16,7 +16,7 @@ package org.mybatis.dynamic.sql.util.kotlin.elements import org.mybatis.dynamic.sql.BasicColumn -import org.mybatis.dynamic.sql.VisitableCondition +import org.mybatis.dynamic.sql.RenderableCondition import org.mybatis.dynamic.sql.select.caseexpression.BasicWhenCondition import org.mybatis.dynamic.sql.select.caseexpression.ConditionBasedWhenCondition import org.mybatis.dynamic.sql.select.caseexpression.SearchedCaseWhenCondition @@ -67,7 +67,7 @@ class KSimpleCaseDSL<T : Any> : KElseDSL { } internal val whenConditions = mutableListOf<SimpleCaseWhenCondition<T>>() - fun `when`(vararg conditions: VisitableCondition<T>) = + fun `when`(vararg conditions: RenderableCondition<T>) = SimpleCaseThenGatherer { whenConditions.add(ConditionBasedWhenCondition(conditions.asList(), it)) } fun `when`(vararg values: T) = diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt index a7fe899d6..536032605 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt @@ -21,11 +21,11 @@ import org.mybatis.dynamic.sql.BasicColumn import org.mybatis.dynamic.sql.BindableColumn import org.mybatis.dynamic.sql.BoundValue import org.mybatis.dynamic.sql.Constant +import org.mybatis.dynamic.sql.RenderableCondition import org.mybatis.dynamic.sql.SortSpecification import org.mybatis.dynamic.sql.SqlBuilder import org.mybatis.dynamic.sql.SqlColumn import org.mybatis.dynamic.sql.StringConstant -import org.mybatis.dynamic.sql.VisitableCondition import org.mybatis.dynamic.sql.select.caseexpression.SearchedCaseModel import org.mybatis.dynamic.sql.select.caseexpression.SimpleCaseModel import org.mybatis.dynamic.sql.select.aggregate.Avg @@ -139,7 +139,7 @@ fun <T : Any> sum(column: BindableColumn<T>): Sum<T> = SqlBuilder.sum(column) fun sum(column: BasicColumn): Sum<*> = SqlBuilder.sum(column) -fun <T : Any> sum(column: BindableColumn<T>, condition: VisitableCondition<T>): Sum<T> = SqlBuilder.sum(column, condition) +fun <T : Any> sum(column: BindableColumn<T>, condition: RenderableCondition<T>): Sum<T> = SqlBuilder.sum(column, condition) // constants fun <T : Any> constant(constant: String): Constant<T> = SqlBuilder.constant(constant) From fd7d6e8206b69ce292647266c73916aab6d26c08 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 5 Mar 2025 16:35:34 -0500 Subject: [PATCH 193/260] Documentation --- src/site/markdown/docs/extending.md | 83 +++++++++++++++++++ .../java/examples/mysql/IsLikeEscape.java | 44 +++++++--- src/test/java/examples/mysql/MySQLTest.java | 2 +- 3 files changed, 116 insertions(+), 13 deletions(-) diff --git a/src/site/markdown/docs/extending.md b/src/site/markdown/docs/extending.md index a32dea137..eabee1e03 100644 --- a/src/site/markdown/docs/extending.md +++ b/src/site/markdown/docs/extending.md @@ -292,3 +292,86 @@ it. You can write your own rendering support if you are dissatisfied with the S Writing a custom renderer is quite complex. If you want to undertake that task, we suggest that you take the time to understand how the default renderers work first. Feel free to ask questions about this topic on the MyBatis mailing list. + +## Writing Custom Conditions + +The library supplies a full range of conditions for all the common SQL operators (=, !=, like, between, etc.) Some +databases support extensions to the standard operators. For example, MySQL supports an extension to the "LIKE" +condition - the "ESCAPE" clause. If you need to implement a condition like that, then you will need to code a +custom condition. + +Here's an example of implementing a LIKE condition that supports ESCAPE: + +```java +@NullMarked +public class IsLikeEscape<T> extends AbstractSingleValueCondition<T> { + private static final IsLikeEscape<?> EMPTY = new IsLikeEscape<Object>(-1, null) { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public boolean isEmpty() { + return true; + } + }; + + public static <T> IsLikeEscape<T> empty() { + @SuppressWarnings("unchecked") + IsLikeEscape<T> t = (IsLikeEscape<T>) EMPTY; + return t; + } + + private final @Nullable Character escapeCharacter; + + protected IsLikeEscape(T value, @Nullable Character escapeCharacter) { + super(value); + this.escapeCharacter = escapeCharacter; + } + + @Override + public String operator() { + return "like"; + } + + @Override + public FragmentAndParameters renderCondition(RenderingContext renderingContext, BindableColumn<T> leftColumn) { + var fragment = super.renderCondition(renderingContext, leftColumn); + if (escapeCharacter != null) { + fragment = fragment.mapFragment(this::addEscape); + } + + return fragment; + } + + private String addEscape(String s) { + return s + " ESCAPE '" + escapeCharacter + "'"; + } + + @Override + public IsLikeEscape<T> filter(Predicate<? super T> predicate) { + return filterSupport(predicate, IsLikeEscape::empty, this); + } + + public <R> IsLikeEscape<R> map(Function<? super T, ? extends R> mapper) { + return mapSupport(mapper, v -> new IsLikeEscape<>(v, escapeCharacter), IsLikeEscape::empty); + } + + public static <T> IsLikeEscape<T> isLike(T value) { + return new IsLikeEscape<>(value, null); + } + + public static <T> IsLikeEscape<T> isLike(T value, Character escapeCharacter) { + return new IsLikeEscape<>(value, escapeCharacter); + } +} +``` + +Important notes: + +1. The class extends `AbstractSingleValueCondition` - which is appropriate for like conditions +2. The class constructor accepts an escape character that will be rendered into an ESCAPE phrase +3. The class overrides `renderCondition` and changes the library generated `FragmentAndParameters` to add the ESCAPE + phrase. **This is the key to what's needed to implement a custom condition.** +4. The class provides `map` and `filter` functions as is expected for any condition in the library diff --git a/src/test/java/examples/mysql/IsLikeEscape.java b/src/test/java/examples/mysql/IsLikeEscape.java index 28e3045c2..19e1a085c 100644 --- a/src/test/java/examples/mysql/IsLikeEscape.java +++ b/src/test/java/examples/mysql/IsLikeEscape.java @@ -17,16 +17,18 @@ import java.util.NoSuchElementException; import java.util.function.Function; +import java.util.function.Predicate; import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; +import org.mybatis.dynamic.sql.AbstractSingleValueCondition; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -import org.mybatis.dynamic.sql.where.condition.IsLike; @NullMarked -public class IsLikeEscape<T> extends IsLike<T> { - private static final IsLikeEscape<?> EMPTY = new IsLikeEscape<Object>(-1, "") { +public class IsLikeEscape<T> extends AbstractSingleValueCondition<T> { + private static final IsLikeEscape<?> EMPTY = new IsLikeEscape<Object>(-1, null) { @Override public Object value() { throw new NoSuchElementException("No value present"); //$NON-NLS-1$ @@ -44,28 +46,46 @@ public static <T> IsLikeEscape<T> empty() { return t; } - private final String escapeString; + private final @Nullable Character escapeCharacter; - protected IsLikeEscape(T value, String escapeString) { + protected IsLikeEscape(T value, @Nullable Character escapeCharacter) { super(value); - this.escapeString = escapeString; + this.escapeCharacter = escapeCharacter; + } + + @Override + public String operator() { + return "like"; } @Override public FragmentAndParameters renderCondition(RenderingContext renderingContext, BindableColumn<T> leftColumn) { - return super.renderCondition(renderingContext, leftColumn).mapFragment(this::addEscape); + var fragment = super.renderCondition(renderingContext, leftColumn); + if (escapeCharacter != null) { + fragment = fragment.mapFragment(this::addEscape); + } + + return fragment; } private String addEscape(String s) { - return s + " ESCAPE '" + escapeString + "'"; + return s + " ESCAPE '" + escapeCharacter + "'"; } @Override - public <R> IsLike<R> map(Function<? super T, ? extends R> mapper) { - return mapSupport(mapper, v -> new IsLikeEscape<>(v, escapeString), IsLikeEscape::empty); + public IsLikeEscape<T> filter(Predicate<? super T> predicate) { + return filterSupport(predicate, IsLikeEscape::empty, this); + } + + public <R> IsLikeEscape<R> map(Function<? super T, ? extends R> mapper) { + return mapSupport(mapper, v -> new IsLikeEscape<>(v, escapeCharacter), IsLikeEscape::empty); + } + + public static <T> IsLikeEscape<T> isLike(T value) { + return new IsLikeEscape<>(value, null); } - public static <T> IsLikeEscape<T> isLike(T value, String escapeString) { - return new IsLikeEscape<>(value, escapeString); + public static <T> IsLikeEscape<T> isLike(T value, Character escapeCharacter) { + return new IsLikeEscape<>(value, escapeCharacter); } } diff --git a/src/test/java/examples/mysql/MySQLTest.java b/src/test/java/examples/mysql/MySQLTest.java index 20dd9fd39..45c403bd7 100644 --- a/src/test/java/examples/mysql/MySQLTest.java +++ b/src/test/java/examples/mysql/MySQLTest.java @@ -127,7 +127,7 @@ void testIsLikeEscape() { SelectStatementProvider selectStatement = select(id, description) .from(items) - .where(description, IsLikeEscape.isLike("Item 1%", "#").map(s -> s)) + .where(description, IsLikeEscape.isLike("Item 1%", '#').map(s -> s)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); From 7dd08ab95c4a9cbb51ccce39cfc93a0505cf5a2f Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 6 Mar 2025 09:33:24 -0500 Subject: [PATCH 194/260] Documentation --- .../dynamic/sql/RenderableCondition.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/main/java/org/mybatis/dynamic/sql/RenderableCondition.java b/src/main/java/org/mybatis/dynamic/sql/RenderableCondition.java index 4ca7a17f2..51dc912e8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/RenderableCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/RenderableCondition.java @@ -20,8 +20,33 @@ @FunctionalInterface public interface RenderableCondition<T> { + /** + * Render a condition - typically a condition in a WHERE clause. + * + * <p>A rendered condition includes an SQL fragment, and any associated parameters. For example, + * the <code>isEqual</code> condition should be rendered as "= ?" where "?" is a properly formatted + * parameter marker (the parameter marker can be computed from the <code>RenderingContext</code>). + * Note that a rendered condition should NOT include the left side of the phrase - that is rendered + * by the {@link RenderableCondition#renderLeftColumn(RenderingContext, BindableColumn)} method. + * + * @param renderingContext the current rendering context + * @param leftColumn the column related to this condition in a where clause + * @return the rendered condition. Should NOT include the column. + */ FragmentAndParameters renderCondition(RenderingContext renderingContext, BindableColumn<T> leftColumn); + /** + * Render the column in a column and condition phrase - typically in a WHERE clause. + * + * <p>By default, the column will be rendered as the column alias if it exists, or the column name. + * This can be complicated if the column has a table qualifier, or if the "column" is a function or + * part of a CASE expression. Columns know how to render themselves, so we just call their "render" + * methods. + * + * @param renderingContext the current rendering context + * @param leftColumn the column related to this condition in a where clause + * @return the rendered column + */ default FragmentAndParameters renderLeftColumn(RenderingContext renderingContext, BindableColumn<T> leftColumn) { return leftColumn.alias() .map(FragmentAndParameters::fromFragment) From 13fb0cf5d7bee7781ea85ce24f8c5ff68c223d14 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 6 Mar 2025 09:33:38 -0500 Subject: [PATCH 195/260] Convert to record --- .../dynamic/sql/render/RenderedParameterInfo.java | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/render/RenderedParameterInfo.java b/src/main/java/org/mybatis/dynamic/sql/render/RenderedParameterInfo.java index c1be974f5..5c8187ef2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/render/RenderedParameterInfo.java +++ b/src/main/java/org/mybatis/dynamic/sql/render/RenderedParameterInfo.java @@ -17,20 +17,9 @@ import java.util.Objects; -public class RenderedParameterInfo { - private final String parameterMapKey; - private final String renderedPlaceHolder; - +public record RenderedParameterInfo(String parameterMapKey, String renderedPlaceHolder) { public RenderedParameterInfo(String parameterMapKey, String renderedPlaceHolder) { this.parameterMapKey = Objects.requireNonNull(parameterMapKey); this.renderedPlaceHolder = Objects.requireNonNull(renderedPlaceHolder); } - - public String parameterMapKey() { - return parameterMapKey; - } - - public String renderedPlaceHolder() { - return renderedPlaceHolder; - } } From 1d4dbe1b5710fa81da865b4411832b8718469631 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 7 Mar 2025 09:40:55 -0500 Subject: [PATCH 196/260] Kotlin version of a custom condition --- .../kotlin/mybatis3/mariadb/KIsLikeEscape.kt | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt diff --git a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt new file mode 100644 index 000000000..454f47d96 --- /dev/null +++ b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt @@ -0,0 +1,44 @@ +package examples.kotlin.mybatis3.mariadb + +import org.mybatis.dynamic.sql.AbstractSingleValueCondition +import org.mybatis.dynamic.sql.BindableColumn +import org.mybatis.dynamic.sql.render.RenderingContext +import org.mybatis.dynamic.sql.util.FragmentAndParameters +import java.util.function.Predicate + +open class KIsLikeEscape<T : Any>(value: T, private val escapeCharacter: Char? = null) : AbstractSingleValueCondition<T>(value) { + + override fun operator(): String = "like" + + override fun renderCondition( + renderingContext: RenderingContext, + leftColumn: BindableColumn<T> + ): FragmentAndParameters { + val f = super.renderCondition(renderingContext, leftColumn) + + return escapeCharacter?.let { f.mapFragment{ "$it ESCAPE '$escapeCharacter'"} } ?: f + } + + override fun filter(predicate: Predicate<in T>): KIsLikeEscape<T> { + return filterSupport(predicate, ::empty, this) + } + + fun <R : Any> map(mapper : (T) -> R): KIsLikeEscape<R> { + return mapSupport(mapper, { r -> KIsLikeEscape(r, escapeCharacter) }, ::empty) + } + + private class EmptyCondition : KIsLikeEscape<Any>(-1) { + override fun isEmpty(): Boolean = true + + override fun value(): Any { + throw NoSuchElementException("No value present") //$NON-NLS-1$ + } + } + + companion object { + private val EMPTY: KIsLikeEscape<Any> = EmptyCondition() + + @Suppress("UNCHECKED_CAST") + fun <T : Any> empty(): KIsLikeEscape<T> = EMPTY as KIsLikeEscape<T> + } +} From 90ddb51e93948e90345f128b81e1619aa43efea2 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 7 Mar 2025 11:00:06 -0500 Subject: [PATCH 197/260] Example of a Custom Condition in Kotlin --- .../kotlin/mybatis3/mariadb/KIsLikeEscape.kt | 46 ++++++----- .../kotlin/mybatis3/mariadb/KMariaDBTest.kt | 77 +++++++++++++++++++ 2 files changed, 105 insertions(+), 18 deletions(-) diff --git a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt index 454f47d96..e018a8329 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt @@ -1,44 +1,54 @@ package examples.kotlin.mybatis3.mariadb +import java.util.function.Predicate +import java.util.function.Function import org.mybatis.dynamic.sql.AbstractSingleValueCondition import org.mybatis.dynamic.sql.BindableColumn import org.mybatis.dynamic.sql.render.RenderingContext import org.mybatis.dynamic.sql.util.FragmentAndParameters -import java.util.function.Predicate -open class KIsLikeEscape<T : Any>(value: T, private val escapeCharacter: Char? = null) : AbstractSingleValueCondition<T>(value) { +sealed class KIsLikeEscape<T : Any>( + value: T, + private val escapeCharacter: Char? = null +) : AbstractSingleValueCondition<T>(value) { override fun operator(): String = "like" override fun renderCondition( renderingContext: RenderingContext, leftColumn: BindableColumn<T> - ): FragmentAndParameters { - val f = super.renderCondition(renderingContext, leftColumn) - - return escapeCharacter?.let { f.mapFragment{ "$it ESCAPE '$escapeCharacter'"} } ?: f + ): FragmentAndParameters = with(super.renderCondition(renderingContext, leftColumn)) { + escapeCharacter?.let { mapFragment { "$it ESCAPE '$escapeCharacter'" } } ?: this } - override fun filter(predicate: Predicate<in T>): KIsLikeEscape<T> { - return filterSupport(predicate, ::empty, this) - } + override fun filter(predicate: Predicate<in T>): KIsLikeEscape<T> = + filterSupport(predicate, EmptyIsLikeEscape::empty, this) - fun <R : Any> map(mapper : (T) -> R): KIsLikeEscape<R> { - return mapSupport(mapper, { r -> KIsLikeEscape(r, escapeCharacter) }, ::empty) + fun <R : Any> map(mapper : Function<in T, out R>): KIsLikeEscape<R> = + mapSupport(mapper, { r -> ConcreteIsLikeEscape(r, escapeCharacter) }, EmptyIsLikeEscape::empty) + + companion object { + fun <T: Any> isLike(value: T, escapeCharacter: Char? = null) : KIsLikeEscape<T> = + ConcreteIsLikeEscape(value, escapeCharacter) } +} + +private class ConcreteIsLikeEscape<T: Any>( + value: T, + escapeCharacter: Char? = null +) : KIsLikeEscape<T>(value, escapeCharacter) - private class EmptyCondition : KIsLikeEscape<Any>(-1) { - override fun isEmpty(): Boolean = true +private class EmptyIsLikeEscape : KIsLikeEscape<Any>(-1) { + override fun isEmpty(): Boolean = true - override fun value(): Any { - throw NoSuchElementException("No value present") //$NON-NLS-1$ - } + override fun value(): Any { + throw NoSuchElementException("No value present") } companion object { - private val EMPTY: KIsLikeEscape<Any> = EmptyCondition() + private val EMPTY: KIsLikeEscape<Any> = EmptyIsLikeEscape() @Suppress("UNCHECKED_CAST") - fun <T : Any> empty(): KIsLikeEscape<T> = EMPTY as KIsLikeEscape<T> + internal fun <T : Any> empty(): KIsLikeEscape<T> = EMPTY as KIsLikeEscape<T> } } diff --git a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt index 8ce870c01..11593f2ac 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt @@ -38,6 +38,7 @@ import org.mybatis.dynamic.sql.util.mybatis3.CommonUpdateMapper import org.testcontainers.containers.MariaDBContainer import org.testcontainers.junit.jupiter.Container import org.testcontainers.junit.jupiter.Testcontainers +import java.util.* @Testcontainers @TestInstance(TestInstance.Lifecycle.PER_CLASS) @@ -142,6 +143,82 @@ class KMariaDBTest { } } + @Test + fun testIsLikeEscape() { + sqlSessionFactory.openSession().use { session -> + val mapper = session.getMapper(CommonSelectMapper::class.java) + val selectStatement = select(id, description) { + from(items) + where { + description(KIsLikeEscape.isLike("Item 1%", '#')) + } + } + + assertThat(selectStatement.selectStatement).isEqualTo("select id, description from items where description like #{parameters.p1,jdbcType=VARCHAR} ESCAPE '#'") + assertThat(selectStatement.parameters).containsEntry("p1", "Item 1%") + + val rows = mapper.selectManyMappedRows(selectStatement) + assertThat(rows).hasSize(11) + } + } + + @Test + fun testIsLikeEscapeNoEscapeCharacter() { + val selectStatement = select(id, description) { + from(items) + where { + description(KIsLikeEscape.isLike("%fred%")) + } + } + + assertThat(selectStatement.selectStatement).isEqualTo("select id, description from items where description like #{parameters.p1,jdbcType=VARCHAR}") + assertThat(selectStatement.parameters).containsEntry("p1", "%fred%") + } + + @Test + fun testIsLikeEscapeMap() { + val selectStatement = select(id, description) { + from(items) + where { + description(KIsLikeEscape.isLike("%fred%", '#').map { s -> s.uppercase(Locale.getDefault()) }) + } + } + + assertThat(selectStatement.selectStatement).isEqualTo("select id, description from items where description like #{parameters.p1,jdbcType=VARCHAR} ESCAPE '#'") + assertThat(selectStatement.parameters).containsEntry("p1", "%FRED%") + } + + @Test + fun testIsLikeEscapeFilter() { + val selectStatement = select(id, description) { + from(items) + where { + description(KIsLikeEscape.isLike("%fred%", '#').filter { _ -> false }) + } + configureStatement { isNonRenderingWhereClauseAllowed = true } + } + + assertThat(selectStatement.selectStatement).isEqualTo("select id, description from items") + assertThat(selectStatement.parameters).isEmpty() + } + + @Test + fun testIsLikeEscapeFilterMapFilter() { + val selectStatement = select(id, description) { + from(items) + where { + description(KIsLikeEscape.isLike("%fred%", '#') + .filter { _ -> true } + .map { s -> s.uppercase(Locale.getDefault()) } + .filter{_ -> false }) + } + configureStatement { isNonRenderingWhereClauseAllowed = true } + } + + assertThat(selectStatement.selectStatement).isEqualTo("select id, description from items") + assertThat(selectStatement.parameters).isEmpty() + } + companion object { @Container private val mariadb = MariaDBContainer(TestContainersConfiguration.MARIADB_LATEST) From 80e0d64ad0d5ee84dbf4e99579bf02251bbaa8b0 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 7 Mar 2025 11:03:14 -0500 Subject: [PATCH 198/260] Rename to match the super interface --- ...leCondition.java => CaseInsensitiveRenderableCondition.java} | 2 +- .../dynamic/sql/where/condition/IsInCaseInsensitive.java | 2 +- .../sql/where/condition/IsInCaseInsensitiveWhenPresent.java | 2 +- .../dynamic/sql/where/condition/IsLikeCaseInsensitive.java | 2 +- .../dynamic/sql/where/condition/IsNotInCaseInsensitive.java | 2 +- .../sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java | 2 +- .../dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) rename src/main/java/org/mybatis/dynamic/sql/where/condition/{CaseInsensitiveVisitableCondition.java => CaseInsensitiveRenderableCondition.java} (93%) diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveVisitableCondition.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveRenderableCondition.java similarity index 93% rename from src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveVisitableCondition.java rename to src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveRenderableCondition.java index 9224ad594..2c837c4c7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveVisitableCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveRenderableCondition.java @@ -20,7 +20,7 @@ import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -public interface CaseInsensitiveVisitableCondition extends RenderableCondition<String> { +public interface CaseInsensitiveRenderableCondition extends RenderableCondition<String> { @Override default FragmentAndParameters renderLeftColumn(RenderingContext renderingContext, diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java index 6f14406fa..67f37951e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java @@ -27,7 +27,7 @@ import org.mybatis.dynamic.sql.util.Validator; public class IsInCaseInsensitive extends AbstractListValueCondition<String> - implements CaseInsensitiveVisitableCondition { + implements CaseInsensitiveRenderableCondition { private static final IsInCaseInsensitive EMPTY = new IsInCaseInsensitive(Collections.emptyList()); public static IsInCaseInsensitive empty() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java index d366f0857..cff58415d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java @@ -27,7 +27,7 @@ import org.mybatis.dynamic.sql.util.Utilities; public class IsInCaseInsensitiveWhenPresent extends AbstractListValueCondition<String> - implements CaseInsensitiveVisitableCondition { + implements CaseInsensitiveRenderableCondition { private static final IsInCaseInsensitiveWhenPresent EMPTY = new IsInCaseInsensitiveWhenPresent(Collections.emptyList()); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java index ccf6699ee..4ebdb00fb 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java @@ -23,7 +23,7 @@ import org.mybatis.dynamic.sql.util.StringUtilities; public class IsLikeCaseInsensitive extends AbstractSingleValueCondition<String> - implements CaseInsensitiveVisitableCondition { + implements CaseInsensitiveRenderableCondition { private static final IsLikeCaseInsensitive EMPTY = new IsLikeCaseInsensitive("") { //$NON-NLS-1$ @Override public String value() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java index b4c1e96a7..f5f970c45 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java @@ -27,7 +27,7 @@ import org.mybatis.dynamic.sql.util.Validator; public class IsNotInCaseInsensitive extends AbstractListValueCondition<String> - implements CaseInsensitiveVisitableCondition { + implements CaseInsensitiveRenderableCondition { private static final IsNotInCaseInsensitive EMPTY = new IsNotInCaseInsensitive(Collections.emptyList()); public static IsNotInCaseInsensitive empty() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java index 5562b0ff4..a8873a7e4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java @@ -27,7 +27,7 @@ import org.mybatis.dynamic.sql.util.Utilities; public class IsNotInCaseInsensitiveWhenPresent extends AbstractListValueCondition<String> - implements CaseInsensitiveVisitableCondition { + implements CaseInsensitiveRenderableCondition { private static final IsNotInCaseInsensitiveWhenPresent EMPTY = new IsNotInCaseInsensitiveWhenPresent(Collections.emptyList()); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java index 5d9d8c3af..1fb6847c0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java @@ -23,7 +23,7 @@ import org.mybatis.dynamic.sql.util.StringUtilities; public class IsNotLikeCaseInsensitive extends AbstractSingleValueCondition<String> - implements CaseInsensitiveVisitableCondition { + implements CaseInsensitiveRenderableCondition { private static final IsNotLikeCaseInsensitive EMPTY = new IsNotLikeCaseInsensitive("") { //$NON-NLS-1$ @Override public String value() { From ff530c6d3dd7014a417289f227564fcc386cf988 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 7 Mar 2025 11:15:19 -0500 Subject: [PATCH 199/260] Add comment about Kotlin context parameters --- .../kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt index 11593f2ac..ee593404c 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt @@ -143,6 +143,10 @@ class KMariaDBTest { } } + // Note that the following example uses of KIsLikeEscape are a bit awkward and don't look as natural as the + // built-in conditions. We should be able to improve this once Kotlin implements the context parameters + // proposal (https://github.com/Kotlin/KEEP/issues/367) + @Test fun testIsLikeEscape() { sqlSessionFactory.openSession().use { session -> From 6694eba0403e8bacae901be0c2388c6ec7350c97 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 7 Mar 2025 11:29:26 -0500 Subject: [PATCH 200/260] Add comment about Kotlin context parameters --- .../util/kotlin/GroupingCriteriaCollector.kt | 4 ++-- .../kotlin/mybatis3/mariadb/KMariaDBTest.kt | 22 ++++++++++++------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/GroupingCriteriaCollector.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/GroupingCriteriaCollector.kt index 0aaaff460..be4ba72af 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/GroupingCriteriaCollector.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/GroupingCriteriaCollector.kt @@ -235,8 +235,8 @@ open class GroupingCriteriaCollector : SubCriteriaCollector() { .build() } - // infix functions...we may be able to rewrite these as extension functions once Kotlin solves the multiple - // receivers problem (https://youtrack.jetbrains.com/issue/KT-42435) + // infix functions...we may be able to rewrite these as extension functions once Kotlin implements the context + // parameters proposal (https://github.com/Kotlin/KEEP/issues/367) // conditions for all data types fun BindableColumn<*>.isNull() = invoke(org.mybatis.dynamic.sql.util.kotlin.elements.isNull()) diff --git a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt index ee593404c..fe1dd2906 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt @@ -143,9 +143,15 @@ class KMariaDBTest { } } - // Note that the following example uses of KIsLikeEscape are a bit awkward and don't look as natural as the - // built-in conditions. We should be able to improve this once Kotlin implements the context parameters - // proposal (https://github.com/Kotlin/KEEP/issues/367) + + /** + * Shortcut function for KIsLikeEscape + * + * Note that the following example uses of this function are a bit awkward and don't look as natural as the + * built-in conditions. We should be able to improve this once Kotlin implements the context parameters + * proposal (https://github.com/Kotlin/KEEP/issues/367) + */ + fun <T : Any> isLike(value: T, escapeCharacter: Char? = null) = KIsLikeEscape.isLike(value, escapeCharacter) @Test fun testIsLikeEscape() { @@ -154,7 +160,7 @@ class KMariaDBTest { val selectStatement = select(id, description) { from(items) where { - description(KIsLikeEscape.isLike("Item 1%", '#')) + description(isLike("Item 1%", '#')) } } @@ -171,7 +177,7 @@ class KMariaDBTest { val selectStatement = select(id, description) { from(items) where { - description(KIsLikeEscape.isLike("%fred%")) + description(isLike("%fred%")) } } @@ -184,7 +190,7 @@ class KMariaDBTest { val selectStatement = select(id, description) { from(items) where { - description(KIsLikeEscape.isLike("%fred%", '#').map { s -> s.uppercase(Locale.getDefault()) }) + description(isLike("%fred%", '#').map { s -> s.uppercase(Locale.getDefault()) }) } } @@ -197,7 +203,7 @@ class KMariaDBTest { val selectStatement = select(id, description) { from(items) where { - description(KIsLikeEscape.isLike("%fred%", '#').filter { _ -> false }) + description(isLike("%fred%", '#').filter { _ -> false }) } configureStatement { isNonRenderingWhereClauseAllowed = true } } @@ -211,7 +217,7 @@ class KMariaDBTest { val selectStatement = select(id, description) { from(items) where { - description(KIsLikeEscape.isLike("%fred%", '#') + description(isLike("%fred%", '#') .filter { _ -> true } .map { s -> s.uppercase(Locale.getDefault()) } .filter{_ -> false }) From 10fe79dbec366cc984a67610050b69240b44eeed Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 7 Mar 2025 11:31:06 -0500 Subject: [PATCH 201/260] Star import is not necessary --- .../kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt index fe1dd2906..28bf98a3b 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt @@ -38,7 +38,7 @@ import org.mybatis.dynamic.sql.util.mybatis3.CommonUpdateMapper import org.testcontainers.containers.MariaDBContainer import org.testcontainers.junit.jupiter.Container import org.testcontainers.junit.jupiter.Testcontainers -import java.util.* +import java.util.Locale @Testcontainers @TestInstance(TestInstance.Lifecycle.PER_CLASS) From 1da7647981bb2c00bb1cc0075f4b1a66d4aa4d52 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 13 Mar 2025 09:39:14 -0400 Subject: [PATCH 202/260] Define a map template method for single value --- .../sql/AbstractSingleValueCondition.java | 11 ++++++ .../org/mybatis/dynamic/sql/SqlBuilder.java | 17 +++++---- .../CaseInsensitiveRenderableCondition.java | 4 +- .../sql/where/condition/IsEqualTo.java | 10 +---- .../sql/where/condition/IsGreaterThan.java | 10 +---- .../condition/IsGreaterThanOrEqualTo.java | 10 +---- .../where/condition/IsInCaseInsensitive.java | 2 +- .../IsInCaseInsensitiveWhenPresent.java | 2 +- .../sql/where/condition/IsLessThan.java | 10 +---- .../where/condition/IsLessThanOrEqualTo.java | 10 +---- .../dynamic/sql/where/condition/IsLike.java | 10 +---- .../condition/IsLikeCaseInsensitive.java | 33 +++++++--------- .../sql/where/condition/IsNotEqualTo.java | 10 +---- .../condition/IsNotInCaseInsensitive.java | 2 +- .../IsNotInCaseInsensitiveWhenPresent.java | 2 +- .../sql/where/condition/IsNotLike.java | 13 +------ .../condition/IsNotLikeCaseInsensitive.java | 24 ++++++------ .../sql/util/kotlin/elements/SqlElements.kt | 8 ++-- .../java/examples/mysql/IsLikeEscape.java | 1 + .../sql/where/condition/FilterAndMapTest.java | 38 +++++++++---------- .../kotlin/mybatis3/mariadb/KIsLikeEscape.kt | 2 +- 21 files changed, 86 insertions(+), 143 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java index 9c8248d02..f032d64db 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java @@ -64,6 +64,17 @@ protected <R, S extends AbstractSingleValueCondition<R>> S mapSupport(Function<? */ public abstract AbstractSingleValueCondition<T> filter(Predicate<? super T> predicate); + /** + * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a + * condition that will not render (this). + * + * @param mapper a mapping function to apply to the value, if renderable + * @param <R> type of the new condition + * @return a new condition with the result of applying the mapper to the value of this condition, + * if renderable, otherwise a condition that will not render. + */ + public abstract <R> AbstractSingleValueCondition<R> map(Function<? super T, ? extends R> mapper); + public abstract String operator(); @Override diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java index 1e27db93d..8d462c698 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java @@ -882,35 +882,36 @@ static IsEqualTo<Boolean> isFalse() { } // conditions for strings only - static IsLikeCaseInsensitive isLikeCaseInsensitive(String value) { + static IsLikeCaseInsensitive<String> isLikeCaseInsensitive(String value) { return IsLikeCaseInsensitive.of(value); } - static IsLikeCaseInsensitive isLikeCaseInsensitive(Supplier<String> valueSupplier) { + static IsLikeCaseInsensitive<String> isLikeCaseInsensitive(Supplier<String> valueSupplier) { return isLikeCaseInsensitive(valueSupplier.get()); } - static IsLikeCaseInsensitive isLikeCaseInsensitiveWhenPresent(@Nullable String value) { + static IsLikeCaseInsensitive<String> isLikeCaseInsensitiveWhenPresent(@Nullable String value) { return value == null ? IsLikeCaseInsensitive.empty() : IsLikeCaseInsensitive.of(value); } - static IsLikeCaseInsensitive isLikeCaseInsensitiveWhenPresent(Supplier<@Nullable String> valueSupplier) { + static IsLikeCaseInsensitive<String> isLikeCaseInsensitiveWhenPresent(Supplier<@Nullable String> valueSupplier) { return isLikeCaseInsensitiveWhenPresent(valueSupplier.get()); } - static IsNotLikeCaseInsensitive isNotLikeCaseInsensitive(String value) { + static IsNotLikeCaseInsensitive<String> isNotLikeCaseInsensitive(String value) { return IsNotLikeCaseInsensitive.of(value); } - static IsNotLikeCaseInsensitive isNotLikeCaseInsensitive(Supplier<String> valueSupplier) { + static IsNotLikeCaseInsensitive<String> isNotLikeCaseInsensitive(Supplier<String> valueSupplier) { return isNotLikeCaseInsensitive(valueSupplier.get()); } - static IsNotLikeCaseInsensitive isNotLikeCaseInsensitiveWhenPresent(@Nullable String value) { + static IsNotLikeCaseInsensitive<String> isNotLikeCaseInsensitiveWhenPresent(@Nullable String value) { return value == null ? IsNotLikeCaseInsensitive.empty() : IsNotLikeCaseInsensitive.of(value); } - static IsNotLikeCaseInsensitive isNotLikeCaseInsensitiveWhenPresent(Supplier<@Nullable String> valueSupplier) { + static IsNotLikeCaseInsensitive<String> isNotLikeCaseInsensitiveWhenPresent( + Supplier<@Nullable String> valueSupplier) { return isNotLikeCaseInsensitiveWhenPresent(valueSupplier.get()); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveRenderableCondition.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveRenderableCondition.java index 2c837c4c7..977a0090b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveRenderableCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/CaseInsensitiveRenderableCondition.java @@ -20,11 +20,11 @@ import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -public interface CaseInsensitiveRenderableCondition extends RenderableCondition<String> { +public interface CaseInsensitiveRenderableCondition<T> extends RenderableCondition<T> { @Override default FragmentAndParameters renderLeftColumn(RenderingContext renderingContext, - BindableColumn<String> leftColumn) { + BindableColumn<T> leftColumn) { return RenderableCondition.super.renderLeftColumn(renderingContext, leftColumn) .mapFragment(s -> "upper(" + s + ")"); //$NON-NLS-1$ //$NON-NLS-2$ } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java index 0a4b19207..17fe9eef1 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java @@ -59,15 +59,7 @@ public IsEqualTo<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsEqualTo::empty, this); } - /** - * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a - * condition that will not render (this). - * - * @param mapper a mapping function to apply to the value, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mapper to the value of this condition, - * if renderable, otherwise a condition that will not render. - */ + @Override public <R> IsEqualTo<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsEqualTo::new, IsEqualTo::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java index a0ed1a2bc..2b3162e1a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java @@ -58,15 +58,7 @@ public IsGreaterThan<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsGreaterThan::empty, this); } - /** - * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a - * condition that will not render (this). - * - * @param mapper a mapping function to apply to the value, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mapper to the value of this condition, - * if renderable, otherwise a condition that will not render. - */ + @Override public <R> IsGreaterThan<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsGreaterThan::new, IsGreaterThan::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java index 59560339b..7439ae4a8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java @@ -58,15 +58,7 @@ public IsGreaterThanOrEqualTo<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsGreaterThanOrEqualTo::empty, this); } - /** - * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a - * condition that will not render (this). - * - * @param mapper a mapping function to apply to the value, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mapper to the value of this condition, - * if renderable, otherwise a condition that will not render. - */ + @Override public <R> IsGreaterThanOrEqualTo<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsGreaterThanOrEqualTo::new, IsGreaterThanOrEqualTo::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java index 67f37951e..8fdf172bd 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java @@ -27,7 +27,7 @@ import org.mybatis.dynamic.sql.util.Validator; public class IsInCaseInsensitive extends AbstractListValueCondition<String> - implements CaseInsensitiveRenderableCondition { + implements CaseInsensitiveRenderableCondition<String> { private static final IsInCaseInsensitive EMPTY = new IsInCaseInsensitive(Collections.emptyList()); public static IsInCaseInsensitive empty() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java index cff58415d..91b77901a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java @@ -27,7 +27,7 @@ import org.mybatis.dynamic.sql.util.Utilities; public class IsInCaseInsensitiveWhenPresent extends AbstractListValueCondition<String> - implements CaseInsensitiveRenderableCondition { + implements CaseInsensitiveRenderableCondition<String> { private static final IsInCaseInsensitiveWhenPresent EMPTY = new IsInCaseInsensitiveWhenPresent(Collections.emptyList()); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java index 09e2e7ba6..01614d6dc 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java @@ -58,15 +58,7 @@ public IsLessThan<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsLessThan::empty, this); } - /** - * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a - * condition that will not render (this). - * - * @param mapper a mapping function to apply to the value, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mapper to the value of this condition, - * if renderable, otherwise a condition that will not render. - */ + @Override public <R> IsLessThan<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsLessThan::new, IsLessThan::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java index b11d06c88..20c3ed460 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java @@ -58,15 +58,7 @@ public IsLessThanOrEqualTo<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsLessThanOrEqualTo::empty, this); } - /** - * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a - * condition that will not render (this). - * - * @param mapper a mapping function to apply to the value, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mapper to the value of this condition, - * if renderable, otherwise a condition that will not render. - */ + @Override public <R> IsLessThanOrEqualTo<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsLessThanOrEqualTo::new, IsLessThanOrEqualTo::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java index 9d79bed81..5c7ba967a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java @@ -58,15 +58,7 @@ public IsLike<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsLike::empty, this); } - /** - * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a - * condition that will not render (this). - * - * @param mapper a mapping function to apply to the value, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mapper to the value of this condition, - * if renderable, otherwise a condition that will not render. - */ + @Override public <R> IsLike<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsLike::new, IsLike::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java index 4ebdb00fb..921903d01 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java @@ -16,15 +16,15 @@ package org.mybatis.dynamic.sql.where.condition; import java.util.NoSuchElementException; +import java.util.function.Function; import java.util.function.Predicate; -import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; -public class IsLikeCaseInsensitive extends AbstractSingleValueCondition<String> - implements CaseInsensitiveRenderableCondition { - private static final IsLikeCaseInsensitive EMPTY = new IsLikeCaseInsensitive("") { //$NON-NLS-1$ +public class IsLikeCaseInsensitive<T> extends AbstractSingleValueCondition<T> + implements CaseInsensitiveRenderableCondition<T> { + private static final IsLikeCaseInsensitive<?> EMPTY = new IsLikeCaseInsensitive<>("") { //$NON-NLS-1$ @Override public String value() { throw new NoSuchElementException("No value present"); //$NON-NLS-1$ @@ -36,11 +36,13 @@ public boolean isEmpty() { } }; - public static IsLikeCaseInsensitive empty() { - return EMPTY; + public static <T> IsLikeCaseInsensitive<T> empty() { + @SuppressWarnings("unchecked") + IsLikeCaseInsensitive<T> t = (IsLikeCaseInsensitive<T>) EMPTY; + return t; } - protected IsLikeCaseInsensitive(String value) { + protected IsLikeCaseInsensitive(T value) { super(value); } @@ -50,25 +52,18 @@ public String operator() { } @Override - public IsLikeCaseInsensitive filter(Predicate<? super String> predicate) { + public IsLikeCaseInsensitive<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsLikeCaseInsensitive::empty, this); } - /** - * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a - * condition that will not render (this). - * - * @param mapper a mapping function to apply to the value, if renderable - * @return a new condition with the result of applying the mapper to the value of this condition, - * if renderable, otherwise a condition that will not render. - */ - public IsLikeCaseInsensitive map(UnaryOperator<String> mapper) { + @Override + public <R> IsLikeCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsLikeCaseInsensitive::new, IsLikeCaseInsensitive::empty); } - public static IsLikeCaseInsensitive of(String value) { + public static IsLikeCaseInsensitive<String> of(String value) { // Keep the null safe upper case utility for backwards compatibility //noinspection DataFlowIssue - return new IsLikeCaseInsensitive(value).map(StringUtilities::safelyUpperCase); + return new IsLikeCaseInsensitive<>(value).map(StringUtilities::safelyUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java index 821fd019f..e52ab0385 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java @@ -58,15 +58,7 @@ public IsNotEqualTo<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsNotEqualTo::empty, this); } - /** - * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a - * condition that will not render (this). - * - * @param mapper a mapping function to apply to the value, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mapper to the value of this condition, - * if renderable, otherwise a condition that will not render. - */ + @Override public <R> IsNotEqualTo<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsNotEqualTo::new, IsNotEqualTo::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java index f5f970c45..473b9077e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java @@ -27,7 +27,7 @@ import org.mybatis.dynamic.sql.util.Validator; public class IsNotInCaseInsensitive extends AbstractListValueCondition<String> - implements CaseInsensitiveRenderableCondition { + implements CaseInsensitiveRenderableCondition<String> { private static final IsNotInCaseInsensitive EMPTY = new IsNotInCaseInsensitive(Collections.emptyList()); public static IsNotInCaseInsensitive empty() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java index a8873a7e4..b2d834f2b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java @@ -27,7 +27,7 @@ import org.mybatis.dynamic.sql.util.Utilities; public class IsNotInCaseInsensitiveWhenPresent extends AbstractListValueCondition<String> - implements CaseInsensitiveRenderableCondition { + implements CaseInsensitiveRenderableCondition<String> { private static final IsNotInCaseInsensitiveWhenPresent EMPTY = new IsNotInCaseInsensitiveWhenPresent(Collections.emptyList()); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java index 7379a316b..a2cf60310 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java @@ -58,18 +58,7 @@ public IsNotLike<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsNotLike::empty, this); } - /** - * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a - * condition that will not render (this). - * - * @param mapper - * a mapping function to apply to the value, if renderable - * @param <R> - * type of the new condition - * - * @return a new condition with the result of applying the mapper to the value of this condition, if renderable, - * otherwise a condition that will not render. - */ + @Override public <R> IsNotLike<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsNotLike::new, IsNotLike::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java index 1fb6847c0..4b3604165 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java @@ -16,15 +16,15 @@ package org.mybatis.dynamic.sql.where.condition; import java.util.NoSuchElementException; +import java.util.function.Function; import java.util.function.Predicate; -import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; -public class IsNotLikeCaseInsensitive extends AbstractSingleValueCondition<String> - implements CaseInsensitiveRenderableCondition { - private static final IsNotLikeCaseInsensitive EMPTY = new IsNotLikeCaseInsensitive("") { //$NON-NLS-1$ +public class IsNotLikeCaseInsensitive<T> extends AbstractSingleValueCondition<T> + implements CaseInsensitiveRenderableCondition<T> { + private static final IsNotLikeCaseInsensitive<?> EMPTY = new IsNotLikeCaseInsensitive<>("") { //$NON-NLS-1$ @Override public String value() { throw new NoSuchElementException("No value present"); //$NON-NLS-1$ @@ -36,11 +36,13 @@ public boolean isEmpty() { } }; - public static IsNotLikeCaseInsensitive empty() { - return EMPTY; + public static <T> IsNotLikeCaseInsensitive<T> empty() { + @SuppressWarnings("unchecked") + IsNotLikeCaseInsensitive<T> t = (IsNotLikeCaseInsensitive<T>) EMPTY; + return t; } - protected IsNotLikeCaseInsensitive(String value) { + protected IsNotLikeCaseInsensitive(T value) { super(value); } @@ -50,7 +52,7 @@ public String operator() { } @Override - public IsNotLikeCaseInsensitive filter(Predicate<? super String> predicate) { + public IsNotLikeCaseInsensitive<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsNotLikeCaseInsensitive::empty, this); } @@ -64,13 +66,13 @@ public IsNotLikeCaseInsensitive filter(Predicate<? super String> predicate) { * @return a new condition with the result of applying the mapper to the value of this condition, if renderable, * otherwise a condition that will not render. */ - public IsNotLikeCaseInsensitive map(UnaryOperator<String> mapper) { + public <R> IsNotLikeCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsNotLikeCaseInsensitive::new, IsNotLikeCaseInsensitive::empty); } - public static IsNotLikeCaseInsensitive of(String value) { + public static IsNotLikeCaseInsensitive<String> of(String value) { // Keep the null safe upper case utility for backwards compatibility //noinspection DataFlowIssue - return new IsNotLikeCaseInsensitive(value).map(StringUtilities::safelyUpperCase); + return new IsNotLikeCaseInsensitive<>(value).map(StringUtilities::safelyUpperCase); } } diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt index 536032605..0983eaa9c 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt @@ -324,14 +324,14 @@ fun isTrue(): IsEqualTo<Boolean> = isEqualTo(true) fun isFalse(): IsEqualTo<Boolean> = isEqualTo(false) // conditions for strings only -fun isLikeCaseInsensitive(value: String): IsLikeCaseInsensitive = SqlBuilder.isLikeCaseInsensitive(value) +fun isLikeCaseInsensitive(value: String): IsLikeCaseInsensitive<String> = SqlBuilder.isLikeCaseInsensitive(value) -fun isLikeCaseInsensitiveWhenPresent(value: String?): IsLikeCaseInsensitive = +fun isLikeCaseInsensitiveWhenPresent(value: String?): IsLikeCaseInsensitive<String> = SqlBuilder.isLikeCaseInsensitiveWhenPresent(value) -fun isNotLikeCaseInsensitive(value: String): IsNotLikeCaseInsensitive = SqlBuilder.isNotLikeCaseInsensitive(value) +fun isNotLikeCaseInsensitive(value: String): IsNotLikeCaseInsensitive<String> = SqlBuilder.isNotLikeCaseInsensitive(value) -fun isNotLikeCaseInsensitiveWhenPresent(value: String?): IsNotLikeCaseInsensitive = +fun isNotLikeCaseInsensitiveWhenPresent(value: String?): IsNotLikeCaseInsensitive<String> = SqlBuilder.isNotLikeCaseInsensitiveWhenPresent(value) fun isInCaseInsensitive(vararg values: String): IsInCaseInsensitive = isInCaseInsensitive(values.asList()) diff --git a/src/test/java/examples/mysql/IsLikeEscape.java b/src/test/java/examples/mysql/IsLikeEscape.java index 19e1a085c..21b43fa13 100644 --- a/src/test/java/examples/mysql/IsLikeEscape.java +++ b/src/test/java/examples/mysql/IsLikeEscape.java @@ -77,6 +77,7 @@ public IsLikeEscape<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsLikeEscape::empty, this); } + @Override public <R> IsLikeEscape<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, v -> new IsLikeEscape<>(v, escapeCharacter), IsLikeEscape::empty); } diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java index bd5f2e2cd..358ec0cd3 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java @@ -28,14 +28,14 @@ class FilterAndMapTest { @Test void testTypeConversion() { - IsEqualTo<Integer> cond = SqlBuilder.isEqualTo("1").map(Integer::parseInt); + var cond = SqlBuilder.isEqualTo("1").map(Integer::parseInt); assertThat(cond.isEmpty()).isFalse(); assertThat(cond.value()).isEqualTo(1); } @Test void testTypeConversionWithNullThrowsException() { - IsEqualTo<String> cond = SqlBuilder.isEqualTo((String) null); + var cond = SqlBuilder.isEqualTo((String) null); assertThatExceptionOfType(NumberFormatException.class).isThrownBy(() -> cond.map(Integer::parseInt) ); @@ -43,7 +43,7 @@ void testTypeConversionWithNullThrowsException() { @Test void testTypeConversionWithNullAndFilterDoesNotThrowException() { - IsEqualTo<Integer> cond = SqlBuilder.isEqualTo((String) null).filter(Objects::nonNull).map(Integer::parseInt); + var cond = SqlBuilder.isEqualTo((String) null).filter(Objects::nonNull).map(Integer::parseInt); assertThat(cond.isEmpty()).isTrue(); } @@ -328,8 +328,8 @@ void testIsLikeMapUnRenderableShouldNotThrowNullPointerException() { @Test void testIsLikeCaseInsensitiveRenderableTruePredicateShouldReturnSameObject() { - IsLikeCaseInsensitive cond = SqlBuilder.isLikeCaseInsensitive("Fred"); - IsLikeCaseInsensitive filtered = cond.filter(s -> true); + var cond = SqlBuilder.isLikeCaseInsensitive("Fred"); + var filtered = cond.filter(s -> true); assertThat(filtered.value()).isEqualTo("FRED"); assertThat(filtered.isEmpty()).isFalse(); assertThat(cond).isSameAs(filtered); @@ -337,24 +337,24 @@ void testIsLikeCaseInsensitiveRenderableTruePredicateShouldReturnSameObject() { @Test void testIsLikeCaseInsensitiveRenderableFalsePredicate() { - IsLikeCaseInsensitive cond = SqlBuilder.isLikeCaseInsensitive("Fred"); - IsLikeCaseInsensitive filtered = cond.filter(s -> false); + var cond = SqlBuilder.isLikeCaseInsensitive("Fred"); + var filtered = cond.filter(s -> false); assertThat(cond.isEmpty()).isFalse(); assertThat(filtered.isEmpty()).isTrue(); } @Test void testIsLikeCaseInsensitiveFilterUnRenderableShouldReturnSameObject() { - IsLikeCaseInsensitive cond = SqlBuilder.isLikeCaseInsensitive("Fred").filter(s -> false); - IsLikeCaseInsensitive filtered = cond.filter(s -> true); + var cond = SqlBuilder.isLikeCaseInsensitive("Fred").filter(s -> false); + var filtered = cond.filter(s -> true); assertThat(filtered.isEmpty()).isTrue(); assertThat(cond).isSameAs(filtered); } @Test void testIsLikeCaseInsensitiveMapUnRenderableShouldNotThrowNullPointerException() { - IsLikeCaseInsensitive cond = SqlBuilder.isLikeCaseInsensitive("Fred").filter(s -> false); - IsLikeCaseInsensitive mapped = cond.map(String::toUpperCase); + IsLikeCaseInsensitive<String> cond = SqlBuilder.isLikeCaseInsensitive("Fred").filter(s -> false); + IsLikeCaseInsensitive<String> mapped = cond.map(String::toUpperCase); assertThat(cond.isEmpty()).isTrue(); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond).isSameAs(mapped); @@ -395,8 +395,8 @@ void testIsNotLikeMapUnRenderableShouldNotThrowNullPointerException() { @Test void testIsNotLikeCaseInsensitiveRenderableTruePredicateShouldReturnSameObject() { - IsNotLikeCaseInsensitive cond = SqlBuilder.isNotLikeCaseInsensitive("Fred"); - IsNotLikeCaseInsensitive filtered = cond.filter(s -> true); + var cond = SqlBuilder.isNotLikeCaseInsensitive("Fred"); + var filtered = cond.filter(s -> true); assertThat(filtered.value()).isEqualTo("FRED"); assertThat(filtered.isEmpty()).isFalse(); assertThat(cond).isSameAs(filtered); @@ -404,24 +404,24 @@ void testIsNotLikeCaseInsensitiveRenderableTruePredicateShouldReturnSameObject() @Test void testIsNotLikeCaseInsensitiveRenderableFalsePredicate() { - IsNotLikeCaseInsensitive cond = SqlBuilder.isNotLikeCaseInsensitive("Fred"); - IsNotLikeCaseInsensitive filtered = cond.filter(s -> false); + var cond = SqlBuilder.isNotLikeCaseInsensitive("Fred"); + var filtered = cond.filter(s -> false); assertThat(cond.isEmpty()).isFalse(); assertThat(filtered.isEmpty()).isTrue(); } @Test void testIsNotLikeCaseInsensitiveFilterUnRenderableShouldReturnSameObject() { - IsNotLikeCaseInsensitive cond = SqlBuilder.isNotLikeCaseInsensitive("Fred").filter(s -> false); - IsNotLikeCaseInsensitive filtered = cond.filter(s -> true); + var cond = SqlBuilder.isNotLikeCaseInsensitive("Fred").filter(s -> false); + var filtered = cond.filter(s -> true); assertThat(filtered.isEmpty()).isTrue(); assertThat(cond).isSameAs(filtered); } @Test void testIsNotLikeCaseInsensitiveMapUnRenderableShouldNotThrowNullPointerException() { - IsNotLikeCaseInsensitive cond = SqlBuilder.isNotLikeCaseInsensitive("Fred").filter(s -> false); - IsNotLikeCaseInsensitive mapped = cond.map(String::toUpperCase); + var cond = SqlBuilder.isNotLikeCaseInsensitive("Fred").filter(s -> false); + var mapped = cond.map(String::toUpperCase); assertThat(cond.isEmpty()).isTrue(); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond).isSameAs(mapped); diff --git a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt index e018a8329..06dca6609 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt @@ -24,7 +24,7 @@ sealed class KIsLikeEscape<T : Any>( override fun filter(predicate: Predicate<in T>): KIsLikeEscape<T> = filterSupport(predicate, EmptyIsLikeEscape::empty, this) - fun <R : Any> map(mapper : Function<in T, out R>): KIsLikeEscape<R> = + override fun <R : Any> map(mapper : Function<in T, out R>): KIsLikeEscape<R> = mapSupport(mapper, { r -> ConcreteIsLikeEscape(r, escapeCharacter) }, EmptyIsLikeEscape::empty) companion object { From 1d41ea4ea587141498d3a66b8199e979391cf144 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 13 Mar 2025 09:48:23 -0400 Subject: [PATCH 203/260] Define a map template method for no value --- .../dynamic/sql/AbstractNoValueCondition.java | 16 +++++++++++++- .../sql/where/condition/IsNotNull.java | 12 +---------- .../dynamic/sql/where/condition/IsNull.java | 12 +---------- .../examples/mysql/MemberOfCondition.java | 21 +++++++++++++++++++ 4 files changed, 38 insertions(+), 23 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java index c0e103baf..f28073bf2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java @@ -34,7 +34,21 @@ protected <S extends AbstractNoValueCondition<?>> S filterSupport(BooleanSupplie public abstract String operator(); - @Override + /** + * If renderable and the supplier returns true, returns this condition. Else returns a condition that will not + * render. + * + * @param booleanSupplier + * function that specifies whether the condition should render + * @param <S> + * condition type - not used except for compilation compliance + * + * @return this condition if renderable and the supplier returns true, otherwise a condition that will not render. + */ + public abstract <S> AbstractNoValueCondition<S> filter(BooleanSupplier booleanSupplier); + + + @Override public FragmentAndParameters renderCondition(RenderingContext renderingContext, BindableColumn<T> leftColumn) { return FragmentAndParameters.fromFragment(operator()); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotNull.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotNull.java index 03d558387..fa13adbaf 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotNull.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotNull.java @@ -42,17 +42,7 @@ public String operator() { return "is not null"; //$NON-NLS-1$ } - /** - * If renderable and the supplier returns true, returns this condition. Else returns a condition that will not - * render. - * - * @param booleanSupplier - * function that specifies whether the condition should render - * @param <S> - * condition type - not used except for compilation compliance - * - * @return this condition if renderable and the supplier returns true, otherwise a condition that will not render. - */ + @Override public <S> IsNotNull<S> filter(BooleanSupplier booleanSupplier) { @SuppressWarnings("unchecked") IsNotNull<S> self = (IsNotNull<S>) this; diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNull.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNull.java index 36c68aa34..befbb9a13 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNull.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNull.java @@ -42,17 +42,7 @@ public String operator() { return "is null"; //$NON-NLS-1$ } - /** - * If renderable and the supplier returns true, returns this condition. Else returns a condition that will not - * render. - * - * @param booleanSupplier - * function that specifies whether the condition should render - * @param <S> - * condition type - not used except for compilation compliance - * - * @return this condition if renderable and the supplier returns true, otherwise a condition that will not render. - */ + @Override public <S> IsNull<S> filter(BooleanSupplier booleanSupplier) { @SuppressWarnings("unchecked") IsNull<S> self = (IsNull<S>) this; diff --git a/src/test/java/examples/mysql/MemberOfCondition.java b/src/test/java/examples/mysql/MemberOfCondition.java index 33b967556..c805b2127 100644 --- a/src/test/java/examples/mysql/MemberOfCondition.java +++ b/src/test/java/examples/mysql/MemberOfCondition.java @@ -16,12 +16,26 @@ package examples.mysql; import java.util.Objects; +import java.util.function.BooleanSupplier; import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.AbstractNoValueCondition; @NullMarked public class MemberOfCondition<T> extends AbstractNoValueCondition<T> { + private static final MemberOfCondition<?> EMPTY = new MemberOfCondition<>("") { + @Override + public boolean isEmpty() { + return true; + } + }; + + public static <T> MemberOfCondition<T> empty() { + @SuppressWarnings("unchecked") + MemberOfCondition<T> t = (MemberOfCondition<T>) EMPTY; + return t; + } + private final String jsonArray; protected MemberOfCondition(String jsonArray) { @@ -33,6 +47,13 @@ public String operator() { return "member of(" + jsonArray + ")"; } + @Override + public <S> MemberOfCondition<S> filter(BooleanSupplier booleanSupplier) { + @SuppressWarnings("unchecked") + MemberOfCondition<S> self = (MemberOfCondition<S>) this; + return filterSupport(booleanSupplier, MemberOfCondition::empty, self); + } + public static <T> MemberOfCondition<T> memberOf(String jsonArray) { return new MemberOfCondition<>(jsonArray); } From e52fa81434a3dfd1d3b7b62451c6f2f55f066ed2 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 13 Mar 2025 10:03:42 -0400 Subject: [PATCH 204/260] Define a map template method for list value --- .../sql/AbstractListValueCondition.java | 10 ++++++ .../org/mybatis/dynamic/sql/SqlBuilder.java | 16 ++++----- .../dynamic/sql/where/condition/IsIn.java | 9 +---- .../where/condition/IsInCaseInsensitive.java | 34 ++++++++---------- .../IsInCaseInsensitiveWhenPresent.java | 36 +++++++++---------- .../dynamic/sql/where/condition/IsNotIn.java | 9 +---- .../condition/IsNotInCaseInsensitive.java | 34 ++++++++---------- .../IsNotInCaseInsensitiveWhenPresent.java | 36 +++++++++---------- .../sql/util/kotlin/elements/SqlElements.kt | 27 +++++++------- .../sql/where/condition/FilterAndMapTest.java | 16 ++++----- 10 files changed, 105 insertions(+), 122 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java index 23f48e6f4..066012e28 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java @@ -83,6 +83,16 @@ protected <R, S extends AbstractListValueCondition<R>> S mapSupport(Function<? s */ public abstract AbstractListValueCondition<T> filter(Predicate<? super T> predicate); + /** + * If not empty, apply the mapping to each value in the list return a new condition with the mapped values. + * Else return an empty condition (this). + * + * @param mapper a mapping function to apply to the values, if not empty + * @param <R> type of the new condition + * @return a new condition with mapped values if renderable, otherwise an empty condition + */ + public abstract <R> AbstractListValueCondition<R> map(Function<? super T, ? extends R> mapper); + public abstract String operator(); @Override diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java index 8d462c698..2f365de1e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java @@ -915,36 +915,36 @@ static IsNotLikeCaseInsensitive<String> isNotLikeCaseInsensitiveWhenPresent( return isNotLikeCaseInsensitiveWhenPresent(valueSupplier.get()); } - static IsInCaseInsensitive isInCaseInsensitive(String... values) { + static IsInCaseInsensitive<String> isInCaseInsensitive(String... values) { return IsInCaseInsensitive.of(values); } - static IsInCaseInsensitive isInCaseInsensitive(Collection<String> values) { + static IsInCaseInsensitive<String> isInCaseInsensitive(Collection<String> values) { return IsInCaseInsensitive.of(values); } - static IsInCaseInsensitiveWhenPresent isInCaseInsensitiveWhenPresent(@Nullable String... values) { + static IsInCaseInsensitiveWhenPresent<String> isInCaseInsensitiveWhenPresent(@Nullable String... values) { return IsInCaseInsensitiveWhenPresent.of(values); } - static IsInCaseInsensitiveWhenPresent isInCaseInsensitiveWhenPresent( + static IsInCaseInsensitiveWhenPresent<String> isInCaseInsensitiveWhenPresent( @Nullable Collection<@Nullable String> values) { return values == null ? IsInCaseInsensitiveWhenPresent.empty() : IsInCaseInsensitiveWhenPresent.of(values); } - static IsNotInCaseInsensitive isNotInCaseInsensitive(String... values) { + static IsNotInCaseInsensitive<String> isNotInCaseInsensitive(String... values) { return IsNotInCaseInsensitive.of(values); } - static IsNotInCaseInsensitive isNotInCaseInsensitive(Collection<String> values) { + static IsNotInCaseInsensitive<String> isNotInCaseInsensitive(Collection<String> values) { return IsNotInCaseInsensitive.of(values); } - static IsNotInCaseInsensitiveWhenPresent isNotInCaseInsensitiveWhenPresent(@Nullable String... values) { + static IsNotInCaseInsensitiveWhenPresent<String> isNotInCaseInsensitiveWhenPresent(@Nullable String... values) { return IsNotInCaseInsensitiveWhenPresent.of(values); } - static IsNotInCaseInsensitiveWhenPresent isNotInCaseInsensitiveWhenPresent( + static IsNotInCaseInsensitiveWhenPresent<String> isNotInCaseInsensitiveWhenPresent( @Nullable Collection<@Nullable String> values) { return values == null ? IsNotInCaseInsensitiveWhenPresent.empty() : IsNotInCaseInsensitiveWhenPresent.of(values); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java index 6ce403717..67b6fff08 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java @@ -54,14 +54,7 @@ public IsIn<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsIn::new, this, IsIn::empty); } - /** - * If not empty, apply the mapping to each value in the list return a new condition with the mapped values. - * Else return an empty condition (this). - * - * @param mapper a mapping function to apply to the values, if not empty - * @param <R> type of the new condition - * @return a new condition with mapped values if renderable, otherwise an empty condition - */ + @Override public <R> IsIn<R> map(Function<? super T, ? extends R> mapper) { Function<Collection<R>, IsIn<R>> constructor = IsIn::new; return mapSupport(mapper, constructor, IsIn::empty); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java index 8fdf172bd..6f2313bdb 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java @@ -18,23 +18,25 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.function.Function; import java.util.function.Predicate; -import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.StringUtilities; import org.mybatis.dynamic.sql.util.Validator; -public class IsInCaseInsensitive extends AbstractListValueCondition<String> - implements CaseInsensitiveRenderableCondition<String> { - private static final IsInCaseInsensitive EMPTY = new IsInCaseInsensitive(Collections.emptyList()); +public class IsInCaseInsensitive<T> extends AbstractListValueCondition<T> + implements CaseInsensitiveRenderableCondition<T> { + private static final IsInCaseInsensitive<?> EMPTY = new IsInCaseInsensitive<>(Collections.emptyList()); - public static IsInCaseInsensitive empty() { - return EMPTY; + public static <T> IsInCaseInsensitive<T> empty() { + @SuppressWarnings("unchecked") + IsInCaseInsensitive<T> t = (IsInCaseInsensitive<T>) EMPTY; + return t; } - protected IsInCaseInsensitive(Collection<String> values) { + protected IsInCaseInsensitive(Collection<T> values) { super(values); } @@ -50,28 +52,22 @@ public String operator() { } @Override - public IsInCaseInsensitive filter(Predicate<? super String> predicate) { + public IsInCaseInsensitive<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsInCaseInsensitive::new, this, IsInCaseInsensitive::empty); } - /** - * If not empty, apply the mapping to each value in the list return a new condition with the mapped values. - * Else return an empty condition (this). - * - * @param mapper a mapping function to apply to the values, if not empty - * @return a new condition with mapped values if renderable, otherwise an empty condition - */ - public IsInCaseInsensitive map(UnaryOperator<String> mapper) { + @Override + public <R> IsInCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsInCaseInsensitive::new, IsInCaseInsensitive::empty); } - public static IsInCaseInsensitive of(String... values) { + public static IsInCaseInsensitive<String> of(String... values) { return of(Arrays.asList(values)); } - public static IsInCaseInsensitive of(Collection<String> values) { + public static IsInCaseInsensitive<String> of(Collection<String> values) { // Keep the null safe upper case utility for backwards compatibility //noinspection DataFlowIssue - return new IsInCaseInsensitive(values).map(StringUtilities::safelyUpperCase); + return new IsInCaseInsensitive<>(values).map(StringUtilities::safelyUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java index 91b77901a..523b3d732 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java @@ -18,24 +18,26 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.function.Function; import java.util.function.Predicate; -import java.util.function.UnaryOperator; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; import org.mybatis.dynamic.sql.util.Utilities; -public class IsInCaseInsensitiveWhenPresent extends AbstractListValueCondition<String> - implements CaseInsensitiveRenderableCondition<String> { - private static final IsInCaseInsensitiveWhenPresent EMPTY = - new IsInCaseInsensitiveWhenPresent(Collections.emptyList()); +public class IsInCaseInsensitiveWhenPresent<T> extends AbstractListValueCondition<T> + implements CaseInsensitiveRenderableCondition<T> { + private static final IsInCaseInsensitiveWhenPresent<?> EMPTY = + new IsInCaseInsensitiveWhenPresent<>(Collections.emptyList()); - public static IsInCaseInsensitiveWhenPresent empty() { - return EMPTY; + public static <T> IsInCaseInsensitiveWhenPresent<T> empty() { + @SuppressWarnings("unchecked") + IsInCaseInsensitiveWhenPresent<T> t = (IsInCaseInsensitiveWhenPresent<T>) EMPTY; + return t; } - protected IsInCaseInsensitiveWhenPresent(Collection<@Nullable String> values) { + protected IsInCaseInsensitiveWhenPresent(Collection<@Nullable T> values) { super(Utilities.removeNullElements(values)); } @@ -45,29 +47,23 @@ public String operator() { } @Override - public IsInCaseInsensitiveWhenPresent filter(Predicate<? super String> predicate) { + public IsInCaseInsensitiveWhenPresent<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsInCaseInsensitiveWhenPresent::new, this, IsInCaseInsensitiveWhenPresent::empty); } - /** - * If not empty, apply the mapping to each value in the list return a new condition with the mapped values. - * Else return an empty condition (this). - * - * @param mapper a mapping function to apply to the values, if not empty - * @return a new condition with mapped values if renderable, otherwise an empty condition - */ - public IsInCaseInsensitiveWhenPresent map(UnaryOperator<String> mapper) { + @Override + public <R> IsInCaseInsensitiveWhenPresent<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsInCaseInsensitiveWhenPresent::new, IsInCaseInsensitiveWhenPresent::empty); } - public static IsInCaseInsensitiveWhenPresent of(@Nullable String... values) { + public static IsInCaseInsensitiveWhenPresent<String> of(@Nullable String... values) { return of(Arrays.asList(values)); } - public static IsInCaseInsensitiveWhenPresent of(Collection<@Nullable String> values) { + public static IsInCaseInsensitiveWhenPresent<String> of(Collection<@Nullable String> values) { // Keep the null safe upper case utility for backwards compatibility //noinspection DataFlowIssue - return new IsInCaseInsensitiveWhenPresent(values).map(StringUtilities::safelyUpperCase); + return new IsInCaseInsensitiveWhenPresent<>(values).map(StringUtilities::safelyUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java index e1ca07abf..f22c504c8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java @@ -54,14 +54,7 @@ public IsNotIn<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsNotIn::new, this, IsNotIn::empty); } - /** - * If not empty, apply the mapping to each value in the list return a new condition with the mapped values. - * Else return an empty condition (this). - * - * @param mapper a mapping function to apply to the values, if not empty - * @param <R> type of the new condition - * @return a new condition with mapped values if renderable, otherwise an empty condition - */ + @Override public <R> IsNotIn<R> map(Function<? super T, ? extends R> mapper) { Function<Collection<R>, IsNotIn<R>> constructor = IsNotIn::new; return mapSupport(mapper, constructor, IsNotIn::empty); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java index 473b9077e..2687ef9b7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java @@ -18,23 +18,25 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.function.Function; import java.util.function.Predicate; -import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.StringUtilities; import org.mybatis.dynamic.sql.util.Validator; -public class IsNotInCaseInsensitive extends AbstractListValueCondition<String> - implements CaseInsensitiveRenderableCondition<String> { - private static final IsNotInCaseInsensitive EMPTY = new IsNotInCaseInsensitive(Collections.emptyList()); +public class IsNotInCaseInsensitive<T> extends AbstractListValueCondition<T> + implements CaseInsensitiveRenderableCondition<T> { + private static final IsNotInCaseInsensitive<?> EMPTY = new IsNotInCaseInsensitive<>(Collections.emptyList()); - public static IsNotInCaseInsensitive empty() { - return EMPTY; + public static <T> IsNotInCaseInsensitive<T> empty() { + @SuppressWarnings("unchecked") + IsNotInCaseInsensitive<T> t = (IsNotInCaseInsensitive<T>) EMPTY; + return t; } - protected IsNotInCaseInsensitive(Collection<String> values) { + protected IsNotInCaseInsensitive(Collection<T> values) { super(values); } @@ -50,28 +52,22 @@ public String operator() { } @Override - public IsNotInCaseInsensitive filter(Predicate<? super String> predicate) { + public IsNotInCaseInsensitive<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsNotInCaseInsensitive::new, this, IsNotInCaseInsensitive::empty); } - /** - * If not empty, apply the mapping to each value in the list return a new condition with the mapped values. - * Else return an empty condition (this). - * - * @param mapper a mapping function to apply to the values, if not empty - * @return a new condition with mapped values if renderable, otherwise an empty condition - */ - public IsNotInCaseInsensitive map(UnaryOperator<String> mapper) { + @Override + public <R> IsNotInCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsNotInCaseInsensitive::new, IsNotInCaseInsensitive::empty); } - public static IsNotInCaseInsensitive of(String... values) { + public static IsNotInCaseInsensitive<String> of(String... values) { return of(Arrays.asList(values)); } - public static IsNotInCaseInsensitive of(Collection<String> values) { + public static IsNotInCaseInsensitive<String> of(Collection<String> values) { // Keep the null safe upper case utility for backwards compatibility //noinspection DataFlowIssue - return new IsNotInCaseInsensitive(values).map(StringUtilities::safelyUpperCase); + return new IsNotInCaseInsensitive<>(values).map(StringUtilities::safelyUpperCase); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java index b2d834f2b..143d2a6a2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java @@ -18,24 +18,26 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.function.Function; import java.util.function.Predicate; -import java.util.function.UnaryOperator; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; import org.mybatis.dynamic.sql.util.Utilities; -public class IsNotInCaseInsensitiveWhenPresent extends AbstractListValueCondition<String> - implements CaseInsensitiveRenderableCondition<String> { - private static final IsNotInCaseInsensitiveWhenPresent EMPTY = - new IsNotInCaseInsensitiveWhenPresent(Collections.emptyList()); +public class IsNotInCaseInsensitiveWhenPresent<T> extends AbstractListValueCondition<T> + implements CaseInsensitiveRenderableCondition<T> { + private static final IsNotInCaseInsensitiveWhenPresent<?> EMPTY = + new IsNotInCaseInsensitiveWhenPresent<>(Collections.emptyList()); - public static IsNotInCaseInsensitiveWhenPresent empty() { - return EMPTY; + public static <T> IsNotInCaseInsensitiveWhenPresent<T> empty() { + @SuppressWarnings("unchecked") + IsNotInCaseInsensitiveWhenPresent<T> t = (IsNotInCaseInsensitiveWhenPresent<T>) EMPTY; + return t; } - protected IsNotInCaseInsensitiveWhenPresent(Collection<@Nullable String> values) { + protected IsNotInCaseInsensitiveWhenPresent(Collection<@Nullable T> values) { super(Utilities.removeNullElements(values)); } @@ -45,29 +47,23 @@ public String operator() { } @Override - public IsNotInCaseInsensitiveWhenPresent filter(Predicate<? super String> predicate) { + public IsNotInCaseInsensitiveWhenPresent<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsNotInCaseInsensitiveWhenPresent::new, this, IsNotInCaseInsensitiveWhenPresent::empty); } - /** - * If not empty, apply the mapping to each value in the list return a new condition with the mapped values. - * Else return an empty condition (this). - * - * @param mapper a mapping function to apply to the values, if not empty - * @return a new condition with mapped values if renderable, otherwise an empty condition - */ - public IsNotInCaseInsensitiveWhenPresent map(UnaryOperator<String> mapper) { + @Override + public <R> IsNotInCaseInsensitiveWhenPresent<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsNotInCaseInsensitiveWhenPresent::new, IsNotInCaseInsensitiveWhenPresent::empty); } - public static IsNotInCaseInsensitiveWhenPresent of(@Nullable String... values) { + public static IsNotInCaseInsensitiveWhenPresent<String> of(@Nullable String... values) { return of(Arrays.asList(values)); } - public static IsNotInCaseInsensitiveWhenPresent of(Collection<@Nullable String> values) { + public static IsNotInCaseInsensitiveWhenPresent<String> of(Collection<@Nullable String> values) { // Keep the null safe upper case utility for backwards compatibility //noinspection DataFlowIssue - return new IsNotInCaseInsensitiveWhenPresent(values).map(StringUtilities::safelyUpperCase); + return new IsNotInCaseInsensitiveWhenPresent<>(values).map(StringUtilities::safelyUpperCase); } } diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt index 0983eaa9c..530c962ed 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt @@ -334,40 +334,43 @@ fun isNotLikeCaseInsensitive(value: String): IsNotLikeCaseInsensitive<String> = fun isNotLikeCaseInsensitiveWhenPresent(value: String?): IsNotLikeCaseInsensitive<String> = SqlBuilder.isNotLikeCaseInsensitiveWhenPresent(value) -fun isInCaseInsensitive(vararg values: String): IsInCaseInsensitive = isInCaseInsensitive(values.asList()) +fun isInCaseInsensitive(vararg values: String): IsInCaseInsensitive<String> = isInCaseInsensitive(values.asList()) @JvmName("isInArrayCaseInsensitive") -fun isInCaseInsensitive(values: Array<out String>): IsInCaseInsensitive = SqlBuilder.isInCaseInsensitive(values.asList()) +fun isInCaseInsensitive(values: Array<out String>): IsInCaseInsensitive<String> = + SqlBuilder.isInCaseInsensitive(values.asList()) -fun isInCaseInsensitive(values: Collection<String>): IsInCaseInsensitive = SqlBuilder.isInCaseInsensitive(values) +fun isInCaseInsensitive(values: Collection<String>): IsInCaseInsensitive<String> = + SqlBuilder.isInCaseInsensitive(values) -fun isInCaseInsensitiveWhenPresent(vararg values: String?): IsInCaseInsensitiveWhenPresent = +fun isInCaseInsensitiveWhenPresent(vararg values: String?): IsInCaseInsensitiveWhenPresent<String> = isInCaseInsensitiveWhenPresent(values.asList()) @JvmName("isInArrayCaseInsensitiveWhenPresent") -fun isInCaseInsensitiveWhenPresent(values: Array<out String?>?): IsInCaseInsensitiveWhenPresent = +fun isInCaseInsensitiveWhenPresent(values: Array<out String?>?): IsInCaseInsensitiveWhenPresent<String> = SqlBuilder.isInCaseInsensitiveWhenPresent(values?.asList()) -fun isInCaseInsensitiveWhenPresent(values: Collection<String?>?): IsInCaseInsensitiveWhenPresent = +fun isInCaseInsensitiveWhenPresent(values: Collection<String?>?): IsInCaseInsensitiveWhenPresent<String> = SqlBuilder.isInCaseInsensitiveWhenPresent(values) -fun isNotInCaseInsensitive(vararg values: String): IsNotInCaseInsensitive = isNotInCaseInsensitive(values.asList()) +fun isNotInCaseInsensitive(vararg values: String): IsNotInCaseInsensitive<String> = + isNotInCaseInsensitive(values.asList()) @JvmName("isNotInArrayCaseInsensitive") -fun isNotInCaseInsensitive(values: Array<out String>): IsNotInCaseInsensitive = +fun isNotInCaseInsensitive(values: Array<out String>): IsNotInCaseInsensitive<String> = SqlBuilder.isNotInCaseInsensitive(values.asList()) -fun isNotInCaseInsensitive(values: Collection<String>): IsNotInCaseInsensitive = +fun isNotInCaseInsensitive(values: Collection<String>): IsNotInCaseInsensitive<String> = SqlBuilder.isNotInCaseInsensitive(values) -fun isNotInCaseInsensitiveWhenPresent(vararg values: String?): IsNotInCaseInsensitiveWhenPresent = +fun isNotInCaseInsensitiveWhenPresent(vararg values: String?): IsNotInCaseInsensitiveWhenPresent<String> = isNotInCaseInsensitiveWhenPresent(values.asList()) @JvmName("isNotInArrayCaseInsensitiveWhenPresent") -fun isNotInCaseInsensitiveWhenPresent(values: Array<out String?>?): IsNotInCaseInsensitiveWhenPresent = +fun isNotInCaseInsensitiveWhenPresent(values: Array<out String?>?): IsNotInCaseInsensitiveWhenPresent<String> = SqlBuilder.isNotInCaseInsensitiveWhenPresent(values?.asList()) -fun isNotInCaseInsensitiveWhenPresent(values: Collection<String?>?): IsNotInCaseInsensitiveWhenPresent = +fun isNotInCaseInsensitiveWhenPresent(values: Collection<String?>?): IsNotInCaseInsensitiveWhenPresent<String> = SqlBuilder.isNotInCaseInsensitiveWhenPresent(values) // order by support diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java index 358ec0cd3..8c8f35eb5 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java @@ -447,25 +447,25 @@ void testIsNotInRenderableMapShouldReturnMappedObject() { @Test void testIsNotInCaseInsensitiveRenderableMapShouldReturnMappedObject() { - IsNotInCaseInsensitive cond = SqlBuilder.isNotInCaseInsensitive("Fred ", "Wilma "); - List<String> values = cond.values().toList(); + var cond = SqlBuilder.isNotInCaseInsensitive("Fred ", "Wilma "); + var values = cond.values().toList(); assertThat(values).containsExactly("FRED ", "WILMA "); assertThat(cond.isEmpty()).isFalse(); - IsNotInCaseInsensitive mapped = cond.map(String::trim); - List<String> mappedValues = mapped.values().toList(); + var mapped = cond.map(String::trim); + var mappedValues = mapped.values().toList(); assertThat(mappedValues).containsExactly("FRED", "WILMA"); } @Test void testIsInCaseInsensitiveRenderableMapShouldReturnMappedObject() { - IsInCaseInsensitive cond = SqlBuilder.isInCaseInsensitive("Fred ", "Wilma "); - List<String> values = cond.values().toList(); + var cond = SqlBuilder.isInCaseInsensitive("Fred ", "Wilma "); + var values = cond.values().toList(); assertThat(values).containsExactly("FRED ", "WILMA "); assertThat(cond.isEmpty()).isFalse(); - IsInCaseInsensitive mapped = cond.map(String::trim); - List<String> mappedValues = mapped.values().toList(); + var mapped = cond.map(String::trim); + var mappedValues = mapped.values().toList(); assertThat(mappedValues).containsExactly("FRED", "WILMA"); } From d73b31b945be5f349cb907e8a78283b87cd14bc0 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 13 Mar 2025 10:10:28 -0400 Subject: [PATCH 205/260] Define a map template method for two value --- .../sql/AbstractTwoValueCondition.java | 24 +++++++++++++++++++ .../sql/where/condition/IsBetween.java | 21 ++-------------- .../sql/where/condition/IsNotBetween.java | 21 ++-------------- 3 files changed, 28 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java index 865f7db0b..15a5b6ffe 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java @@ -88,6 +88,30 @@ protected <R, S extends AbstractTwoValueCondition<R>> S mapSupport(Function<? su */ public abstract AbstractTwoValueCondition<T> filter(Predicate<? super T> predicate); + /** + * If renderable, apply the mappings to the values and return a new condition with the new values. Else return a + * condition that will not render (this). + * + * @param mapper1 a mapping function to apply to the first value, if renderable + * @param mapper2 a mapping function to apply to the second value, if renderable + * @param <R> type of the new condition + * @return a new condition with the result of applying the mappers to the values of this condition, + * if renderable, otherwise a condition that will not render. + */ + public abstract <R> AbstractTwoValueCondition<R> map(Function<? super T, ? extends R> mapper1, + Function<? super T, ? extends R> mapper2); + + /** + * If renderable, apply the mapping to both values and return a new condition with the new values. Else return a + * condition that will not render (this). + * + * @param mapper a mapping function to apply to both values, if renderable + * @param <R> type of the new condition + * @return a new condition with the result of applying the mappers to the values of this condition, + * if renderable, otherwise a condition that will not render. + */ + public abstract <R> AbstractTwoValueCondition<R> map(Function<? super T, ? extends R> mapper); + public abstract String operator1(); public abstract String operator2(); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java index deeddb4c9..0d554d0fc 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java @@ -71,29 +71,12 @@ public IsBetween<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsBetween::empty, this); } - /** - * If renderable, apply the mappings to the values and return a new condition with the new values. Else return a - * condition that will not render (this). - * - * @param mapper1 a mapping function to apply to the first value, if renderable - * @param mapper2 a mapping function to apply to the second value, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mappers to the values of this condition, - * if renderable, otherwise a condition that will not render. - */ + @Override public <R> IsBetween<R> map(Function<? super T, ? extends R> mapper1, Function<? super T, ? extends R> mapper2) { return mapSupport(mapper1, mapper2, IsBetween::new, IsBetween::empty); } - /** - * If renderable, apply the mapping to both values and return a new condition with the new values. Else return a - * condition that will not render (this). - * - * @param mapper a mapping function to apply to both values, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mappers to the values of this condition, - * if renderable, otherwise a condition that will not render. - */ + @Override public <R> IsBetween<R> map(Function<? super T, ? extends R> mapper) { return map(mapper, mapper); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java index 5700de2ac..f7eb98f52 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java @@ -71,30 +71,13 @@ public IsNotBetween<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsNotBetween::empty, this); } - /** - * If renderable, apply the mappings to the values and return a new condition with the new values. Else return a - * condition that will not render (this). - * - * @param mapper1 a mapping function to apply to the first value, if renderable - * @param mapper2 a mapping function to apply to the second value, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mappers to the values of this condition, - * if renderable, otherwise a condition that will not render. - */ + @Override public <R> IsNotBetween<R> map(Function<? super T, ? extends R> mapper1, Function<? super T, ? extends R> mapper2) { return mapSupport(mapper1, mapper2, IsNotBetween::new, IsNotBetween::empty); } - /** - * If renderable, apply the mapping to both values and return a new condition with the new values. Else return a - * condition that will not render (this). - * - * @param mapper a mapping function to apply to both values, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mappers to the values of this condition, - * if renderable, otherwise a condition that will not render. - */ + @Override public <R> IsNotBetween<R> map(Function<? super T, ? extends R> mapper) { return map(mapper, mapper); } From 5eda6cb283ae3fa3a09ebd3510277264f3754fe6 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 13 Mar 2025 17:33:08 -0400 Subject: [PATCH 206/260] Little optimization that creates less garbage --- .../mybatis/dynamic/sql/util/StringUtilities.java | 1 - .../org/mybatis/dynamic/sql/util/Utilities.java | 13 ------------- .../sql/where/condition/IsInCaseInsensitive.java | 5 ++--- .../condition/IsInCaseInsensitiveWhenPresent.java | 12 +++++------- .../sql/where/condition/IsLikeCaseInsensitive.java | 5 ++--- .../sql/where/condition/IsNotInCaseInsensitive.java | 5 ++--- .../IsNotInCaseInsensitiveWhenPresent.java | 12 +++++------- .../where/condition/IsNotLikeCaseInsensitive.java | 5 ++--- 8 files changed, 18 insertions(+), 40 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java b/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java index 3104c2905..2b57c748e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java @@ -58,6 +58,5 @@ static String toCamelCase(String inputString) { static String formatConstantForSQL(String in) { String escaped = in.replace("'", "''"); //$NON-NLS-1$ //$NON-NLS-2$ return "'" + escaped + "'"; //$NON-NLS-1$ //$NON-NLS-2$ - } } diff --git a/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java b/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java index 87ea18e12..0c3bd188f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/Utilities.java @@ -15,23 +15,10 @@ */ package org.mybatis.dynamic.sql.util; -import java.util.Collection; -import java.util.Objects; -import java.util.stream.Stream; - -import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; public interface Utilities { static long safelyUnbox(@Nullable Long l) { return l == null ? 0 : l; } - - static <T> Stream<@NonNull T> filterNullValues(Stream<@Nullable T> values) { - return values.filter(Objects::nonNull); - } - - static <T> Collection<@NonNull T> removeNullElements(Collection<@Nullable T> values) { - return filterNullValues(values.stream()).toList(); - } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java index 67f37951e..e521d28b2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java @@ -70,8 +70,7 @@ public static IsInCaseInsensitive of(String... values) { } public static IsInCaseInsensitive of(Collection<String> values) { - // Keep the null safe upper case utility for backwards compatibility - //noinspection DataFlowIssue - return new IsInCaseInsensitive(values).map(StringUtilities::safelyUpperCase); + // Keep the null safe upper case utility for backwards compatibility in case someone passes in a null + return new IsInCaseInsensitive(values.stream().map(StringUtilities::safelyUpperCase).toList()); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java index cff58415d..7d81bba69 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java @@ -18,13 +18,12 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Objects; import java.util.function.Predicate; import java.util.function.UnaryOperator; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; -import org.mybatis.dynamic.sql.util.StringUtilities; -import org.mybatis.dynamic.sql.util.Utilities; public class IsInCaseInsensitiveWhenPresent extends AbstractListValueCondition<String> implements CaseInsensitiveRenderableCondition { @@ -35,8 +34,8 @@ public static IsInCaseInsensitiveWhenPresent empty() { return EMPTY; } - protected IsInCaseInsensitiveWhenPresent(Collection<@Nullable String> values) { - super(Utilities.removeNullElements(values)); + protected IsInCaseInsensitiveWhenPresent(Collection<String> values) { + super(values); } @Override @@ -66,8 +65,7 @@ public static IsInCaseInsensitiveWhenPresent of(@Nullable String... values) { } public static IsInCaseInsensitiveWhenPresent of(Collection<@Nullable String> values) { - // Keep the null safe upper case utility for backwards compatibility - //noinspection DataFlowIssue - return new IsInCaseInsensitiveWhenPresent(values).map(StringUtilities::safelyUpperCase); + return new IsInCaseInsensitiveWhenPresent( + values.stream().filter(Objects::nonNull).map(String::toUpperCase).toList()); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java index 4ebdb00fb..de8d72cd0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java @@ -67,8 +67,7 @@ public IsLikeCaseInsensitive map(UnaryOperator<String> mapper) { } public static IsLikeCaseInsensitive of(String value) { - // Keep the null safe upper case utility for backwards compatibility - //noinspection DataFlowIssue - return new IsLikeCaseInsensitive(value).map(StringUtilities::safelyUpperCase); + // Keep the null safe upper case utility for backwards compatibility in case someone passes in a null + return new IsLikeCaseInsensitive(StringUtilities.safelyUpperCase(value)); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java index f5f970c45..c956b4d55 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java @@ -70,8 +70,7 @@ public static IsNotInCaseInsensitive of(String... values) { } public static IsNotInCaseInsensitive of(Collection<String> values) { - // Keep the null safe upper case utility for backwards compatibility - //noinspection DataFlowIssue - return new IsNotInCaseInsensitive(values).map(StringUtilities::safelyUpperCase); + // Keep the null safe upper case utility for backwards compatibility in case someone passes in a null + return new IsNotInCaseInsensitive(values.stream().map(StringUtilities::safelyUpperCase).toList()); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java index a8873a7e4..9202a2ad1 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java @@ -18,13 +18,12 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Objects; import java.util.function.Predicate; import java.util.function.UnaryOperator; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; -import org.mybatis.dynamic.sql.util.StringUtilities; -import org.mybatis.dynamic.sql.util.Utilities; public class IsNotInCaseInsensitiveWhenPresent extends AbstractListValueCondition<String> implements CaseInsensitiveRenderableCondition { @@ -35,8 +34,8 @@ public static IsNotInCaseInsensitiveWhenPresent empty() { return EMPTY; } - protected IsNotInCaseInsensitiveWhenPresent(Collection<@Nullable String> values) { - super(Utilities.removeNullElements(values)); + protected IsNotInCaseInsensitiveWhenPresent(Collection<String> values) { + super(values); } @Override @@ -66,8 +65,7 @@ public static IsNotInCaseInsensitiveWhenPresent of(@Nullable String... values) { } public static IsNotInCaseInsensitiveWhenPresent of(Collection<@Nullable String> values) { - // Keep the null safe upper case utility for backwards compatibility - //noinspection DataFlowIssue - return new IsNotInCaseInsensitiveWhenPresent(values).map(StringUtilities::safelyUpperCase); + return new IsNotInCaseInsensitiveWhenPresent( + values.stream().filter(Objects::nonNull).map(String::toUpperCase).toList()); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java index 1fb6847c0..c26168e42 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java @@ -69,8 +69,7 @@ public IsNotLikeCaseInsensitive map(UnaryOperator<String> mapper) { } public static IsNotLikeCaseInsensitive of(String value) { - // Keep the null safe upper case utility for backwards compatibility - //noinspection DataFlowIssue - return new IsNotLikeCaseInsensitive(value).map(StringUtilities::safelyUpperCase); + // Keep the null safe upper case utility for backwards compatibility in case someone passes in a null + return new IsNotLikeCaseInsensitive(StringUtilities.safelyUpperCase(value)); } } From b428bb5fad0041f8abf330c2b63adda3601a5942 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 13 Mar 2025 21:40:52 +0000 Subject: [PATCH 207/260] Update dependency org.springframework:spring-jdbc to v6.2.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 584b5daa6..f26ba6481 100644 --- a/pom.xml +++ b/pom.xml @@ -101,7 +101,7 @@ <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> - <version>6.2.3</version> + <version>6.2.4</version> <scope>provided</scope> <optional>true</optional> </dependency> From f49cf7f28f3f9a48ac8c880895f0e3c19d8175b3 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 13 Mar 2025 17:50:02 -0400 Subject: [PATCH 208/260] Fixes after merge --- .../sql/where/condition/IsInCaseInsensitiveWhenPresent.java | 2 +- .../sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java index abd6758e0..de17a8394 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java @@ -36,7 +36,7 @@ public static <T> IsInCaseInsensitiveWhenPresent<T> empty() { return t; } - protected IsInCaseInsensitiveWhenPresent(Collection<String> values) { + protected IsInCaseInsensitiveWhenPresent(Collection<T> values) { super(values); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java index c2784d819..bbff09bbe 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java @@ -36,7 +36,7 @@ public static <T> IsNotInCaseInsensitiveWhenPresent<T> empty() { return t; } - protected IsNotInCaseInsensitiveWhenPresent(Collection<String> values) { + protected IsNotInCaseInsensitiveWhenPresent(Collection<T> values) { super(values); } From 7b426ceb0a3795112a15867670d8007c002240ed Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 14 Mar 2025 09:40:32 -0400 Subject: [PATCH 209/260] Make filtering optional on no value conditions --- .../dynamic/sql/AbstractNoValueCondition.java | 31 ++++++++++--------- .../sql/where/condition/IsNotNull.java | 2 +- .../dynamic/sql/where/condition/IsNull.java | 2 +- .../examples/mysql/MemberOfCondition.java | 21 ------------- 4 files changed, 18 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java index f28073bf2..b0c7d9bad 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java @@ -34,22 +34,23 @@ protected <S extends AbstractNoValueCondition<?>> S filterSupport(BooleanSupplie public abstract String operator(); - /** - * If renderable and the supplier returns true, returns this condition. Else returns a condition that will not - * render. - * - * @param booleanSupplier - * function that specifies whether the condition should render - * @param <S> - * condition type - not used except for compilation compliance - * - * @return this condition if renderable and the supplier returns true, otherwise a condition that will not render. - */ - public abstract <S> AbstractNoValueCondition<S> filter(BooleanSupplier booleanSupplier); - - - @Override + @Override public FragmentAndParameters renderCondition(RenderingContext renderingContext, BindableColumn<T> leftColumn) { return FragmentAndParameters.fromFragment(operator()); } + + public interface Filterable { + /** + * If renderable and the supplier returns true, returns this condition. Else returns a condition that will not + * render. + * + * @param booleanSupplier + * function that specifies whether the condition should render + * @param <S> + * condition type - not used except for compilation compliance + * + * @return this condition if renderable and the supplier returns true, otherwise a condition that will not render. + */ + <S> AbstractNoValueCondition<S> filter(BooleanSupplier booleanSupplier); + } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotNull.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotNull.java index fa13adbaf..1c1f3139d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotNull.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotNull.java @@ -19,7 +19,7 @@ import org.mybatis.dynamic.sql.AbstractNoValueCondition; -public class IsNotNull<T> extends AbstractNoValueCondition<T> { +public class IsNotNull<T> extends AbstractNoValueCondition<T> implements AbstractNoValueCondition.Filterable { private static final IsNotNull<?> EMPTY = new IsNotNull<>() { @Override public boolean isEmpty() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNull.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNull.java index befbb9a13..a27b7dc2a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNull.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNull.java @@ -19,7 +19,7 @@ import org.mybatis.dynamic.sql.AbstractNoValueCondition; -public class IsNull<T> extends AbstractNoValueCondition<T> { +public class IsNull<T> extends AbstractNoValueCondition<T> implements AbstractNoValueCondition.Filterable { private static final IsNull<?> EMPTY = new IsNull<>() { @Override public boolean isEmpty() { diff --git a/src/test/java/examples/mysql/MemberOfCondition.java b/src/test/java/examples/mysql/MemberOfCondition.java index c805b2127..33b967556 100644 --- a/src/test/java/examples/mysql/MemberOfCondition.java +++ b/src/test/java/examples/mysql/MemberOfCondition.java @@ -16,26 +16,12 @@ package examples.mysql; import java.util.Objects; -import java.util.function.BooleanSupplier; import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.AbstractNoValueCondition; @NullMarked public class MemberOfCondition<T> extends AbstractNoValueCondition<T> { - private static final MemberOfCondition<?> EMPTY = new MemberOfCondition<>("") { - @Override - public boolean isEmpty() { - return true; - } - }; - - public static <T> MemberOfCondition<T> empty() { - @SuppressWarnings("unchecked") - MemberOfCondition<T> t = (MemberOfCondition<T>) EMPTY; - return t; - } - private final String jsonArray; protected MemberOfCondition(String jsonArray) { @@ -47,13 +33,6 @@ public String operator() { return "member of(" + jsonArray + ")"; } - @Override - public <S> MemberOfCondition<S> filter(BooleanSupplier booleanSupplier) { - @SuppressWarnings("unchecked") - MemberOfCondition<S> self = (MemberOfCondition<S>) this; - return filterSupport(booleanSupplier, MemberOfCondition::empty, self); - } - public static <T> MemberOfCondition<T> memberOf(String jsonArray) { return new MemberOfCondition<>(jsonArray); } From 30fc7efdfd868761fc653f4655002d9b2ccb9f82 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 14 Mar 2025 10:12:56 -0400 Subject: [PATCH 210/260] Make filtering optional on no value conditions --- .../mybatis/dynamic/sql/AbstractNoValueCondition.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java index b0c7d9bad..20e6251d6 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java @@ -39,6 +39,17 @@ public FragmentAndParameters renderCondition(RenderingContext renderingContext, return FragmentAndParameters.fromFragment(operator()); } + /** + * Conditions may implement Filterable to add optionality to rendering. + * + * <p>If a condition is Filterable, then a user may add a filter to the usage of the condition that makes a decision + * whether to render the condition at runtime. Conditions that fail the filter will be dropped from the + * rendered SQL. + * + * <p>Implementations of Filterable may call + * {@link AbstractNoValueCondition#filterSupport(BooleanSupplier, Supplier, AbstractNoValueCondition)} as + * a common implementation of the filtering algorithm. + */ public interface Filterable { /** * If renderable and the supplier returns true, returns this condition. Else returns a condition that will not From 50944221f6e15df6f95c57887da3c58011212444 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 14 Mar 2025 10:45:37 -0400 Subject: [PATCH 211/260] Make filter and map optional on single value conditions --- .../sql/AbstractSingleValueCondition.java | 71 +++++++++++++------ .../sql/where/condition/IsEqualTo.java | 3 +- .../sql/where/condition/IsGreaterThan.java | 3 +- .../condition/IsGreaterThanOrEqualTo.java | 3 +- .../sql/where/condition/IsLessThan.java | 4 +- .../where/condition/IsLessThanOrEqualTo.java | 3 +- .../dynamic/sql/where/condition/IsLike.java | 4 +- .../condition/IsLikeCaseInsensitive.java | 3 +- .../sql/where/condition/IsNotEqualTo.java | 3 +- .../sql/where/condition/IsNotLike.java | 3 +- .../condition/IsNotLikeCaseInsensitive.java | 14 +--- .../java/examples/mysql/IsLikeEscape.java | 3 +- .../kotlin/mybatis3/mariadb/KIsLikeEscape.kt | 3 +- 13 files changed, 77 insertions(+), 43 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java index f032d64db..c16dbf08c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java @@ -54,27 +54,6 @@ protected <R, S extends AbstractSingleValueCondition<R>> S mapSupport(Function<? } } - /** - * If renderable and the value matches the predicate, returns this condition. Else returns a condition - * that will not render. - * - * @param predicate predicate applied to the value, if renderable - * @return this condition if renderable and the value matches the predicate, otherwise a condition - * that will not render. - */ - public abstract AbstractSingleValueCondition<T> filter(Predicate<? super T> predicate); - - /** - * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a - * condition that will not render (this). - * - * @param mapper a mapping function to apply to the value, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mapper to the value of this condition, - * if renderable, otherwise a condition that will not render. - */ - public abstract <R> AbstractSingleValueCondition<R> map(Function<? super T, ? extends R> mapper); - public abstract String operator(); @Override @@ -86,4 +65,54 @@ public FragmentAndParameters renderCondition(RenderingContext renderingContext, .withParameter(parameterInfo.parameterMapKey(), leftColumn.convertParameterType(value())) .build(); } + + /** + * Conditions may implement Filterable to add optionality to rendering. + * + * <p>If a condition is Filterable, then a user may add a filter to the usage of the condition that makes a decision + * whether to render the condition at runtime. Conditions that fail the filter will be dropped from the + * rendered SQL. + * + * <p>Implementations of Filterable may call + * {@link AbstractSingleValueCondition#filterSupport(Predicate, Supplier, AbstractSingleValueCondition)} as + * a common implementation of the filtering algorithm. + * + * @param <T> the Java type related to the database column type + */ + public interface Filterable<T> { + /** + * If renderable and the value matches the predicate, returns this condition. Else returns a condition + * that will not render. + * + * @param predicate predicate applied to the value, if renderable + * @return this condition if renderable and the value matches the predicate, otherwise a condition + * that will not render. + */ + AbstractSingleValueCondition<T> filter(Predicate<? super T> predicate); + } + + /** + * Conditions may implement Mappable to alter condition values or types during rendering. + * + * <p>If a condition is Mappable, then a user may add a mapper to the usage of the condition that can alter the + * values of a condition, or change that datatype. + * + * <p>Implementations of Mappable may call + * {@link AbstractSingleValueCondition#mapSupport(Function, Function, Supplier)} as + * a common implementation of the mapping algorithm. + * + * @param <T> the Java type related to the database column type + */ + public interface Mappable<T> { + /** + * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a + * condition that will not render (this). + * + * @param mapper a mapping function to apply to the value, if renderable + * @param <R> type of the new condition + * @return a new condition with the result of applying the mapper to the value of this condition, + * if renderable, otherwise a condition that will not render. + */ + <R> AbstractSingleValueCondition<R> map(Function<? super T, ? extends R> mapper); + } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java index 17fe9eef1..51e6e4d47 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java @@ -21,7 +21,8 @@ import org.mybatis.dynamic.sql.AbstractSingleValueCondition; -public class IsEqualTo<T> extends AbstractSingleValueCondition<T> { +public class IsEqualTo<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { private static final IsEqualTo<?> EMPTY = new IsEqualTo<Object>(-1) { @Override diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java index 2b3162e1a..93be70911 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java @@ -21,7 +21,8 @@ import org.mybatis.dynamic.sql.AbstractSingleValueCondition; -public class IsGreaterThan<T> extends AbstractSingleValueCondition<T> { +public class IsGreaterThan<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { private static final IsGreaterThan<?> EMPTY = new IsGreaterThan<Object>(-1) { @Override public Object value() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java index 7439ae4a8..8373bf352 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java @@ -21,7 +21,8 @@ import org.mybatis.dynamic.sql.AbstractSingleValueCondition; -public class IsGreaterThanOrEqualTo<T> extends AbstractSingleValueCondition<T> { +public class IsGreaterThanOrEqualTo<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { private static final IsGreaterThanOrEqualTo<?> EMPTY = new IsGreaterThanOrEqualTo<Object>(-1) { @Override public Object value() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java index 01614d6dc..3ed383fbd 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java @@ -21,7 +21,9 @@ import org.mybatis.dynamic.sql.AbstractSingleValueCondition; -public class IsLessThan<T> extends AbstractSingleValueCondition<T> { +public class IsLessThan<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { + private static final IsLessThan<?> EMPTY = new IsLessThan<Object>(-1) { @Override public Object value() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java index 20c3ed460..1b92e0c40 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java @@ -21,7 +21,8 @@ import org.mybatis.dynamic.sql.AbstractSingleValueCondition; -public class IsLessThanOrEqualTo<T> extends AbstractSingleValueCondition<T> { +public class IsLessThanOrEqualTo<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { private static final IsLessThanOrEqualTo<?> EMPTY = new IsLessThanOrEqualTo<Object>(-1) { @Override public Object value() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java index 5c7ba967a..e738bda4c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java @@ -21,7 +21,9 @@ import org.mybatis.dynamic.sql.AbstractSingleValueCondition; -public class IsLike<T> extends AbstractSingleValueCondition<T> { +public class IsLike<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { + private static final IsLike<?> EMPTY = new IsLike<Object>(-1) { @Override public Object value() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java index c7d8deefe..b1675a44d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java @@ -23,7 +23,8 @@ import org.mybatis.dynamic.sql.util.StringUtilities; public class IsLikeCaseInsensitive<T> extends AbstractSingleValueCondition<T> - implements CaseInsensitiveRenderableCondition<T> { + implements CaseInsensitiveRenderableCondition<T>, AbstractSingleValueCondition.Filterable<T>, + AbstractSingleValueCondition.Mappable<T> { private static final IsLikeCaseInsensitive<?> EMPTY = new IsLikeCaseInsensitive<>("") { //$NON-NLS-1$ @Override public String value() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java index e52ab0385..39070c2e8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java @@ -21,7 +21,8 @@ import org.mybatis.dynamic.sql.AbstractSingleValueCondition; -public class IsNotEqualTo<T> extends AbstractSingleValueCondition<T> { +public class IsNotEqualTo<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { private static final IsNotEqualTo<?> EMPTY = new IsNotEqualTo<Object>(-1) { @Override public Object value() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java index a2cf60310..a62dc3e9e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java @@ -21,7 +21,8 @@ import org.mybatis.dynamic.sql.AbstractSingleValueCondition; -public class IsNotLike<T> extends AbstractSingleValueCondition<T> { +public class IsNotLike<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { private static final IsNotLike<?> EMPTY = new IsNotLike<Object>(-1) { @Override public Object value() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java index 8aded422d..5b64ef5f5 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java @@ -23,7 +23,8 @@ import org.mybatis.dynamic.sql.util.StringUtilities; public class IsNotLikeCaseInsensitive<T> extends AbstractSingleValueCondition<T> - implements CaseInsensitiveRenderableCondition<T> { + implements CaseInsensitiveRenderableCondition<T>, AbstractSingleValueCondition.Filterable<T>, + AbstractSingleValueCondition.Mappable<T> { private static final IsNotLikeCaseInsensitive<?> EMPTY = new IsNotLikeCaseInsensitive<>("") { //$NON-NLS-1$ @Override public String value() { @@ -56,16 +57,7 @@ public IsNotLikeCaseInsensitive<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsNotLikeCaseInsensitive::empty, this); } - /** - * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a - * condition that will not render (this). - * - * @param mapper - * a mapping function to apply to the value, if renderable - * - * @return a new condition with the result of applying the mapper to the value of this condition, if renderable, - * otherwise a condition that will not render. - */ + @Override public <R> IsNotLikeCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsNotLikeCaseInsensitive::new, IsNotLikeCaseInsensitive::empty); } diff --git a/src/test/java/examples/mysql/IsLikeEscape.java b/src/test/java/examples/mysql/IsLikeEscape.java index 21b43fa13..6b8799abb 100644 --- a/src/test/java/examples/mysql/IsLikeEscape.java +++ b/src/test/java/examples/mysql/IsLikeEscape.java @@ -27,7 +27,8 @@ import org.mybatis.dynamic.sql.util.FragmentAndParameters; @NullMarked -public class IsLikeEscape<T> extends AbstractSingleValueCondition<T> { +public class IsLikeEscape<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { private static final IsLikeEscape<?> EMPTY = new IsLikeEscape<Object>(-1, null) { @Override public Object value() { diff --git a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt index 06dca6609..b47f09110 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt @@ -10,7 +10,8 @@ import org.mybatis.dynamic.sql.util.FragmentAndParameters sealed class KIsLikeEscape<T : Any>( value: T, private val escapeCharacter: Char? = null -) : AbstractSingleValueCondition<T>(value) { +) : AbstractSingleValueCondition<T>(value), AbstractSingleValueCondition.Filterable<T>, + AbstractSingleValueCondition.Mappable<T> { override fun operator(): String = "like" From 43fdf0651330c71c810e49a730e47efbfc28d9bb Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 14 Mar 2025 10:53:52 -0400 Subject: [PATCH 212/260] Make filter and map optional on list value conditions --- .../sql/AbstractListValueCondition.java | 70 +++++++++++++------ .../dynamic/sql/where/condition/IsIn.java | 6 +- .../where/condition/IsInCaseInsensitive.java | 3 +- .../IsInCaseInsensitiveWhenPresent.java | 3 +- .../sql/where/condition/IsInWhenPresent.java | 15 ++-- .../dynamic/sql/where/condition/IsNotIn.java | 6 +- .../condition/IsNotInCaseInsensitive.java | 3 +- .../IsNotInCaseInsensitiveWhenPresent.java | 3 +- .../where/condition/IsNotInWhenPresent.java | 15 ++-- 9 files changed, 72 insertions(+), 52 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java index 066012e28..41c6a56e2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java @@ -73,26 +73,6 @@ protected <R, S extends AbstractListValueCondition<R>> S mapSupport(Function<? s } } - /** - * If not empty, apply the predicate to each value in the list and return a new condition with the filtered values. - * Else returns an empty condition (this). - * - * @param predicate predicate applied to the values, if not empty - * - * @return a new condition with filtered values if renderable, otherwise an empty condition - */ - public abstract AbstractListValueCondition<T> filter(Predicate<? super T> predicate); - - /** - * If not empty, apply the mapping to each value in the list return a new condition with the mapped values. - * Else return an empty condition (this). - * - * @param mapper a mapping function to apply to the values, if not empty - * @param <R> type of the new condition - * @return a new condition with mapped values if renderable, otherwise an empty condition - */ - public abstract <R> AbstractListValueCondition<R> map(Function<? super T, ? extends R> mapper); - public abstract String operator(); @Override @@ -110,4 +90,54 @@ private FragmentAndParameters toFragmentAndParameters(T value, RenderingContext .withParameter(parameterInfo.parameterMapKey(), leftColumn.convertParameterType(value)) .build(); } + + /** + * Conditions may implement Filterable to add optionality to rendering. + * + * <p>If a condition is Filterable, then a user may add a filter to the usage of the condition that makes a decision + * whether to render the condition at runtime. Conditions that fail the filter will be dropped from the + * rendered SQL. + * + * <p>Implementations of Filterable may call + * {@link AbstractListValueCondition#filterSupport(Predicate, Function, AbstractListValueCondition, Supplier)} as + * a common implementation of the filtering algorithm. + * + * @param <T> the Java type related to the database column type + */ + public interface Filterable<T> { + /** + * If renderable and the value matches the predicate, returns this condition. Else returns a condition + * that will not render. + * + * @param predicate predicate applied to the value, if renderable + * @return this condition if renderable and the value matches the predicate, otherwise a condition + * that will not render. + */ + AbstractListValueCondition<T> filter(Predicate<? super T> predicate); + } + + /** + * Conditions may implement Mappable to alter condition values or types during rendering. + * + * <p>If a condition is Mappable, then a user may add a mapper to the usage of the condition that can alter the + * values of a condition, or change that datatype. + * + * <p>Implementations of Mappable may call + * {@link AbstractListValueCondition#mapSupport(Function, Function, Supplier)} as + * a common implementation of the mapping algorithm. + * + * @param <T> the Java type related to the database column type + */ + public interface Mappable<T> { + /** + * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a + * condition that will not render (this). + * + * @param mapper a mapping function to apply to the value, if renderable + * @param <R> type of the new condition + * @return a new condition with the result of applying the mapper to the value of this condition, + * if renderable, otherwise a condition that will not render. + */ + <R> AbstractListValueCondition<R> map(Function<? super T, ? extends R> mapper); + } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java index 67b6fff08..8beeacc8d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java @@ -25,7 +25,8 @@ import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.Validator; -public class IsIn<T> extends AbstractListValueCondition<T> { +public class IsIn<T> extends AbstractListValueCondition<T> + implements AbstractListValueCondition.Filterable<T>, AbstractListValueCondition.Mappable<T>{ private static final IsIn<?> EMPTY = new IsIn<>(Collections.emptyList()); public static <T> IsIn<T> empty() { @@ -56,8 +57,7 @@ public IsIn<T> filter(Predicate<? super T> predicate) { @Override public <R> IsIn<R> map(Function<? super T, ? extends R> mapper) { - Function<Collection<R>, IsIn<R>> constructor = IsIn::new; - return mapSupport(mapper, constructor, IsIn::empty); + return mapSupport(mapper, IsIn::new, IsIn::empty); } @SafeVarargs diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java index 6d0219dcd..6ca85d554 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java @@ -27,7 +27,8 @@ import org.mybatis.dynamic.sql.util.Validator; public class IsInCaseInsensitive<T> extends AbstractListValueCondition<T> - implements CaseInsensitiveRenderableCondition<T> { + implements CaseInsensitiveRenderableCondition<T>, AbstractListValueCondition.Filterable<T>, + AbstractListValueCondition.Mappable<T> { private static final IsInCaseInsensitive<?> EMPTY = new IsInCaseInsensitive<>(Collections.emptyList()); public static <T> IsInCaseInsensitive<T> empty() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java index de17a8394..6afdb486d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java @@ -26,7 +26,8 @@ import org.mybatis.dynamic.sql.AbstractListValueCondition; public class IsInCaseInsensitiveWhenPresent<T> extends AbstractListValueCondition<T> - implements CaseInsensitiveRenderableCondition<T> { + implements CaseInsensitiveRenderableCondition<T>, AbstractListValueCondition.Filterable<T>, + AbstractListValueCondition.Mappable<T> { private static final IsInCaseInsensitiveWhenPresent<?> EMPTY = new IsInCaseInsensitiveWhenPresent<>(Collections.emptyList()); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java index ea1bfe509..5c431fea3 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java @@ -25,7 +25,8 @@ import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; -public class IsInWhenPresent<T> extends AbstractListValueCondition<T> { +public class IsInWhenPresent<T> extends AbstractListValueCondition<T> + implements AbstractListValueCondition.Filterable<T>, AbstractListValueCondition.Mappable<T>{ private static final IsInWhenPresent<?> EMPTY = new IsInWhenPresent<>(Collections.emptyList()); public static <T> IsInWhenPresent<T> empty() { @@ -48,17 +49,9 @@ public IsInWhenPresent<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsInWhenPresent::new, this, IsInWhenPresent::empty); } - /** - * If not empty, apply the mapping to each value in the list return a new condition with the mapped values. - * Else return an empty condition (this). - * - * @param mapper a mapping function to apply to the values, if not empty - * @param <R> type of the new condition - * @return a new condition with mapped values if renderable, otherwise an empty condition - */ + @Override public <R> IsInWhenPresent<R> map(Function<? super T, ? extends R> mapper) { - Function<Collection<R>, IsInWhenPresent<R>> constructor = IsInWhenPresent::new; - return mapSupport(mapper, constructor, IsInWhenPresent::empty); + return mapSupport(mapper, IsInWhenPresent::new, IsInWhenPresent::empty); } @SafeVarargs diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java index f22c504c8..33f5d14c7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java @@ -25,7 +25,8 @@ import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.Validator; -public class IsNotIn<T> extends AbstractListValueCondition<T> { +public class IsNotIn<T> extends AbstractListValueCondition<T> + implements AbstractListValueCondition.Filterable<T>, AbstractListValueCondition.Mappable<T>{ private static final IsNotIn<?> EMPTY = new IsNotIn<>(Collections.emptyList()); public static <T> IsNotIn<T> empty() { @@ -56,8 +57,7 @@ public IsNotIn<T> filter(Predicate<? super T> predicate) { @Override public <R> IsNotIn<R> map(Function<? super T, ? extends R> mapper) { - Function<Collection<R>, IsNotIn<R>> constructor = IsNotIn::new; - return mapSupport(mapper, constructor, IsNotIn::empty); + return mapSupport(mapper, IsNotIn::new, IsNotIn::empty); } @SafeVarargs diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java index 3513d022c..7ade40938 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java @@ -27,7 +27,8 @@ import org.mybatis.dynamic.sql.util.Validator; public class IsNotInCaseInsensitive<T> extends AbstractListValueCondition<T> - implements CaseInsensitiveRenderableCondition<T> { + implements CaseInsensitiveRenderableCondition<T>, AbstractListValueCondition.Filterable<T>, + AbstractListValueCondition.Mappable<T> { private static final IsNotInCaseInsensitive<?> EMPTY = new IsNotInCaseInsensitive<>(Collections.emptyList()); public static <T> IsNotInCaseInsensitive<T> empty() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java index bbff09bbe..9d57e7623 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java @@ -26,7 +26,8 @@ import org.mybatis.dynamic.sql.AbstractListValueCondition; public class IsNotInCaseInsensitiveWhenPresent<T> extends AbstractListValueCondition<T> - implements CaseInsensitiveRenderableCondition<T> { + implements CaseInsensitiveRenderableCondition<T>, AbstractListValueCondition.Filterable<T>, + AbstractListValueCondition.Mappable<T> { private static final IsNotInCaseInsensitiveWhenPresent<?> EMPTY = new IsNotInCaseInsensitiveWhenPresent<>(Collections.emptyList()); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java index 1c4b570a9..ddc8e5470 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java @@ -24,7 +24,8 @@ import org.mybatis.dynamic.sql.AbstractListValueCondition; -public class IsNotInWhenPresent<T> extends AbstractListValueCondition<T> { +public class IsNotInWhenPresent<T> extends AbstractListValueCondition<T> + implements AbstractListValueCondition.Filterable<T>, AbstractListValueCondition.Mappable<T>{ private static final IsNotInWhenPresent<?> EMPTY = new IsNotInWhenPresent<>(Collections.emptyList()); public static <T> IsNotInWhenPresent<T> empty() { @@ -47,17 +48,9 @@ public IsNotInWhenPresent<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsNotInWhenPresent::new, this, IsNotInWhenPresent::empty); } - /** - * If not empty, apply the mapping to each value in the list return a new condition with the mapped values. - * Else return an empty condition (this). - * - * @param mapper a mapping function to apply to the values, if not empty - * @param <R> type of the new condition - * @return a new condition with mapped values if renderable, otherwise an empty condition - */ + @Override public <R> IsNotInWhenPresent<R> map(Function<? super T, ? extends R> mapper) { - Function<Collection<R>, IsNotInWhenPresent<R>> constructor = IsNotInWhenPresent::new; - return mapSupport(mapper, constructor, IsNotInWhenPresent::empty); + return mapSupport(mapper, IsNotInWhenPresent::new, IsNotInWhenPresent::empty); } @SafeVarargs From 1a2b9189270dd1b2c8f0bb02e1a8bbd6820da5b1 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 14 Mar 2025 11:08:08 -0400 Subject: [PATCH 213/260] Make filter and map optional on two value conditions --- .../sql/AbstractTwoValueCondition.java | 120 +++++++++++------- .../sql/where/condition/IsBetween.java | 3 +- .../sql/where/condition/IsNotBetween.java | 3 +- 3 files changed, 79 insertions(+), 47 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java index 15a5b6ffe..6cceff16e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java @@ -67,51 +67,6 @@ protected <R, S extends AbstractTwoValueCondition<R>> S mapSupport(Function<? su } } - /** - * If renderable and the values match the predicate, returns this condition. Else returns a condition - * that will not render. - * - * @param predicate predicate applied to the values, if renderable - * @return this condition if renderable and the values match the predicate, otherwise a condition - * that will not render. - */ - public abstract AbstractTwoValueCondition<T> filter(BiPredicate<? super T, ? super T> predicate); - - /** - * If renderable and both values match the predicate, returns this condition. Else returns a condition - * that will not render. This function implements a short-circuiting test. If the - * first value does not match the predicate, then the second value will not be tested. - * - * @param predicate predicate applied to both values, if renderable - * @return this condition if renderable and the values match the predicate, otherwise a condition - * that will not render. - */ - public abstract AbstractTwoValueCondition<T> filter(Predicate<? super T> predicate); - - /** - * If renderable, apply the mappings to the values and return a new condition with the new values. Else return a - * condition that will not render (this). - * - * @param mapper1 a mapping function to apply to the first value, if renderable - * @param mapper2 a mapping function to apply to the second value, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mappers to the values of this condition, - * if renderable, otherwise a condition that will not render. - */ - public abstract <R> AbstractTwoValueCondition<R> map(Function<? super T, ? extends R> mapper1, - Function<? super T, ? extends R> mapper2); - - /** - * If renderable, apply the mapping to both values and return a new condition with the new values. Else return a - * condition that will not render (this). - * - * @param mapper a mapping function to apply to both values, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mappers to the values of this condition, - * if renderable, otherwise a condition that will not render. - */ - public abstract <R> AbstractTwoValueCondition<R> map(Function<? super T, ? extends R> mapper); - public abstract String operator1(); public abstract String operator2(); @@ -131,4 +86,79 @@ public FragmentAndParameters renderCondition(RenderingContext renderingContext, .withParameter(parameterInfo2.parameterMapKey(), leftColumn.convertParameterType(value2())) .build(); } + + /** + * Conditions may implement Filterable to add optionality to rendering. + * + * <p>If a condition is Filterable, then a user may add a filter to the usage of the condition that makes a decision + * whether to render the condition at runtime. Conditions that fail the filter will be dropped from the + * rendered SQL. + * + * <p>Implementations of Filterable may call + * {@link AbstractTwoValueCondition#filterSupport(Predicate, Supplier, AbstractTwoValueCondition)} + * or {@link AbstractTwoValueCondition#filterSupport(BiPredicate, Supplier, AbstractTwoValueCondition)} as + * a common implementation of the filtering algorithm. + * + * @param <T> the Java type related to the database column type + */ + public interface Filterable<T> { + /** + * If renderable and the values match the predicate, returns this condition. Else returns a condition + * that will not render. + * + * @param predicate predicate applied to the values, if renderable + * @return this condition if renderable and the values match the predicate, otherwise a condition + * that will not render. + */ + AbstractTwoValueCondition<T> filter(BiPredicate<? super T, ? super T> predicate); + + /** + * If renderable and both values match the predicate, returns this condition. Else returns a condition + * that will not render. This function implements a short-circuiting test. If the + * first value does not match the predicate, then the second value will not be tested. + * + * @param predicate predicate applied to both values, if renderable + * @return this condition if renderable and the values match the predicate, otherwise a condition + * that will not render. + */ + AbstractTwoValueCondition<T> filter(Predicate<? super T> predicate); + } + + /** + * Conditions may implement Mappable to alter condition values or types during rendering. + * + * <p>If a condition is Mappable, then a user may add a mapper to the usage of the condition that can alter the + * values of a condition, or change that datatype. + * + * <p>Implementations of Mappable may call + * {@link AbstractTwoValueCondition#mapSupport(Function, Function, BiFunction, Supplier)} as + * a common implementation of the mapping algorithm. + * + * @param <T> the Java type related to the database column type + */ + public interface Mappable<T> { + /** + * If renderable, apply the mappings to the values and return a new condition with the new values. Else return a + * condition that will not render (this). + * + * @param mapper1 a mapping function to apply to the first value, if renderable + * @param mapper2 a mapping function to apply to the second value, if renderable + * @param <R> type of the new condition + * @return a new condition with the result of applying the mappers to the values of this condition, + * if renderable, otherwise a condition that will not render. + */ + <R> AbstractTwoValueCondition<R> map(Function<? super T, ? extends R> mapper1, + Function<? super T, ? extends R> mapper2); + + /** + * If renderable, apply the mapping to both values and return a new condition with the new values. Else return a + * condition that will not render (this). + * + * @param mapper a mapping function to apply to both values, if renderable + * @param <R> type of the new condition + * @return a new condition with the result of applying the mappers to the values of this condition, + * if renderable, otherwise a condition that will not render. + */ + <R> AbstractTwoValueCondition<R> map(Function<? super T, ? extends R> mapper); + } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java index 0d554d0fc..0e6700fb0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java @@ -23,7 +23,8 @@ import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractTwoValueCondition; -public class IsBetween<T> extends AbstractTwoValueCondition<T> { +public class IsBetween<T> extends AbstractTwoValueCondition<T> + implements AbstractTwoValueCondition.Filterable<T>, AbstractTwoValueCondition.Mappable<T> { private static final IsBetween<?> EMPTY = new IsBetween<Object>(-1, -1) { @Override public Object value1() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java index f7eb98f52..6a515d4ac 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java @@ -23,7 +23,8 @@ import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractTwoValueCondition; -public class IsNotBetween<T> extends AbstractTwoValueCondition<T> { +public class IsNotBetween<T> extends AbstractTwoValueCondition<T> + implements AbstractTwoValueCondition.Filterable<T>, AbstractTwoValueCondition.Mappable<T> { private static final IsNotBetween<?> EMPTY = new IsNotBetween<Object>(-1, -1) { @Override public Object value1() { From 4594a5f4995f7d76d20eb5366fcca429ce4c412b Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 14 Mar 2025 11:19:14 -0400 Subject: [PATCH 214/260] Update docs --- src/site/markdown/docs/extending.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/site/markdown/docs/extending.md b/src/site/markdown/docs/extending.md index eabee1e03..a1fee9adb 100644 --- a/src/site/markdown/docs/extending.md +++ b/src/site/markdown/docs/extending.md @@ -304,7 +304,8 @@ Here's an example of implementing a LIKE condition that supports ESCAPE: ```java @NullMarked -public class IsLikeEscape<T> extends AbstractSingleValueCondition<T> { +public class IsLikeEscape<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { private static final IsLikeEscape<?> EMPTY = new IsLikeEscape<Object>(-1, null) { @Override public Object value() { @@ -354,6 +355,7 @@ public class IsLikeEscape<T> extends AbstractSingleValueCondition<T> { return filterSupport(predicate, IsLikeEscape::empty, this); } + @Override public <R> IsLikeEscape<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, v -> new IsLikeEscape<>(v, escapeCharacter), IsLikeEscape::empty); } @@ -374,4 +376,5 @@ Important notes: 2. The class constructor accepts an escape character that will be rendered into an ESCAPE phrase 3. The class overrides `renderCondition` and changes the library generated `FragmentAndParameters` to add the ESCAPE phrase. **This is the key to what's needed to implement a custom condition.** -4. The class provides `map` and `filter` functions as is expected for any condition in the library +4. The class implements `Filterable` and `Mappable` to provide `filter` and `map` functions as is expected for most + conditions in the library From 0acbda7617d41b0a5608beccda8074499fbe436b Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 14 Mar 2025 12:32:53 -0400 Subject: [PATCH 215/260] Update docs --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b333e3ab..cec9f683f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,7 +103,8 @@ Runtime behavior changes: - Rendering for all the conditions (isEqualTo, etc.) has changed. This should be transparent to most users unless you have coded a direct implementation of `VisitableCondition`. The change makes it easier to code custom conditions that are not supported by the library out of the box. The statement renderers now call methods `renderCondition` and - `renderLeftColumn` that you can override to implement any rendering you need. + `renderLeftColumn` that you can override to implement any rendering you need. In addition, we've made `filter` and + `map` support optional if you implement custom conditions ## Release 1.5.2 - June 3, 2024 From 1df401a0c1e7493ea6cb0f37423bee2c4a8668e4 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 14 Mar 2025 12:54:59 -0400 Subject: [PATCH 216/260] Polishing --- .../sql/where/condition/SupplierTest.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java index e1362d48f..b85a7f412 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java @@ -260,28 +260,28 @@ void testIsLikeNull() { @Test void testIsLikeCaseInsensitive() { - IsLikeCaseInsensitive cond = SqlBuilder.isLikeCaseInsensitive(() -> "%f%"); + IsLikeCaseInsensitive<String> cond = SqlBuilder.isLikeCaseInsensitive(() -> "%f%"); assertThat(cond.value()).isEqualTo("%F%"); assertThat(cond.isEmpty()).isFalse(); } @Test void testIsLikeCaseInsensitiveNull() { - IsLikeCaseInsensitive cond = SqlBuilder.isLikeCaseInsensitive(() -> null); + IsLikeCaseInsensitive<String> cond = SqlBuilder.isLikeCaseInsensitive(() -> null); assertThat(cond.value()).isNull(); assertThat(cond.isEmpty()).isFalse(); } @Test void testIsLikeCaseInsensitiveWhenPresent() { - IsLikeCaseInsensitive cond = SqlBuilder.isLikeCaseInsensitiveWhenPresent(() -> "%f%"); + IsLikeCaseInsensitive<String> cond = SqlBuilder.isLikeCaseInsensitiveWhenPresent(() -> "%f%"); assertThat(cond.value()).isEqualTo("%F%"); assertThat(cond.isEmpty()).isFalse(); } @Test void testIsLikeCaseInsensitiveWhenPresentNull() { - IsLikeCaseInsensitive cond = SqlBuilder.isLikeCaseInsensitiveWhenPresent(() -> null); + IsLikeCaseInsensitive<String> cond = SqlBuilder.isLikeCaseInsensitiveWhenPresent(() -> null); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -330,28 +330,28 @@ void testIsNotLikeWhenPresentNull() { @Test void testIsNotLikeCaseInsensitive() { - IsNotLikeCaseInsensitive cond = SqlBuilder.isNotLikeCaseInsensitive(() -> "%f%"); + IsNotLikeCaseInsensitive<String> cond = SqlBuilder.isNotLikeCaseInsensitive(() -> "%f%"); assertThat(cond.value()).isEqualTo("%F%"); assertThat(cond.isEmpty()).isFalse(); } @Test void testIsNotLikeCaseInsensitiveNull() { - IsNotLikeCaseInsensitive cond = SqlBuilder.isNotLikeCaseInsensitive(() -> null); + IsNotLikeCaseInsensitive<String> cond = SqlBuilder.isNotLikeCaseInsensitive(() -> null); assertThat(cond.value()).isNull(); assertThat(cond.isEmpty()).isFalse(); } @Test void testIsNotLikeCaseInsensitiveWhenPresent() { - IsNotLikeCaseInsensitive cond = SqlBuilder.isNotLikeCaseInsensitiveWhenPresent(() -> "%f%"); + IsNotLikeCaseInsensitive<String> cond = SqlBuilder.isNotLikeCaseInsensitiveWhenPresent(() -> "%f%"); assertThat(cond.value()).isEqualTo("%F%"); assertThat(cond.isEmpty()).isFalse(); } @Test void testIsNotLikeCaseInsensitiveWhenPresentNull() { - IsNotLikeCaseInsensitive cond = SqlBuilder.isNotLikeCaseInsensitiveWhenPresent(() -> null); + IsNotLikeCaseInsensitive<String> cond = SqlBuilder.isNotLikeCaseInsensitiveWhenPresent(() -> null); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } From 60b10b04695e58c5c9c52d6e446e6c5904807e74 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 14 Mar 2025 18:10:39 +0000 Subject: [PATCH 217/260] Update junit5 monorepo to v5.12.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f26ba6481..03b9bc69f 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ <java.release.version>17</java.release.version> <java.test.version>17</java.test.version> <java.test.release.version>17</java.test.release.version> - <junit.jupiter.version>5.12.0</junit.jupiter.version> + <junit.jupiter.version>5.12.1</junit.jupiter.version> <spring.batch.version>5.2.1</spring.batch.version> <checkstyle.config>checkstyle-override.xml</checkstyle.config> From 7cb17bd932f150a6765b0751244917b4c22599c6 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 14 Mar 2025 16:17:05 -0400 Subject: [PATCH 218/260] Coverage --- .../dynamic/sql/util/StringUtilities.java | 6 +++ .../where/condition/IsInCaseInsensitive.java | 13 +++++++ .../IsInCaseInsensitiveWhenPresent.java | 14 +++++++ .../condition/IsLikeCaseInsensitive.java | 13 +++++++ .../condition/IsNotInCaseInsensitive.java | 13 +++++++ .../IsNotInCaseInsensitiveWhenPresent.java | 14 +++++++ .../condition/IsNotLikeCaseInsensitive.java | 13 +++++++ .../sql/where/condition/FilterAndMapTest.java | 37 +++++++++++++++++++ 8 files changed, 123 insertions(+) diff --git a/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java b/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java index 2b57c748e..25a7e390c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java @@ -15,6 +15,8 @@ */ package org.mybatis.dynamic.sql.util; +import java.util.function.Function; + import org.jspecify.annotations.Nullable; public interface StringUtilities { @@ -59,4 +61,8 @@ static String formatConstantForSQL(String in) { String escaped = in.replace("'", "''"); //$NON-NLS-1$ //$NON-NLS-2$ return "'" + escaped + "'"; //$NON-NLS-1$ //$NON-NLS-2$ } + + static Function<String, String> mapToUpperCase(Function<String, String> f) { + return f.andThen(String::toUpperCase); + } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java index 6ca85d554..dc3b0f8f1 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java @@ -57,6 +57,19 @@ public IsInCaseInsensitive<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsInCaseInsensitive::new, this, IsInCaseInsensitive::empty); } + /** + * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a + * condition that will not render (this). + * + * <p>This function DOES NOT automatically transform values to uppercase, so it potentially creates a + * case-sensitive query. For String conditions you can use {@link StringUtilities#mapToUpperCase(Function)} + * to add an uppercase transform after your mapping function. + * + * @param mapper a mapping function to apply to the value, if renderable + * @param <R> type of the new condition + * @return a new condition with the result of applying the mapper to the value of this condition, + * if renderable, otherwise a condition that will not render. + */ @Override public <R> IsInCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsInCaseInsensitive::new, IsInCaseInsensitive::empty); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java index 6afdb486d..283e62fc7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java @@ -24,6 +24,7 @@ import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; +import org.mybatis.dynamic.sql.util.StringUtilities; public class IsInCaseInsensitiveWhenPresent<T> extends AbstractListValueCondition<T> implements CaseInsensitiveRenderableCondition<T>, AbstractListValueCondition.Filterable<T>, @@ -52,6 +53,19 @@ public IsInCaseInsensitiveWhenPresent<T> filter(Predicate<? super T> predicate) IsInCaseInsensitiveWhenPresent::empty); } + /** + * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a + * condition that will not render (this). + * + * <p>This function DOES NOT automatically transform values to uppercase, so it potentially creates a + * case-sensitive query. For String conditions you can use {@link StringUtilities#mapToUpperCase(Function)} + * to add an uppercase transform after your mapping function. + * + * @param mapper a mapping function to apply to the value, if renderable + * @param <R> type of the new condition + * @return a new condition with the result of applying the mapper to the value of this condition, + * if renderable, otherwise a condition that will not render. + */ @Override public <R> IsInCaseInsensitiveWhenPresent<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsInCaseInsensitiveWhenPresent::new, IsInCaseInsensitiveWhenPresent::empty); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java index b1675a44d..6b569b32d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java @@ -57,6 +57,19 @@ public IsLikeCaseInsensitive<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsLikeCaseInsensitive::empty, this); } + /** + * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a + * condition that will not render (this). + * + * <p>This function DOES NOT automatically transform values to uppercase, so it potentially creates a + * case-sensitive query. For String conditions you can use {@link StringUtilities#mapToUpperCase(Function)} + * to add an uppercase transform after your mapping function. + * + * @param mapper a mapping function to apply to the value, if renderable + * @param <R> type of the new condition + * @return a new condition with the result of applying the mapper to the value of this condition, + * if renderable, otherwise a condition that will not render. + */ @Override public <R> IsLikeCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsLikeCaseInsensitive::new, IsLikeCaseInsensitive::empty); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java index 7ade40938..8731d5b64 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java @@ -57,6 +57,19 @@ public IsNotInCaseInsensitive<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsNotInCaseInsensitive::new, this, IsNotInCaseInsensitive::empty); } + /** + * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a + * condition that will not render (this). + * + * <p>This function DOES NOT automatically transform values to uppercase, so it potentially creates a + * case-sensitive query. For String conditions you can use {@link StringUtilities#mapToUpperCase(Function)} + * to add an uppercase transform after your mapping function. + * + * @param mapper a mapping function to apply to the value, if renderable + * @param <R> type of the new condition + * @return a new condition with the result of applying the mapper to the value of this condition, + * if renderable, otherwise a condition that will not render. + */ @Override public <R> IsNotInCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsNotInCaseInsensitive::new, IsNotInCaseInsensitive::empty); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java index 9d57e7623..438e1c5ed 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java @@ -24,6 +24,7 @@ import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; +import org.mybatis.dynamic.sql.util.StringUtilities; public class IsNotInCaseInsensitiveWhenPresent<T> extends AbstractListValueCondition<T> implements CaseInsensitiveRenderableCondition<T>, AbstractListValueCondition.Filterable<T>, @@ -52,6 +53,19 @@ public IsNotInCaseInsensitiveWhenPresent<T> filter(Predicate<? super T> predicat this, IsNotInCaseInsensitiveWhenPresent::empty); } + /** + * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a + * condition that will not render (this). + * + * <p>This function DOES NOT automatically transform values to uppercase, so it potentially creates a + * case-sensitive query. For String conditions you can use {@link StringUtilities#mapToUpperCase(Function)} + * to add an uppercase transform after your mapping function. + * + * @param mapper a mapping function to apply to the value, if renderable + * @param <R> type of the new condition + * @return a new condition with the result of applying the mapper to the value of this condition, + * if renderable, otherwise a condition that will not render. + */ @Override public <R> IsNotInCaseInsensitiveWhenPresent<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsNotInCaseInsensitiveWhenPresent::new, IsNotInCaseInsensitiveWhenPresent::empty); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java index 5b64ef5f5..8eb65d772 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java @@ -57,6 +57,19 @@ public IsNotLikeCaseInsensitive<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsNotLikeCaseInsensitive::empty, this); } + /** + * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a + * condition that will not render (this). + * + * <p>This function DOES NOT automatically transform values to uppercase, so it potentially creates a + * case-sensitive query. For String conditions you can use {@link StringUtilities#mapToUpperCase(Function)} + * to add an uppercase transform after your mapping function. + * + * @param mapper a mapping function to apply to the value, if renderable + * @param <R> type of the new condition + * @return a new condition with the result of applying the mapper to the value of this condition, + * if renderable, otherwise a condition that will not render. + */ @Override public <R> IsNotLikeCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsNotLikeCaseInsensitive::new, IsNotLikeCaseInsensitive::empty); diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java index 8c8f35eb5..7d4e4505e 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java @@ -24,6 +24,7 @@ import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.SqlBuilder; +import org.mybatis.dynamic.sql.util.StringUtilities; class FilterAndMapTest { @Test @@ -533,4 +534,40 @@ void testNotBetweenMapWithSingleMapper() { assertThat(cond.value2()).isEqualTo(4); } + @Test + void testMappingAnEmptyListCondition() { + var cond = SqlBuilder.isNotIn("Fred", "Wilma"); + var filtered = cond.filter(s -> false); + var mapped = filtered.map(s -> s); + assertThat(mapped.isEmpty()).isTrue(); + assertThat(filtered).isSameAs(mapped); + } + + @Test + void testIsInCaseInsensitiveWhenPresentMap() { + var cond = SqlBuilder.isInCaseInsensitiveWhenPresent("Fred", "Wilma"); + var mapped = cond.map(s -> s + " Flintstone"); + assertThat(mapped.values().toList()).containsExactly("FRED Flintstone", "WILMA Flintstone"); + } + + @Test + void testIsInCaseInsensitiveWhenPresentMapCaseInsensitive() { + var cond = SqlBuilder.isInCaseInsensitiveWhenPresent("Fred", "Wilma"); + var mapped = cond.map(StringUtilities.mapToUpperCase(s -> s + " Flintstone")); + assertThat(mapped.values().toList()).containsExactly("FRED FLINTSTONE", "WILMA FLINTSTONE"); + } + + @Test + void testIsNotInCaseInsensitiveWhenPresentMap() { + var cond = SqlBuilder.isNotInCaseInsensitiveWhenPresent("Fred", "Wilma"); + var mapped = cond.map(s -> s + " Flintstone"); + assertThat(mapped.values().toList()).containsExactly("FRED Flintstone", "WILMA Flintstone"); + } + + @Test + void testIsNotInCaseInsensitiveWhenPresentMapCaseInsensitive() { + var cond = SqlBuilder.isNotInCaseInsensitiveWhenPresent("Fred", "Wilma"); + var mapped = cond.map(StringUtilities.mapToUpperCase(s -> s + " Flintstone")); + assertThat(mapped.values().toList()).containsExactly("FRED FLINTSTONE", "WILMA FLINTSTONE"); + } } From 2a3be8185fae1ecbdb3dc73b33ee4f3be4ef4cb0 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Sat, 15 Mar 2025 09:36:06 -0400 Subject: [PATCH 219/260] Improve Case Insensitive Conditions Make the case-insensitive conditions work as expected. With a map operation, the values will now be upper-cased if possible. --- .../dynamic/sql/util/StringUtilities.java | 12 ++++++++---- .../where/condition/IsInCaseInsensitive.java | 19 +++---------------- .../IsInCaseInsensitiveWhenPresent.java | 18 ++---------------- .../condition/IsLikeCaseInsensitive.java | 18 ++---------------- .../condition/IsNotInCaseInsensitive.java | 18 ++---------------- .../IsNotInCaseInsensitiveWhenPresent.java | 18 ++---------------- .../condition/IsNotLikeCaseInsensitive.java | 18 ++---------------- .../dynamic/sql/util/StringUtilitiesTest.java | 12 ++++++++++++ .../sql/where/condition/FilterAndMapTest.java | 19 ++----------------- 9 files changed, 35 insertions(+), 117 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java b/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java index 25a7e390c..532391856 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java @@ -15,8 +15,6 @@ */ package org.mybatis.dynamic.sql.util; -import java.util.function.Function; - import org.jspecify.annotations.Nullable; public interface StringUtilities { @@ -62,7 +60,13 @@ static String formatConstantForSQL(String in) { return "'" + escaped + "'"; //$NON-NLS-1$ //$NON-NLS-2$ } - static Function<String, String> mapToUpperCase(Function<String, String> f) { - return f.andThen(String::toUpperCase); + static <T> T upperCaseIfPossible(T value) { + if (value instanceof String) { + @SuppressWarnings("unchecked") + T t = (T) safelyUpperCase((String) value); + return t; + } + + return value; } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java index dc3b0f8f1..a3777188a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java @@ -20,6 +20,7 @@ import java.util.Collections; import java.util.function.Function; import java.util.function.Predicate; +import java.util.stream.Collectors; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; @@ -38,7 +39,7 @@ public static <T> IsInCaseInsensitive<T> empty() { } protected IsInCaseInsensitive(Collection<T> values) { - super(values); + super(values.stream().map(StringUtilities::upperCaseIfPossible).collect(Collectors.toList())); } @Override @@ -57,19 +58,6 @@ public IsInCaseInsensitive<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsInCaseInsensitive::new, this, IsInCaseInsensitive::empty); } - /** - * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a - * condition that will not render (this). - * - * <p>This function DOES NOT automatically transform values to uppercase, so it potentially creates a - * case-sensitive query. For String conditions you can use {@link StringUtilities#mapToUpperCase(Function)} - * to add an uppercase transform after your mapping function. - * - * @param mapper a mapping function to apply to the value, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mapper to the value of this condition, - * if renderable, otherwise a condition that will not render. - */ @Override public <R> IsInCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsInCaseInsensitive::new, IsInCaseInsensitive::empty); @@ -80,7 +68,6 @@ public static IsInCaseInsensitive<String> of(String... values) { } public static IsInCaseInsensitive<String> of(Collection<String> values) { - // Keep the null safe upper case utility for backwards compatibility in case someone passes in a null - return new IsInCaseInsensitive<>(values.stream().map(StringUtilities::safelyUpperCase).toList()); + return new IsInCaseInsensitive<>(values); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java index 283e62fc7..fee942f7d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java @@ -39,7 +39,7 @@ public static <T> IsInCaseInsensitiveWhenPresent<T> empty() { } protected IsInCaseInsensitiveWhenPresent(Collection<T> values) { - super(values); + super(values.stream().filter(Objects::nonNull).map(StringUtilities::upperCaseIfPossible).toList()); } @Override @@ -53,19 +53,6 @@ public IsInCaseInsensitiveWhenPresent<T> filter(Predicate<? super T> predicate) IsInCaseInsensitiveWhenPresent::empty); } - /** - * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a - * condition that will not render (this). - * - * <p>This function DOES NOT automatically transform values to uppercase, so it potentially creates a - * case-sensitive query. For String conditions you can use {@link StringUtilities#mapToUpperCase(Function)} - * to add an uppercase transform after your mapping function. - * - * @param mapper a mapping function to apply to the value, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mapper to the value of this condition, - * if renderable, otherwise a condition that will not render. - */ @Override public <R> IsInCaseInsensitiveWhenPresent<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsInCaseInsensitiveWhenPresent::new, IsInCaseInsensitiveWhenPresent::empty); @@ -76,7 +63,6 @@ public static IsInCaseInsensitiveWhenPresent<String> of(@Nullable String... valu } public static IsInCaseInsensitiveWhenPresent<String> of(Collection<@Nullable String> values) { - return new IsInCaseInsensitiveWhenPresent<>( - values.stream().filter(Objects::nonNull).map(String::toUpperCase).toList()); + return new IsInCaseInsensitiveWhenPresent<>(values); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java index 6b569b32d..e4d31c126 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java @@ -44,7 +44,7 @@ public static <T> IsLikeCaseInsensitive<T> empty() { } protected IsLikeCaseInsensitive(T value) { - super(value); + super(StringUtilities.upperCaseIfPossible(value)); } @Override @@ -57,26 +57,12 @@ public IsLikeCaseInsensitive<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsLikeCaseInsensitive::empty, this); } - /** - * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a - * condition that will not render (this). - * - * <p>This function DOES NOT automatically transform values to uppercase, so it potentially creates a - * case-sensitive query. For String conditions you can use {@link StringUtilities#mapToUpperCase(Function)} - * to add an uppercase transform after your mapping function. - * - * @param mapper a mapping function to apply to the value, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mapper to the value of this condition, - * if renderable, otherwise a condition that will not render. - */ @Override public <R> IsLikeCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsLikeCaseInsensitive::new, IsLikeCaseInsensitive::empty); } public static IsLikeCaseInsensitive<String> of(String value) { - // Keep the null safe upper case utility for backwards compatibility in case someone passes in a null - return new IsLikeCaseInsensitive<>(StringUtilities.safelyUpperCase(value)); + return new IsLikeCaseInsensitive<>(value); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java index 8731d5b64..4486d1df7 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java @@ -38,7 +38,7 @@ public static <T> IsNotInCaseInsensitive<T> empty() { } protected IsNotInCaseInsensitive(Collection<T> values) { - super(values); + super(values.stream().map(StringUtilities::upperCaseIfPossible).toList()); } @Override @@ -57,19 +57,6 @@ public IsNotInCaseInsensitive<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsNotInCaseInsensitive::new, this, IsNotInCaseInsensitive::empty); } - /** - * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a - * condition that will not render (this). - * - * <p>This function DOES NOT automatically transform values to uppercase, so it potentially creates a - * case-sensitive query. For String conditions you can use {@link StringUtilities#mapToUpperCase(Function)} - * to add an uppercase transform after your mapping function. - * - * @param mapper a mapping function to apply to the value, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mapper to the value of this condition, - * if renderable, otherwise a condition that will not render. - */ @Override public <R> IsNotInCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsNotInCaseInsensitive::new, IsNotInCaseInsensitive::empty); @@ -80,7 +67,6 @@ public static IsNotInCaseInsensitive<String> of(String... values) { } public static IsNotInCaseInsensitive<String> of(Collection<String> values) { - // Keep the null safe upper case utility for backwards compatibility in case someone passes in a null - return new IsNotInCaseInsensitive<>(values.stream().map(StringUtilities::safelyUpperCase).toList()); + return new IsNotInCaseInsensitive<>(values); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java index 438e1c5ed..992a231eb 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java @@ -39,7 +39,7 @@ public static <T> IsNotInCaseInsensitiveWhenPresent<T> empty() { } protected IsNotInCaseInsensitiveWhenPresent(Collection<T> values) { - super(values); + super(values.stream().filter(Objects::nonNull).map(StringUtilities::upperCaseIfPossible).toList()); } @Override @@ -53,19 +53,6 @@ public IsNotInCaseInsensitiveWhenPresent<T> filter(Predicate<? super T> predicat this, IsNotInCaseInsensitiveWhenPresent::empty); } - /** - * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a - * condition that will not render (this). - * - * <p>This function DOES NOT automatically transform values to uppercase, so it potentially creates a - * case-sensitive query. For String conditions you can use {@link StringUtilities#mapToUpperCase(Function)} - * to add an uppercase transform after your mapping function. - * - * @param mapper a mapping function to apply to the value, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mapper to the value of this condition, - * if renderable, otherwise a condition that will not render. - */ @Override public <R> IsNotInCaseInsensitiveWhenPresent<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsNotInCaseInsensitiveWhenPresent::new, IsNotInCaseInsensitiveWhenPresent::empty); @@ -76,7 +63,6 @@ public static IsNotInCaseInsensitiveWhenPresent<String> of(@Nullable String... v } public static IsNotInCaseInsensitiveWhenPresent<String> of(Collection<@Nullable String> values) { - return new IsNotInCaseInsensitiveWhenPresent<>( - values.stream().filter(Objects::nonNull).map(String::toUpperCase).toList()); + return new IsNotInCaseInsensitiveWhenPresent<>(values); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java index 8eb65d772..715a19a8d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java @@ -44,7 +44,7 @@ public static <T> IsNotLikeCaseInsensitive<T> empty() { } protected IsNotLikeCaseInsensitive(T value) { - super(value); + super(StringUtilities.upperCaseIfPossible(value)); } @Override @@ -57,26 +57,12 @@ public IsNotLikeCaseInsensitive<T> filter(Predicate<? super T> predicate) { return filterSupport(predicate, IsNotLikeCaseInsensitive::empty, this); } - /** - * If renderable, apply the mapping to the value and return a new condition with the new value. Else return a - * condition that will not render (this). - * - * <p>This function DOES NOT automatically transform values to uppercase, so it potentially creates a - * case-sensitive query. For String conditions you can use {@link StringUtilities#mapToUpperCase(Function)} - * to add an uppercase transform after your mapping function. - * - * @param mapper a mapping function to apply to the value, if renderable - * @param <R> type of the new condition - * @return a new condition with the result of applying the mapper to the value of this condition, - * if renderable, otherwise a condition that will not render. - */ @Override public <R> IsNotLikeCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsNotLikeCaseInsensitive::new, IsNotLikeCaseInsensitive::empty); } public static IsNotLikeCaseInsensitive<String> of(String value) { - // Keep the null safe upper case utility for backwards compatibility in case someone passes in a null - return new IsNotLikeCaseInsensitive<>(StringUtilities.safelyUpperCase(value)); + return new IsNotLikeCaseInsensitive<>(value); } } diff --git a/src/test/java/org/mybatis/dynamic/sql/util/StringUtilitiesTest.java b/src/test/java/org/mybatis/dynamic/sql/util/StringUtilitiesTest.java index 1c54cafc9..e1d8c137c 100644 --- a/src/test/java/org/mybatis/dynamic/sql/util/StringUtilitiesTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/util/StringUtilitiesTest.java @@ -38,4 +38,16 @@ void testNumeric() { String input = "USER%NAME%3"; assertThat(StringUtilities.toCamelCase(input)).isEqualTo("userName3"); } + + @Test + void testUpperCaseInteger() { + Integer i = StringUtilities.upperCaseIfPossible(3); + assertThat(i).isEqualTo(3); + } + + @Test + void testUpperCaseString() { + String i = StringUtilities.upperCaseIfPossible("fred"); + assertThat(i).isEqualTo("FRED"); + } } diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java index 7d4e4505e..bd2e56fbb 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java @@ -24,7 +24,6 @@ import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.SqlBuilder; -import org.mybatis.dynamic.sql.util.StringUtilities; class FilterAndMapTest { @Test @@ -543,31 +542,17 @@ void testMappingAnEmptyListCondition() { assertThat(filtered).isSameAs(mapped); } - @Test - void testIsInCaseInsensitiveWhenPresentMap() { - var cond = SqlBuilder.isInCaseInsensitiveWhenPresent("Fred", "Wilma"); - var mapped = cond.map(s -> s + " Flintstone"); - assertThat(mapped.values().toList()).containsExactly("FRED Flintstone", "WILMA Flintstone"); - } - @Test void testIsInCaseInsensitiveWhenPresentMapCaseInsensitive() { var cond = SqlBuilder.isInCaseInsensitiveWhenPresent("Fred", "Wilma"); - var mapped = cond.map(StringUtilities.mapToUpperCase(s -> s + " Flintstone")); - assertThat(mapped.values().toList()).containsExactly("FRED FLINTSTONE", "WILMA FLINTSTONE"); - } - - @Test - void testIsNotInCaseInsensitiveWhenPresentMap() { - var cond = SqlBuilder.isNotInCaseInsensitiveWhenPresent("Fred", "Wilma"); var mapped = cond.map(s -> s + " Flintstone"); - assertThat(mapped.values().toList()).containsExactly("FRED Flintstone", "WILMA Flintstone"); + assertThat(mapped.values().toList()).containsExactly("FRED FLINTSTONE", "WILMA FLINTSTONE"); } @Test void testIsNotInCaseInsensitiveWhenPresentMapCaseInsensitive() { var cond = SqlBuilder.isNotInCaseInsensitiveWhenPresent("Fred", "Wilma"); - var mapped = cond.map(StringUtilities.mapToUpperCase(s -> s + " Flintstone")); + var mapped = cond.map(s -> s + " Flintstone"); assertThat(mapped.values().toList()).containsExactly("FRED FLINTSTONE", "WILMA FLINTSTONE"); } } From 1fdb1c2ad27657f7024fee6b7e409e942c02bdbd Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Sat, 15 Mar 2025 09:40:19 -0400 Subject: [PATCH 220/260] Prefer toList --- .../dynamic/sql/where/condition/IsInCaseInsensitive.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java index a3777188a..bc8bfbdf9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java @@ -20,7 +20,6 @@ import java.util.Collections; import java.util.function.Function; import java.util.function.Predicate; -import java.util.stream.Collectors; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; @@ -39,7 +38,7 @@ public static <T> IsInCaseInsensitive<T> empty() { } protected IsInCaseInsensitive(Collection<T> values) { - super(values.stream().map(StringUtilities::upperCaseIfPossible).collect(Collectors.toList())); + super(values.stream().map(StringUtilities::upperCaseIfPossible).toList()); } @Override From c8480cc97155d2aef10634b0035ffe8bb96a41f2 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Sat, 15 Mar 2025 11:02:59 -0400 Subject: [PATCH 221/260] Coverage --- .../org/mybatis/dynamic/sql/util/StringUtilities.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java b/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java index 532391856..aad161f0c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/StringUtilities.java @@ -15,8 +15,6 @@ */ package org.mybatis.dynamic.sql.util; -import org.jspecify.annotations.Nullable; - public interface StringUtilities { static String spaceAfter(String in) { @@ -27,10 +25,6 @@ static String spaceBefore(String in) { return " " + in; //$NON-NLS-1$ } - static @Nullable String safelyUpperCase(@Nullable String s) { - return s == null ? null : s.toUpperCase(); - } - static String toCamelCase(String inputString) { StringBuilder sb = new StringBuilder(); @@ -63,7 +57,7 @@ static String formatConstantForSQL(String in) { static <T> T upperCaseIfPossible(T value) { if (value instanceof String) { @SuppressWarnings("unchecked") - T t = (T) safelyUpperCase((String) value); + T t = (T) ((String) value).toUpperCase(); return t; } From 43f8e8b75ed3243598d2abd6abb3ec9c8db7dab6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 18 Mar 2025 15:59:39 +0000 Subject: [PATCH 222/260] Update dependency ch.qos.logback:logback-classic to v1.5.18 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 03b9bc69f..637e0eff1 100644 --- a/pom.xml +++ b/pom.xml @@ -170,7 +170,7 @@ <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> - <version>1.5.17</version> + <version>1.5.18</version> <scope>test</scope> </dependency> <dependency> From e476b7b0df661c04fc972d43bd3e100c38f84923 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 19 Mar 2025 19:00:30 +0000 Subject: [PATCH 223/260] Update spring batch to v5.2.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 637e0eff1..8efe27229 100644 --- a/pom.xml +++ b/pom.xml @@ -61,7 +61,7 @@ <java.test.version>17</java.test.version> <java.test.release.version>17</java.test.release.version> <junit.jupiter.version>5.12.1</junit.jupiter.version> - <spring.batch.version>5.2.1</spring.batch.version> + <spring.batch.version>5.2.2</spring.batch.version> <checkstyle.config>checkstyle-override.xml</checkstyle.config> From 07668533d4665197ec4ae0f9e0b50e307593f935 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 19 Mar 2025 22:35:33 +0000 Subject: [PATCH 224/260] Update dependency org.springframework:spring-jdbc to v6.2.5 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 637e0eff1..372b41021 100644 --- a/pom.xml +++ b/pom.xml @@ -101,7 +101,7 @@ <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> - <version>6.2.4</version> + <version>6.2.5</version> <scope>provided</scope> <optional>true</optional> </dependency> From 05bf2d5176762d1d7bfc2f8eae0fbb9858b9c459 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 20 Mar 2025 09:56:44 +0000 Subject: [PATCH 225/260] Update kotlin monorepo to v2.1.20 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 575738922..cad1ea0b9 100644 --- a/pom.xml +++ b/pom.xml @@ -69,7 +69,7 @@ <module.name>org.mybatis.dynamic.sql</module.name> - <kotlin.version>2.1.10</kotlin.version> + <kotlin.version>2.1.20</kotlin.version> <kotlin.compiler.jvmTarget>17</kotlin.compiler.jvmTarget> <kotlin.compiler.languageVersion>2.0</kotlin.compiler.languageVersion> <kotlin.compiler.apiVersion>2.0</kotlin.compiler.apiVersion> From 99becd9d915231cdbba7c8a3e1ddf6c3bdae2958 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Mar 2025 08:26:56 +0000 Subject: [PATCH 226/260] Update dependency org.mariadb.jdbc:mariadb-java-client to v3.5.3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cad1ea0b9..f5b9b21c7 100644 --- a/pom.xml +++ b/pom.xml @@ -200,7 +200,7 @@ <dependency> <groupId>org.mariadb.jdbc</groupId> <artifactId>mariadb-java-client</artifactId> - <version>3.5.2</version> + <version>3.5.3</version> <scope>test</scope> </dependency> <dependency> From 6380d6fce809f17328f45f53dc6b7a29c0869c09 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 2 Apr 2025 11:02:37 -0400 Subject: [PATCH 227/260] Another round of misc. code cleanup --- .../dynamic/sql/select/UnionQuery.java | 13 +- .../examples/complexquery/GroupingTest.java | 6 +- .../examples/emptywhere/EmptyWhereTest.java | 123 ++++++++---------- .../emptywhere/OrderDynamicSqlSupport.java | 10 +- .../emptywhere/PersonDynamicSqlSupport.java | 14 +- .../examples/spring/PersonTemplateTest.java | 2 +- .../examples/spring/SpringMapToRowTest.java | 2 +- .../springbatch/common/PersonProcessor.java | 2 +- .../mapper/PersonDynamicSqlSupport.java | 18 +-- .../sql/insert/InsertStatementTest.java | 56 ++------ .../dynamic/sql/insert/MapToRowTest.java | 10 +- .../sql/util/ColumnMappingVisitorTest.java | 4 +- .../mybatis3/joins/JoinMapperNewSyntaxTest.kt | 24 ++-- .../GeneratedAlwaysDynamicSqlSupport.kt | 2 +- .../sql/util/kotlin/model/ModelBuilderTest.kt | 5 +- 15 files changed, 107 insertions(+), 184 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/select/UnionQuery.java b/src/main/java/org/mybatis/dynamic/sql/select/UnionQuery.java index 9beb85b46..6806d4791 100644 --- a/src/main/java/org/mybatis/dynamic/sql/select/UnionQuery.java +++ b/src/main/java/org/mybatis/dynamic/sql/select/UnionQuery.java @@ -17,20 +17,9 @@ import java.util.Objects; -public class UnionQuery { - private final String connector; - private final SelectModel selectModel; - +public record UnionQuery(String connector, SelectModel selectModel) { public UnionQuery(String connector, SelectModel selectModel) { this.connector = Objects.requireNonNull(connector); this.selectModel = Objects.requireNonNull(selectModel); } - - public String connector() { - return connector; - } - - public SelectModel selectModel() { - return selectModel; - } } diff --git a/src/test/java/examples/complexquery/GroupingTest.java b/src/test/java/examples/complexquery/GroupingTest.java index 1d3f631f6..b6552b3cb 100644 --- a/src/test/java/examples/complexquery/GroupingTest.java +++ b/src/test/java/examples/complexquery/GroupingTest.java @@ -33,9 +33,9 @@ class GroupingTest { private static class Foo extends SqlTable { - public SqlColumn<Integer> columnA = column("A"); - public SqlColumn<Integer> columnB = column("B"); - public SqlColumn<Integer> columnC = column("C"); + public final SqlColumn<Integer> columnA = column("A"); + public final SqlColumn<Integer> columnB = column("B"); + public final SqlColumn<Integer> columnC = column("C"); public Foo() { super("Foo"); diff --git a/src/test/java/examples/emptywhere/EmptyWhereTest.java b/src/test/java/examples/emptywhere/EmptyWhereTest.java index 4c02f4f66..f20a81a9a 100644 --- a/src/test/java/examples/emptywhere/EmptyWhereTest.java +++ b/src/test/java/examples/emptywhere/EmptyWhereTest.java @@ -20,9 +20,11 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mybatis.dynamic.sql.SqlBuilder.*; -import java.util.*; +import java.util.Optional; import java.util.stream.Stream; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; @@ -39,62 +41,63 @@ import org.mybatis.dynamic.sql.where.WhereDSL; import org.mybatis.dynamic.sql.where.render.WhereClauseProvider; +@NullMarked class EmptyWhereTest { + private static final String FIRST_NAME = "Fred"; + private static final String LAST_NAME = "Flintstone"; - static List<Variation> baseVariations() { - String firstName = "Fred"; - String lastName = "Flintstone"; - - Variation v1 = new Variation(firstName, lastName, + static Stream<Variation> whereVariations() { + Variation v1 = new Variation(FIRST_NAME, LAST_NAME, "where first_name = #{parameters.p1} or last_name = #{parameters.p2}"); - Variation v2 = new Variation(null, lastName, + Variation v2 = new Variation(null, LAST_NAME, "where last_name = #{parameters.p1}"); - Variation v3 = new Variation(firstName, null, + Variation v3 = new Variation(FIRST_NAME, null, "where first_name = #{parameters.p1}"); Variation v4 = new Variation(null, null, ""); - return List.of(v1, v2, v3, v4); - } - - static Stream<Variation> whereVariations() { - return baseVariations().stream(); + return Stream.of(v1, v2, v3, v4); } static Stream<Variation> joinWhereVariations() { - List<Variation> baseVariations = baseVariations(); + Variation v1 = new Variation(FIRST_NAME, LAST_NAME, + "where person.first_name = #{parameters.p1} or person.last_name = #{parameters.p2}"); - baseVariations.get(0).whereClause = - "where person.first_name = #{parameters.p1} or person.last_name = #{parameters.p2}"; - baseVariations.get(1).whereClause = "where person.last_name = #{parameters.p1}"; - baseVariations.get(2).whereClause = "where person.first_name = #{parameters.p1}"; + Variation v2 = new Variation(null, LAST_NAME, + "where person.last_name = #{parameters.p1}"); - return baseVariations.stream(); + Variation v3 = new Variation(FIRST_NAME, null, + "where person.first_name = #{parameters.p1}"); + + Variation v4 = new Variation(null, null, ""); + + return Stream.of(v1, v2, v3, v4); } static Stream<Variation> updateWhereVariations() { - List<Variation> baseVariations = baseVariations(); + Variation v1 = new Variation(FIRST_NAME, LAST_NAME, + "where first_name = #{parameters.p2} or last_name = #{parameters.p3}"); - baseVariations.get(0).whereClause = - "where first_name = #{parameters.p2} or last_name = #{parameters.p3}"; - baseVariations.get(1).whereClause ="where last_name = #{parameters.p2}"; - baseVariations.get(2).whereClause = "where first_name = #{parameters.p2}"; + Variation v2 = new Variation(null, LAST_NAME, + "where last_name = #{parameters.p2}"); - return baseVariations.stream(); + Variation v3 = new Variation(FIRST_NAME, null, + "where first_name = #{parameters.p2}"); + + Variation v4 = new Variation(null, null, ""); + + return Stream.of(v1, v2, v3, v4); } @Test void testDeleteThreeConditions() { - String fName = "Fred"; - String lName = "Flintstone"; - DeleteDSL<DeleteModel>.DeleteWhereBuilder builder = deleteFrom(person) .where(id, isEqualTo(3)); - builder.and(firstName, isEqualTo(fName).filter(Objects::nonNull)); - builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(lName).filter(Objects::nonNull)); + builder.and(firstName, isEqualTo(FIRST_NAME)); + builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(LAST_NAME)); DeleteStatementProvider deleteStatement = builder.build().render(RenderingStrategies.MYBATIS3); @@ -112,8 +115,8 @@ void testDeleteVariations(Variation variation) { DeleteDSL<DeleteModel>.DeleteWhereBuilder builder = deleteFrom(person) .where(); - builder.and(firstName, isEqualTo(variation.firstName).filter(Objects::nonNull)); - builder.or(PersonDynamicSqlSupport.lastName, isEqualTo(variation.lastName).filter(Objects::nonNull)); + builder.and(firstName, isEqualToWhenPresent(variation.firstName)); + builder.or(PersonDynamicSqlSupport.lastName, isEqualToWhenPresent(variation.lastName)); builder.configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)); DeleteStatementProvider deleteStatement = builder.build().render(RenderingStrategies.MYBATIS3); @@ -125,15 +128,12 @@ void testDeleteVariations(Variation variation) { @Test void testSelectThreeConditions() { - String fName = "Fred"; - String lName = "Flintstone"; - QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder = select(id, firstName, PersonDynamicSqlSupport.lastName) .from(person) .where(id, isEqualTo(3)); - builder.and(firstName, isEqualTo(fName).filter(Objects::nonNull)); - builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(lName).filter(Objects::nonNull)); + builder.and(firstName, isEqualTo(FIRST_NAME)); + builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(LAST_NAME)); SelectStatementProvider selectStatement = builder.build().render(RenderingStrategies.MYBATIS3); @@ -153,8 +153,8 @@ void testSelectVariations(Variation variation) { .from(person) .where(); - builder.and(firstName, isEqualTo(variation.firstName).filter(Objects::nonNull)); - builder.or(PersonDynamicSqlSupport.lastName, isEqualTo(variation.lastName).filter(Objects::nonNull)); + builder.and(firstName, isEqualToWhenPresent(variation.firstName)); + builder.or(PersonDynamicSqlSupport.lastName, isEqualToWhenPresent(variation.lastName)); builder.configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)); SelectStatementProvider selectStatement = builder.build().render(RenderingStrategies.MYBATIS3); @@ -166,15 +166,12 @@ void testSelectVariations(Variation variation) { @Test void testJoinThreeConditions() { - String fName = "Fred"; - String lName = "Flintstone"; - QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder = select(id, firstName, PersonDynamicSqlSupport.lastName, orderDate) .from(person).join(order).on(person.id, isEqualTo(order.personId)) .where(id, isEqualTo(3)); - builder.and(firstName, isEqualTo(fName).filter(Objects::nonNull)); - builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(lName).filter(Objects::nonNull)); + builder.and(firstName, isEqualTo(FIRST_NAME)); + builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(LAST_NAME)); SelectStatementProvider selectStatement = builder.build().render(RenderingStrategies.MYBATIS3); @@ -195,8 +192,8 @@ void testJoinVariations(Variation variation) { .from(person).join(order).on(person.id, isEqualTo(order.personId)) .where(); - builder.and(firstName, isEqualTo(variation.firstName).filter(Objects::nonNull)); - builder.or(PersonDynamicSqlSupport.lastName, isEqualTo(variation.lastName).filter(Objects::nonNull)); + builder.and(firstName, isEqualToWhenPresent(variation.firstName)); + builder.or(PersonDynamicSqlSupport.lastName, isEqualToWhenPresent(variation.lastName)); builder.configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)); SelectStatementProvider selectStatement = builder.build().render(RenderingStrategies.MYBATIS3); @@ -211,15 +208,12 @@ void testJoinVariations(Variation variation) { @Test void testUpdateThreeConditions() { - String fName = "Fred"; - String lName = "Flintstone"; - UpdateDSL<UpdateModel>.UpdateWhereBuilder builder = update(person) .set(id).equalTo(3) .where(id, isEqualTo(3)); - builder.and(firstName, isEqualTo(fName).filter(Objects::nonNull)); - builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(lName).filter(Objects::nonNull)); + builder.and(firstName, isEqualTo(FIRST_NAME)); + builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(LAST_NAME)); UpdateStatementProvider updateStatement = builder.build().render(RenderingStrategies.MYBATIS3); @@ -239,8 +233,8 @@ void testUpdateVariations(Variation variation) { .set(id).equalTo(3) .where(); - builder.and(firstName, isEqualTo(variation.firstName).filter(Objects::nonNull)); - builder.or(PersonDynamicSqlSupport.lastName, isEqualTo(variation.lastName).filter(Objects::nonNull)); + builder.and(firstName, isEqualToWhenPresent(variation.firstName)); + builder.or(PersonDynamicSqlSupport.lastName, isEqualToWhenPresent(variation.lastName)); builder.configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)); UpdateStatementProvider updateStatement = builder.build().render(RenderingStrategies.MYBATIS3); @@ -254,13 +248,10 @@ void testUpdateVariations(Variation variation) { @Test void testWhereThreeConditions() { - String fName = "Fred"; - String lName = "Flintstone"; - WhereDSL.StandaloneWhereFinisher builder = where(id, isEqualTo(3)); - builder.and(firstName, isEqualTo(fName).filter(Objects::nonNull)); - builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(lName).filter(Objects::nonNull)); + builder.and(firstName, isEqualTo(FIRST_NAME)); + builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(LAST_NAME)); Optional<WhereClauseProvider> whereClause = builder.build().render(RenderingStrategies.MYBATIS3); @@ -278,8 +269,8 @@ void testWhereThreeConditions() { void testWhereVariations(Variation variation) { WhereDSL.StandaloneWhereFinisher builder = where(); - builder.and(firstName, isEqualTo(variation.firstName).filter(Objects::nonNull)); - builder.or(PersonDynamicSqlSupport.lastName, isEqualTo(variation.lastName).filter(Objects::nonNull)); + builder.and(firstName, isEqualToWhenPresent(variation.firstName)); + builder.or(PersonDynamicSqlSupport.lastName, isEqualToWhenPresent(variation.lastName)); builder.configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)); Optional<WhereClauseProvider> whereClause = builder.build().render(RenderingStrategies.MYBATIS3); @@ -293,15 +284,5 @@ void testWhereVariations(Variation variation) { } } - private static class Variation { - String firstName; - String lastName; - String whereClause; - - public Variation(String firstName, String lastName, String whereClause) { - this.firstName = firstName; - this.lastName = lastName; - this.whereClause = whereClause; - } - } + private record Variation (@Nullable String firstName, @Nullable String lastName, String whereClause) {} } diff --git a/src/test/java/examples/emptywhere/OrderDynamicSqlSupport.java b/src/test/java/examples/emptywhere/OrderDynamicSqlSupport.java index 4664e2b21..41cab1031 100644 --- a/src/test/java/examples/emptywhere/OrderDynamicSqlSupport.java +++ b/src/test/java/examples/emptywhere/OrderDynamicSqlSupport.java @@ -22,13 +22,13 @@ public class OrderDynamicSqlSupport { - public static Order order = new Order(); - public static SqlColumn<Integer> personId = order.personId; - public static SqlColumn<Date> orderDate = order.orderDate; + public static final Order order = new Order(); + public static final SqlColumn<Integer> personId = order.personId; + public static final SqlColumn<Date> orderDate = order.orderDate; public static class Order extends SqlTable { - public SqlColumn<Integer> personId = column("person_id"); - public SqlColumn<Date> orderDate = column("order_date"); + public final SqlColumn<Integer> personId = column("person_id"); + public final SqlColumn<Date> orderDate = column("order_date"); public Order() { super("order"); diff --git a/src/test/java/examples/emptywhere/PersonDynamicSqlSupport.java b/src/test/java/examples/emptywhere/PersonDynamicSqlSupport.java index 0a8d791fe..9a7d83a81 100644 --- a/src/test/java/examples/emptywhere/PersonDynamicSqlSupport.java +++ b/src/test/java/examples/emptywhere/PersonDynamicSqlSupport.java @@ -20,15 +20,15 @@ public class PersonDynamicSqlSupport { - public static Person person = new Person(); - public static SqlColumn<Integer> id = person.id; - public static SqlColumn<String> firstName = person.firstName; - public static SqlColumn<String> lastName = person.lastName; + public static final Person person = new Person(); + public static final SqlColumn<Integer> id = person.id; + public static final SqlColumn<String> firstName = person.firstName; + public static final SqlColumn<String> lastName = person.lastName; public static class Person extends SqlTable { - public SqlColumn<Integer> id = column("id"); - public SqlColumn<String> firstName = column("first_name"); - public SqlColumn<String> lastName = column("last_name"); + public final SqlColumn<Integer> id = column("id"); + public final SqlColumn<String> firstName = column("first_name"); + public final SqlColumn<String> lastName = column("last_name"); public Person() { super("person"); diff --git a/src/test/java/examples/spring/PersonTemplateTest.java b/src/test/java/examples/spring/PersonTemplateTest.java index 8376dcef7..1f5f8548a 100644 --- a/src/test/java/examples/spring/PersonTemplateTest.java +++ b/src/test/java/examples/spring/PersonTemplateTest.java @@ -779,7 +779,7 @@ void testJoinCountWithSubCriteria() { }; - static RowMapper<PersonRecord> personRowMapper = + static final RowMapper<PersonRecord> personRowMapper = (rs, i) -> { PersonRecord row = new PersonRecord(); row.setId(rs.getInt(1)); diff --git a/src/test/java/examples/spring/SpringMapToRowTest.java b/src/test/java/examples/spring/SpringMapToRowTest.java index 7c40f03d8..cf9b52258 100644 --- a/src/test/java/examples/spring/SpringMapToRowTest.java +++ b/src/test/java/examples/spring/SpringMapToRowTest.java @@ -122,7 +122,7 @@ void testInsertBatch() { assertThat(records).hasSize(3); } - static RowMapper<CompoundKeyRow> rowMapper = + static final RowMapper<CompoundKeyRow> rowMapper = (rs, i) -> { CompoundKeyRow answer = new CompoundKeyRow(); answer.setId1(rs.getInt("ID1")); diff --git a/src/test/java/examples/springbatch/common/PersonProcessor.java b/src/test/java/examples/springbatch/common/PersonProcessor.java index ad7492f4e..2a4939cdb 100644 --- a/src/test/java/examples/springbatch/common/PersonProcessor.java +++ b/src/test/java/examples/springbatch/common/PersonProcessor.java @@ -29,7 +29,7 @@ public class PersonProcessor implements ItemProcessor<PersonRecord, PersonRecord private ExecutionContext executionContext; @Override - public PersonRecord process(PersonRecord person) throws Exception { + public PersonRecord process(PersonRecord person) { incrementRowCount(); PersonRecord transformed = new PersonRecord(); diff --git a/src/test/java/examples/springbatch/mapper/PersonDynamicSqlSupport.java b/src/test/java/examples/springbatch/mapper/PersonDynamicSqlSupport.java index 82884f29b..b5a264509 100644 --- a/src/test/java/examples/springbatch/mapper/PersonDynamicSqlSupport.java +++ b/src/test/java/examples/springbatch/mapper/PersonDynamicSqlSupport.java @@ -22,17 +22,17 @@ public class PersonDynamicSqlSupport { - public static Person person = new Person(); - public static SqlColumn<Integer> id = person.id; - public static SqlColumn<String> firstName = person.firstName; - public static SqlColumn<String> lastName = person.lastName; - public static SqlColumn<Boolean> forPagingTest = person.forPagingTest; + public static final Person person = new Person(); + public static final SqlColumn<Integer> id = person.id; + public static final SqlColumn<String> firstName = person.firstName; + public static final SqlColumn<String> lastName = person.lastName; + public static final SqlColumn<Boolean> forPagingTest = person.forPagingTest; public static class Person extends SqlTable { - public SqlColumn<Integer> id = column("id", JDBCType.INTEGER); - public SqlColumn<String> firstName = column("first_name", JDBCType.VARCHAR); - public SqlColumn<String> lastName = column("last_name", JDBCType.VARCHAR); - public SqlColumn<Boolean> forPagingTest = column("for_paging_test", JDBCType.BOOLEAN); + public final SqlColumn<Integer> id = column("id", JDBCType.INTEGER); + public final SqlColumn<String> firstName = column("first_name", JDBCType.VARCHAR); + public final SqlColumn<String> lastName = column("last_name", JDBCType.VARCHAR); + public final SqlColumn<Boolean> forPagingTest = column("for_paging_test", JDBCType.BOOLEAN); public Person() { super("person"); 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 e991bef02..29249317b 100644 --- a/src/test/java/org/mybatis/dynamic/sql/insert/InsertStatementTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/insert/InsertStatementTest.java @@ -20,6 +20,7 @@ import java.sql.JDBCType; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.SqlTable; @@ -37,9 +38,7 @@ class InsertStatementTest { @Test void testFullInsertStatementBuilder() { - TestRecord row = new TestRecord(); - row.setLastName("jones"); - row.setOccupation("dino driver"); + TestRecord row = new TestRecord(null, null, "jones", "dino driver"); InsertStatementProvider<TestRecord> insertStatement = insert(row) .into(foo) @@ -97,16 +96,14 @@ void testInsertStatementBuilderWithConstants() { @Test void testSelectiveInsertStatementBuilder() { - TestRecord row = new TestRecord(); - row.setLastName("jones"); - row.setOccupation("dino driver"); + TestRecord row = new TestRecord(null, null, "jones", "dino driver"); InsertStatementProvider<TestRecord> insertStatement = insert(row) .into(foo) - .map(id).toPropertyWhenPresent("id", row::getId) - .map(firstName).toPropertyWhenPresent("firstName", row::getFirstName) - .map(lastName).toPropertyWhenPresent("lastName", row::getLastName) - .map(occupation).toPropertyWhenPresent("occupation", row::getOccupation) + .map(id).toPropertyWhenPresent("id", row::id) + .map(firstName).toPropertyWhenPresent("firstName", row::firstName) + .map(lastName).toPropertyWhenPresent("lastName", row::lastName) + .map(occupation).toPropertyWhenPresent("occupation", row::occupation) .build() .render(RenderingStrategies.MYBATIS3); @@ -115,42 +112,9 @@ void testSelectiveInsertStatementBuilder() { assertThat(insertStatement.getInsertStatement()).isEqualTo(expected); } - static class TestRecord { - private Integer id; - private String firstName; - private String lastName; - private String occupation; - - Integer getId() { - return id; - } - - void setId(Integer id) { - this.id = id; - } - - String getFirstName() { - return firstName; - } - - void setFirstName(String firstName) { - this.firstName = firstName; - } - - String getLastName() { - return lastName; - } - - void setLastName(String lastName) { - this.lastName = lastName; - } - - String getOccupation() { - return occupation; - } - - void setOccupation(String occupation) { - this.occupation = occupation; + record TestRecord (@Nullable Integer id, @Nullable String firstName, @Nullable String lastName, @Nullable String occupation) { + TestRecord() { + this(null, null, null, null); } } } diff --git a/src/test/java/org/mybatis/dynamic/sql/insert/MapToRowTest.java b/src/test/java/org/mybatis/dynamic/sql/insert/MapToRowTest.java index eb0ff2657..d17811fe1 100644 --- a/src/test/java/org/mybatis/dynamic/sql/insert/MapToRowTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/insert/MapToRowTest.java @@ -166,13 +166,5 @@ void testBatchInsertRowMappingWithSpring() { assertThat(batchInsert.getInsertStatementSQL()).isEqualTo(expected); } - static class Record { - public Record(Integer id1, Integer id2) { - this.id1 = id1; - this.id2 = id2; - } - - public Integer id1; - public Integer id2; - } + record Record(Integer id1, Integer id2) { } } diff --git a/src/test/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitorTest.java b/src/test/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitorTest.java index f75be43f6..2f17910b2 100644 --- a/src/test/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitorTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/util/ColumnMappingVisitorTest.java @@ -205,8 +205,8 @@ void testThatUpdateVisitorErrorsForRowMapping() { } private static class TestTable extends SqlTable { - public SqlColumn<Integer> id; - public SqlColumn<String> description; + public final SqlColumn<Integer> id; + public final SqlColumn<String> description; public TestTable() { super("Test"); diff --git a/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt b/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt index 2d74a5784..1ad6d71c2 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/joins/JoinMapperNewSyntaxTest.kt @@ -477,14 +477,12 @@ class JoinMapperNewSyntaxTest { join(orderLine, "ol") on { orderMaster.orderId isEqualTo orderLine.orderId } - leftJoin( - { - select(itemMaster.allColumns()) { - from(itemMaster) - } - + "im" + leftJoin { + select(itemMaster.allColumns()) { + from(itemMaster) } - ) on { + +"im" + } on { orderLine.itemId isEqualTo "im"(itemMaster.itemId) } orderBy(orderLine.orderId, itemMaster.itemId) @@ -614,14 +612,12 @@ class JoinMapperNewSyntaxTest { join(orderLine, "ol") on { orderMaster.orderId isEqualTo orderLine.orderId } - rightJoin( - { - select(itemMaster.allColumns()) { - from(itemMaster) - } - + "im" + rightJoin { + select(itemMaster.allColumns()) { + from(itemMaster) } - ) on { + +"im" + } on { orderLine.itemId isEqualTo "im"(itemMaster.itemId) } orderBy(orderLine.orderId, itemMaster.itemId) diff --git a/src/test/kotlin/examples/kotlin/spring/canonical/GeneratedAlwaysDynamicSqlSupport.kt b/src/test/kotlin/examples/kotlin/spring/canonical/GeneratedAlwaysDynamicSqlSupport.kt index db4067c5a..0c388bdb6 100644 --- a/src/test/kotlin/examples/kotlin/spring/canonical/GeneratedAlwaysDynamicSqlSupport.kt +++ b/src/test/kotlin/examples/kotlin/spring/canonical/GeneratedAlwaysDynamicSqlSupport.kt @@ -26,7 +26,7 @@ object GeneratedAlwaysDynamicSqlSupport { val fullName = generatedAlways.fullName class GeneratedAlways : SqlTable("GeneratedAlways") { - val id = column<Int>("id") + val id = column<Int>(name = "id") val firstName = column<String>(name = "first_name") val lastName = column<String>(name = "last_name") val fullName = column<String>(name = "full_name") diff --git a/src/test/kotlin/org/mybatis/dynamic/sql/util/kotlin/model/ModelBuilderTest.kt b/src/test/kotlin/org/mybatis/dynamic/sql/util/kotlin/model/ModelBuilderTest.kt index d4394a500..a4a4b9e3f 100644 --- a/src/test/kotlin/org/mybatis/dynamic/sql/util/kotlin/model/ModelBuilderTest.kt +++ b/src/test/kotlin/org/mybatis/dynamic/sql/util/kotlin/model/ModelBuilderTest.kt @@ -19,13 +19,14 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import org.mybatis.dynamic.sql.SqlTable import org.mybatis.dynamic.sql.render.RenderingStrategies +import org.mybatis.dynamic.sql.util.kotlin.elements.column class ModelBuilderTest { class Table : SqlTable("Table") val table = Table() - val id = table.column<Int>("id") - val description = table.column<String>("description") + val id = table.column<Int>(name = "id") + val description = table.column<String>(name = "description") @Test fun testSelectBuilder() { From c0d769c5b5e34843a47c581a86fcc1ff464279fd Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 3 Apr 2025 11:32:22 -0400 Subject: [PATCH 228/260] Checkstyle --- src/test/java/examples/animal/data/AnimalDataTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/examples/animal/data/AnimalDataTest.java b/src/test/java/examples/animal/data/AnimalDataTest.java index a883b4bd2..90c247116 100644 --- a/src/test/java/examples/animal/data/AnimalDataTest.java +++ b/src/test/java/examples/animal/data/AnimalDataTest.java @@ -792,7 +792,7 @@ void testNotInCaseSensitiveConditionWithNull() { SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isNotInCaseInsensitive((String)null)) + .where(animalName, isNotInCaseInsensitive((String) null)) .build() .render(RenderingStrategies.MYBATIS3); From 65d0c77b47ddc8051bcbbe4ca47169fa524095a1 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 3 Apr 2025 11:45:30 -0400 Subject: [PATCH 229/260] Convert to records in the Spring example --- .../java/examples/spring/AddressRecord.java | 39 +-- src/test/java/examples/spring/LastName.java | 40 +-- .../spring/LastNameParameterConverter.java | 6 +- .../java/examples/spring/PersonRecord.java | 73 +--- .../examples/spring/PersonTemplateTest.java | 317 +++++++----------- .../examples/spring/PersonWithAddress.java | 67 +--- .../spring/YesNoParameterConverter.java | 2 - .../java/examples/spring/package-info.java | 19 ++ 8 files changed, 164 insertions(+), 399 deletions(-) create mode 100644 src/test/java/examples/spring/package-info.java diff --git a/src/test/java/examples/spring/AddressRecord.java b/src/test/java/examples/spring/AddressRecord.java index a8f56e426..3987285ab 100644 --- a/src/test/java/examples/spring/AddressRecord.java +++ b/src/test/java/examples/spring/AddressRecord.java @@ -15,41 +15,4 @@ */ package examples.spring; -public class AddressRecord { - private Integer id; - private String streetAddress; - private String city; - private String state; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getStreetAddress() { - return streetAddress; - } - - public void setStreetAddress(String streetAddress) { - this.streetAddress = streetAddress; - } - - public String getCity() { - return city; - } - - public void setCity(String city) { - this.city = city; - } - - public String getState() { - return state; - } - - public void setState(String state) { - this.state = state; - } -} +public record AddressRecord (Integer id, String streetAddress, String city, String state) { } diff --git a/src/test/java/examples/spring/LastName.java b/src/test/java/examples/spring/LastName.java index 2bda4c7cc..e6e9d93dd 100644 --- a/src/test/java/examples/spring/LastName.java +++ b/src/test/java/examples/spring/LastName.java @@ -15,42 +15,6 @@ */ package examples.spring; -public class LastName { - private String name; +import org.jspecify.annotations.Nullable; - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public static LastName of(String name) { - LastName lastName = new LastName(); - lastName.setName(name); - return lastName; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - LastName other = (LastName) obj; - if (name == null) { - return other.name == null; - } else return name.equals(other.name); - } -} +public record LastName(@Nullable String name) { } diff --git a/src/test/java/examples/spring/LastNameParameterConverter.java b/src/test/java/examples/spring/LastNameParameterConverter.java index e8d57d4cd..413aea7cb 100644 --- a/src/test/java/examples/spring/LastNameParameterConverter.java +++ b/src/test/java/examples/spring/LastNameParameterConverter.java @@ -15,20 +15,18 @@ */ package examples.spring; -import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.ParameterTypeConverter; import org.springframework.core.convert.converter.Converter; -@NullMarked public class LastNameParameterConverter implements ParameterTypeConverter<LastName, String>, Converter<LastName, String> { @Override public @Nullable String convert(LastName source) { - if ("Slate".equals(source.getName())) { + if ("Slate".equals(source.name())) { return null; } else { - return source.getName(); + return source.name(); } } } diff --git a/src/test/java/examples/spring/PersonRecord.java b/src/test/java/examples/spring/PersonRecord.java index 138f853d1..73417e5c6 100644 --- a/src/test/java/examples/spring/PersonRecord.java +++ b/src/test/java/examples/spring/PersonRecord.java @@ -15,78 +15,23 @@ */ package examples.spring; -import java.util.Date; - -public class PersonRecord { - private Integer id; - private String firstName; - private LastName lastName; - private Date birthDate; - private Boolean employed; - private String occupation; - private Integer addressId; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public LastName getLastName() { - return lastName; - } - - public String getLastNameAsString() { - return lastName == null ? null : lastName.getName(); - } +import org.jspecify.annotations.Nullable; - public void setLastName(LastName lastName) { - this.lastName = lastName; - } - - public Date getBirthDate() { - return birthDate; - } - - public void setBirthDate(Date birthDate) { - this.birthDate = birthDate; - } - - public String getOccupation() { - return occupation; - } +import java.util.Date; - public void setOccupation(String occupation) { - this.occupation = occupation; - } +public record PersonRecord (Integer id, @Nullable String firstName, @Nullable LastName lastName, + @Nullable Date birthDate, @Nullable Boolean employed, + @Nullable String occupation, @Nullable Integer addressId) { - public Boolean getEmployed() { - return employed; + public @Nullable String getLastNameAsString() { + return lastName == null ? null : lastName.name(); } public String getEmployedAsString() { return employed == null ? "No" : employed ? "Yes" : "No"; } - public void setEmployed(Boolean employed) { - this.employed = employed; - } - - public Integer getAddressId() { - return addressId; - } - - public void setAddressId(Integer addressId) { - this.addressId = addressId; + public PersonRecord withOccupation(String occupation) { + return new PersonRecord(id, firstName, lastName, birthDate, employed, occupation, addressId); } } diff --git a/src/test/java/examples/spring/PersonTemplateTest.java b/src/test/java/examples/spring/PersonTemplateTest.java index 1f5f8548a..b92c03a50 100644 --- a/src/test/java/examples/spring/PersonTemplateTest.java +++ b/src/test/java/examples/spring/PersonTemplateTest.java @@ -20,7 +20,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mybatis.dynamic.sql.SqlBuilder.*; -import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Optional; @@ -38,7 +37,7 @@ import org.mybatis.dynamic.sql.util.Buildable; import org.mybatis.dynamic.sql.util.spring.NamedParameterJdbcTemplateExtensions; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.DataClassRowMapper; import org.springframework.jdbc.core.RowMapper; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import org.springframework.transaction.annotation.Transactional; @@ -70,8 +69,8 @@ void testSelectAll() { List<PersonRecord> rows = template.selectList(selectStatement, personRowMapper); assertThat(rows).hasSize(6); - assertThat(rows.get(0).getId()).isEqualTo(1); - assertThat(rows.get(5).getId()).isEqualTo(6); + assertThat(rows.get(0).id()).isEqualTo(1); + assertThat(rows.get(5).id()).isEqualTo(6); } @@ -84,8 +83,8 @@ void testSelectAllOrdered() { List<PersonRecord> rows = template.selectList(selectStatement, personRowMapper); assertThat(rows).hasSize(6); - assertThat(rows.get(0).getId()).isEqualTo(5); - assertThat(rows.get(5).getId()).isEqualTo(1); + assertThat(rows.get(0).id()).isEqualTo(5); + assertThat(rows.get(5).id()).isEqualTo(1); } @@ -151,36 +150,36 @@ void testSelectWithTypeHandler() { List<PersonRecord> rows = template.selectList(selectStatement, personRowMapper); assertThat(rows).hasSize(2); - assertThat(rows.get(0).getId()).isEqualTo(3); - assertThat(rows.get(1).getId()).isEqualTo(6); + assertThat(rows.get(0).id()).isEqualTo(3); + assertThat(rows.get(1).id()).isEqualTo(6); } @Test void testSelectBetweenWithTypeHandler() { Buildable<SelectModel> selectStatement = select(id, firstName, lastName, birthDate, employed, occupation, addressId) .from(person) - .where(lastName, isBetween(LastName.of("Adams")).and(LastName.of("Jones"))) + .where(lastName, isBetween(new LastName("Adams")).and(new LastName("Jones"))) .orderBy(id); List<PersonRecord> rows = template.selectList(selectStatement, personRowMapper); assertThat(rows).hasSize(3); - assertThat(rows.get(0).getId()).isEqualTo(1); - assertThat(rows.get(1).getId()).isEqualTo(2); + assertThat(rows.get(0).id()).isEqualTo(1); + assertThat(rows.get(1).id()).isEqualTo(2); } @Test void testSelectListWithTypeHandler() { Buildable<SelectModel> selectStatement = select(id, firstName, lastName, birthDate, employed, occupation, addressId) .from(person) - .where(lastName, isIn(LastName.of("Flintstone"), LastName.of("Rubble"))) + .where(lastName, isIn(new LastName("Flintstone"), new LastName("Rubble"))) .orderBy(id); List<PersonRecord> rows = template.selectList(selectStatement, personRowMapper); assertThat(rows).hasSize(6); - assertThat(rows.get(0).getId()).isEqualTo(1); - assertThat(rows.get(1).getId()).isEqualTo(2); + assertThat(rows.get(0).id()).isEqualTo(1); + assertThat(rows.get(1).id()).isEqualTo(2); } @Test @@ -203,8 +202,15 @@ void testFirstNameIn() { List<PersonRecord> rows = template.selectList(selectStatement, personRowMapper); assertThat(rows).hasSize(2); - assertThat(rows.get(0).getLastName().getName()).isEqualTo("Flintstone"); - assertThat(rows.get(1).getLastName().getName()).isEqualTo("Rubble"); + + assertThat(rows).satisfiesExactly( + person1 -> assertThat(person1).isNotNull() + .extracting("lastName").isNotNull() + .extracting("name").isEqualTo("Flintstone"), + person2 -> assertThat(person2).isNotNull() + .extracting("lastName").isNotNull() + .extracting("name").isEqualTo("Rubble") + ); } @Test @@ -238,14 +244,7 @@ void testDeleteByPrimaryKey() { @Test void testInsert() { - PersonRecord row = new PersonRecord(); - row.setId(100); - row.setFirstName("Joe"); - row.setLastName(LastName.of("Jones")); - row.setBirthDate(new Date()); - row.setEmployed(true); - row.setOccupation("Developer"); - row.setAddressId(1); + PersonRecord row = new PersonRecord(100, "Joe", new LastName("Jones"), new Date(), true, "Developer", 1); Buildable<InsertModel<PersonRecord>> insertStatement = insert(row).into(person) .map(id).toProperty("id") @@ -266,7 +265,7 @@ void testGeneralInsert() { Buildable<GeneralInsertModel> insertStatement = insertInto(person) .set(id).toValue(100) .set(firstName).toValue("Joe") - .set(lastName).toValue(LastName.of("Jones")) + .set(lastName).toValue(new LastName("Jones")) .set(birthDate).toValue(new Date()) .set(employed).toValue(true) .set(occupation).toValue("Developer") @@ -280,27 +279,9 @@ void testGeneralInsert() { @Test void testInsertMultiple() { - List<PersonRecord> records = new ArrayList<>(); - - PersonRecord row = new PersonRecord(); - row.setId(100); - row.setFirstName("Joe"); - row.setLastName(LastName.of("Jones")); - row.setBirthDate(new Date()); - row.setEmployed(true); - row.setOccupation("Developer"); - row.setAddressId(1); - records.add(row); - - row = new PersonRecord(); - row.setId(101); - row.setFirstName("Sarah"); - row.setLastName(LastName.of("Smith")); - row.setBirthDate(new Date()); - row.setEmployed(true); - row.setOccupation("Architect"); - row.setAddressId(2); - records.add(row); + List<PersonRecord> records = List.of( + new PersonRecord(100, "Joe", new LastName("Jones"), new Date(), true, "Developer", 1), + new PersonRecord(101, "Sarah", new LastName("Smith"), new Date(), true, "Architect", 2)); Buildable<MultiRowInsertModel<PersonRecord>> insertStatement = insertMultiple(records).into(person) .map(id).toProperty("id") @@ -319,27 +300,9 @@ void testInsertMultiple() { @Test void testInsertBatch() { - List<PersonRecord> records = new ArrayList<>(); - - PersonRecord row = new PersonRecord(); - row.setId(100); - row.setFirstName("Joe"); - row.setLastName(LastName.of("Jones")); - row.setBirthDate(new Date()); - row.setEmployed(true); - row.setOccupation("Developer"); - row.setAddressId(1); - records.add(row); - - row = new PersonRecord(); - row.setId(101); - row.setFirstName("Sarah"); - row.setLastName(LastName.of("Smith")); - row.setBirthDate(new Date()); - row.setEmployed(true); - row.setOccupation("Architect"); - row.setAddressId(2); - records.add(row); + List<PersonRecord> records = List.of( + new PersonRecord(100, "Joe", new LastName("Jones"), new Date(), true, "Developer", 1), + new PersonRecord(101, "Sarah", new LastName("Smith"), new Date(), true, "Architect", 2)); Buildable<BatchInsertModel<PersonRecord>> insertStatement = insertBatch(records).into(person) .map(id).toProperty("id") @@ -359,22 +322,16 @@ void testInsertBatch() { @Test void testInsertSelective() { - PersonRecord row = new PersonRecord(); - row.setId(100); - row.setFirstName("Joe"); - row.setLastName(LastName.of("Jones")); - row.setBirthDate(new Date()); - row.setEmployed(false); - row.setAddressId(1); + PersonRecord row = new PersonRecord(100, "Joe", new LastName("Jones"), new Date(), false, null, 1); Buildable<InsertModel<PersonRecord>> insertStatement = insert(row).into(person) - .map(id).toPropertyWhenPresent("id", row::getId) - .map(firstName).toPropertyWhenPresent("firstName", row::getFirstName) + .map(id).toPropertyWhenPresent("id", row::id) + .map(firstName).toPropertyWhenPresent("firstName", row::firstName) .map(lastName).toPropertyWhenPresent("lastNameAsString", row::getLastNameAsString) - .map(birthDate).toPropertyWhenPresent("birthDate", row::getBirthDate) + .map(birthDate).toPropertyWhenPresent("birthDate", row::birthDate) .map(employed).toPropertyWhenPresent("employedAsString", row::getEmployedAsString) - .map(occupation).toPropertyWhenPresent("occupation", row::getOccupation) - .map(addressId).toPropertyWhenPresent("addressId", row::getAddressId); + .map(occupation).toPropertyWhenPresent("occupation", row::occupation) + .map(addressId).toPropertyWhenPresent("addressId", row::addressId); int rows = template.insert(insertStatement); @@ -387,7 +344,7 @@ void testGeneralInsertWhenTypeConverterReturnsNull() { GeneralInsertStatementProvider insertStatement = insertInto(person) .set(id).toValue(100) .set(firstName).toValue("Joe") - .set(lastName).toValueWhenPresent(LastName.of("Slate")) + .set(lastName).toValueWhenPresent(new LastName("Slate")) .set(birthDate).toValue(new Date()) .set(employed).toValue(true) .set(occupation).toValue("Quarry Owner") @@ -404,7 +361,9 @@ void testGeneralInsertWhenTypeConverterReturnsNull() { .from(person) .where(id, isEqualTo(100)); Optional<PersonRecord> newRecord = template.selectOne(selectStatement, personRowMapper); - assertThat(newRecord).hasValueSatisfying(r -> assertThat(r.getLastName().getName()).isNull()); + assertThat(newRecord).hasValueSatisfying( + r -> assertThat(r).isNotNull().extracting("lastName").isNotNull().extracting("name").isNull() + ); } @Test @@ -413,7 +372,7 @@ void testUpdateByPrimaryKey() { Buildable<GeneralInsertModel> insertStatement = insertInto(person) .set(id).toValue(100) .set(firstName).toValue("Joe") - .set(lastName).toValue(LastName.of("Jones")) + .set(lastName).toValue(new LastName("Jones")) .set(birthDate).toValue(new Date()) .set(employed).toValue(true) .set(occupation).toValue("Developer") @@ -433,7 +392,7 @@ void testUpdateByPrimaryKey() { .from(person) .where(id, isEqualTo(100)); Optional<PersonRecord> newRecord = template.selectOne(selectStatement, personRowMapper); - assertThat(newRecord).hasValueSatisfying(r -> assertThat(r.getOccupation()).isEqualTo("Programmer")); + assertThat(newRecord).hasValueSatisfying(r -> assertThat(r.occupation()).isEqualTo("Programmer")); } @Test @@ -442,7 +401,7 @@ void testUpdateByPrimaryKeyWithTypeHandler() { Buildable<GeneralInsertModel> insertStatement = insertInto(person) .set(id).toValue(100) .set(firstName).toValue("Joe") - .set(lastName).toValue(LastName.of("Jones")) + .set(lastName).toValue(new LastName("Jones")) .set(birthDate).toValue(new Date()) .set(employed).toValue(true) .set(occupation).toValue("Developer") @@ -452,7 +411,7 @@ void testUpdateByPrimaryKeyWithTypeHandler() { assertThat(rows).isEqualTo(1); Buildable<UpdateModel> updateStatement = update(person) - .set(lastName).equalTo(LastName.of("Smith")) + .set(lastName).equalTo(new LastName("Smith")) .where(id, isEqualTo(100)); rows = template.update(updateStatement); @@ -462,8 +421,10 @@ void testUpdateByPrimaryKeyWithTypeHandler() { .from(person) .where(id, isEqualTo(100)); Optional<PersonRecord> newRecord = template.selectOne(selectStatement, personRowMapper); - assertThat(newRecord).hasValueSatisfying(r -> - assertThat(r.getLastName().getName()).isEqualTo("Smith")); + assertThat(newRecord).hasValueSatisfying(r -> assertThat(r).isNotNull() + .extracting("lastName").isNotNull() + .extracting("name").isEqualTo("Smith") + ); } @Test @@ -471,7 +432,7 @@ void testUpdateByPrimaryKeySelective() { Buildable<GeneralInsertModel> insertStatement = insertInto(person) .set(id).toValue(100) .set(firstName).toValue("Joe") - .set(lastName).toValue(LastName.of("Jones")) + .set(lastName).toValue(new LastName("Jones")) .set(birthDate).toValue(new Date()) .set(employed).toValue(true) .set(occupation).toValue("Developer") @@ -480,18 +441,16 @@ void testUpdateByPrimaryKeySelective() { int rows = template.generalInsert(insertStatement); assertThat(rows).isEqualTo(1); - PersonRecord updateRecord = new PersonRecord(); - updateRecord.setId(100); - updateRecord.setOccupation("Programmer"); + PersonRecord updateRecord = new PersonRecord(100, null, null, null, null, "Programmer", null); Buildable<UpdateModel> updateStatement = update(person) - .set(firstName).equalToWhenPresent(updateRecord::getFirstName) - .set(lastName).equalToWhenPresent(updateRecord::getLastName) - .set(birthDate).equalToWhenPresent(updateRecord::getBirthDate) - .set(employed).equalToWhenPresent(updateRecord::getEmployed) - .set(occupation).equalToWhenPresent(updateRecord::getOccupation) - .set(addressId).equalToWhenPresent(updateRecord::getAddressId) - .where(id, isEqualTo(updateRecord::getId)); + .set(firstName).equalToWhenPresent(updateRecord::firstName) + .set(lastName).equalToWhenPresent(updateRecord::lastName) + .set(birthDate).equalToWhenPresent(updateRecord::birthDate) + .set(employed).equalToWhenPresent(updateRecord::employed) + .set(occupation).equalToWhenPresent(updateRecord::occupation) + .set(addressId).equalToWhenPresent(updateRecord::addressId) + .where(id, isEqualTo(updateRecord::id)); rows = template.update(updateStatement); assertThat(rows).isEqualTo(1); @@ -501,21 +460,14 @@ void testUpdateByPrimaryKeySelective() { .where(id, isEqualTo(100)); Optional<PersonRecord> newRecord = template.selectOne(selectStatement, personRowMapper); assertThat(newRecord).hasValueSatisfying(r -> { - assertThat(r.getOccupation()).isEqualTo("Programmer"); - assertThat(r.getFirstName()).isEqualTo("Joe"); + assertThat(r.occupation()).isEqualTo("Programmer"); + assertThat(r.firstName()).isEqualTo("Joe"); }); } @Test void testUpdate() { - PersonRecord row = new PersonRecord(); - row.setId(100); - row.setFirstName("Joe"); - row.setLastName(LastName.of("Jones")); - row.setBirthDate(new Date()); - row.setEmployed(true); - row.setOccupation("Developer"); - row.setAddressId(1); + PersonRecord row = new PersonRecord(100, "Joe", new LastName("Jones"), new Date(), true, "Developer", 1); Buildable<InsertModel<PersonRecord>> insertStatement = insert(row).into(person) .map(id).toProperty("id") @@ -529,16 +481,16 @@ void testUpdate() { int rows = template.insert(insertStatement); assertThat(rows).isEqualTo(1); - row.setOccupation("Programmer"); + row = row.withOccupation("Programmer"); Buildable<UpdateModel> updateStatement = update(person) - .set(firstName).equalTo(row::getFirstName) - .set(lastName).equalTo(row::getLastName) - .set(birthDate).equalTo(row::getBirthDate) - .set(employed).equalTo(row::getEmployed) - .set(occupation).equalTo(row::getOccupation) - .set(addressId).equalTo(row::getAddressId) - .where(id, isEqualTo(row::getId)); + .set(firstName).equalToWhenPresent(row::firstName) + .set(lastName).equalToWhenPresent(row::lastName) + .set(birthDate).equalToWhenPresent(row::birthDate) + .set(employed).equalToWhenPresent(row::employed) + .set(occupation).equalToWhenPresent(row::occupation) + .set(addressId).equalToWhenPresent(row::addressId) + .where(id, isEqualTo(row::id)); rows = template.update(updateStatement); assertThat(rows).isEqualTo(1); @@ -548,8 +500,8 @@ void testUpdate() { .where(id, isEqualTo(100)); Optional<PersonRecord> newRecord = template.selectOne(selectStatement, personRowMapper); assertThat(newRecord).hasValueSatisfying(r -> { - assertThat(r.getOccupation()).isEqualTo("Programmer"); - assertThat(r.getFirstName()).isEqualTo("Joe"); + assertThat(r.occupation()).isEqualTo("Programmer"); + assertThat(r.firstName()).isEqualTo("Joe"); }); } @@ -558,7 +510,7 @@ void testUpdateAll() { Buildable<GeneralInsertModel> insertStatement = insertInto(person) .set(id).toValue(100) .set(firstName).toValue("Joe") - .set(lastName).toValue(LastName.of("Jones")) + .set(lastName).toValue(new LastName("Jones")) .set(birthDate).toValue(new Date()) .set(employed).toValue(true) .set(occupation).toValue("Developer") @@ -578,7 +530,7 @@ void testUpdateAll() { .where(id, isEqualTo(100)); Optional<PersonRecord> newRecord = template.selectOne(selectStatement, personRowMapper); - assertThat(newRecord).hasValueSatisfying(r -> assertThat(r.getOccupation()).isEqualTo("Programmer")); + assertThat(newRecord).hasValueSatisfying(r -> assertThat(r.occupation()).isEqualTo("Programmer")); } @Test @@ -618,25 +570,25 @@ void testCountDistinctLastName() { void testTypeHandledLike() { Buildable<SelectModel> selectStatement = select(id, firstName, lastName, birthDate, employed, occupation, addressId) .from(person) - .where(lastName, isLike(LastName.of("Fl%"))) + .where(lastName, isLike(new LastName("Fl%"))) .orderBy(id); List<PersonRecord> rows = template.selectList(selectStatement, personRowMapper); assertThat(rows).hasSize(3); - assertThat(rows.get(0).getFirstName()).isEqualTo("Fred"); + assertThat(rows.get(0).firstName()).isEqualTo("Fred"); } @Test void testTypeHandledNotLike() { Buildable<SelectModel> selectStatement = select(id, firstName, lastName, birthDate, employed, occupation, addressId) .from(person) - .where(lastName, isNotLike(LastName.of("Fl%"))) + .where(lastName, isNotLike(new LastName("Fl%"))) .orderBy(id); List<PersonRecord> rows = template.selectList(selectStatement, personRowMapper); assertThat(rows).hasSize(3); - assertThat(rows.get(0).getFirstName()).isEqualTo("Barney"); + assertThat(rows.get(0).firstName()).isEqualTo("Barney"); } @Test @@ -646,14 +598,15 @@ void testAutoMapping() { .from(address) .orderBy(address.id); + List<AddressRecord> records = template.selectList(selectStatement, - BeanPropertyRowMapper.newInstance(AddressRecord.class)); + DataClassRowMapper.newInstance(AddressRecord.class)); assertThat(records).hasSize(2); - assertThat(records.get(0).getId()).isEqualTo(1); - assertThat(records.get(0).getStreetAddress()).isEqualTo("123 Main Street"); - assertThat(records.get(0).getCity()).isEqualTo("Bedrock"); - assertThat(records.get(0).getState()).isEqualTo("IN"); + assertThat(records.get(0).id()).isEqualTo(1); + assertThat(records.get(0).streetAddress()).isEqualTo("123 Main Street"); + assertThat(records.get(0).city()).isEqualTo("Bedrock"); + assertThat(records.get(0).state()).isEqualTo("IN"); } @Test @@ -667,16 +620,16 @@ void testJoinAllRows() { List<PersonWithAddress> records = template.selectList(selectStatement, personWithAddressRowMapper); assertThat(records).hasSize(6); - assertThat(records.get(0).getId()).isEqualTo(1); - assertThat(records.get(0).getEmployed()).isTrue(); - assertThat(records.get(0).getFirstName()).isEqualTo("Fred"); - assertThat(records.get(0).getLastName()).isEqualTo(LastName.of("Flintstone")); - assertThat(records.get(0).getOccupation()).isEqualTo("Brontosaurus Operator"); - assertThat(records.get(0).getBirthDate()).isNotNull(); - assertThat(records.get(0).getAddress().getId()).isEqualTo(1); - assertThat(records.get(0).getAddress().getStreetAddress()).isEqualTo("123 Main Street"); - assertThat(records.get(0).getAddress().getCity()).isEqualTo("Bedrock"); - assertThat(records.get(0).getAddress().getState()).isEqualTo("IN"); + assertThat(records.get(0).id()).isEqualTo(1); + assertThat(records.get(0).employed()).isTrue(); + assertThat(records.get(0).firstName()).isEqualTo("Fred"); + assertThat(records.get(0).lastName()).isEqualTo(new LastName("Flintstone")); + assertThat(records.get(0).occupation()).isEqualTo("Brontosaurus Operator"); + assertThat(records.get(0).birthDate()).isNotNull(); + assertThat(records.get(0).address().id()).isEqualTo(1); + assertThat(records.get(0).address().streetAddress()).isEqualTo("123 Main Street"); + assertThat(records.get(0).address().city()).isEqualTo("Bedrock"); + assertThat(records.get(0).address().state()).isEqualTo("IN"); } @Test @@ -690,16 +643,16 @@ void testJoinOneRow() { List<PersonWithAddress> records = template.selectList(selectStatement, personWithAddressRowMapper); assertThat(records).hasSize(1); - assertThat(records.get(0).getId()).isEqualTo(1); - assertThat(records.get(0).getEmployed()).isTrue(); - assertThat(records.get(0).getFirstName()).isEqualTo("Fred"); - assertThat(records.get(0).getLastName()).isEqualTo(LastName.of("Flintstone")); - assertThat(records.get(0).getOccupation()).isEqualTo("Brontosaurus Operator"); - assertThat(records.get(0).getBirthDate()).isNotNull(); - assertThat(records.get(0).getAddress().getId()).isEqualTo(1); - assertThat(records.get(0).getAddress().getStreetAddress()).isEqualTo("123 Main Street"); - assertThat(records.get(0).getAddress().getCity()).isEqualTo("Bedrock"); - assertThat(records.get(0).getAddress().getState()).isEqualTo("IN"); + assertThat(records.get(0).id()).isEqualTo(1); + assertThat(records.get(0).employed()).isTrue(); + assertThat(records.get(0).firstName()).isEqualTo("Fred"); + assertThat(records.get(0).lastName()).isEqualTo(new LastName("Flintstone")); + assertThat(records.get(0).occupation()).isEqualTo("Brontosaurus Operator"); + assertThat(records.get(0).birthDate()).isNotNull(); + assertThat(records.get(0).address().id()).isEqualTo(1); + assertThat(records.get(0).address().streetAddress()).isEqualTo("123 Main Street"); + assertThat(records.get(0).address().city()).isEqualTo("Bedrock"); + assertThat(records.get(0).address().state()).isEqualTo("IN"); } @Test @@ -713,16 +666,16 @@ void testJoinPrimaryKey() { Optional<PersonWithAddress> row = template.selectOne(selectStatement, personWithAddressRowMapper); assertThat(row).hasValueSatisfying(r -> { - assertThat(r.getId()).isEqualTo(1); - assertThat(r.getEmployed()).isTrue(); - assertThat(r.getFirstName()).isEqualTo("Fred"); - assertThat(r.getLastName()).isEqualTo(LastName.of("Flintstone")); - assertThat(r.getOccupation()).isEqualTo("Brontosaurus Operator"); - assertThat(r.getBirthDate()).isNotNull(); - assertThat(r.getAddress().getId()).isEqualTo(1); - assertThat(r.getAddress().getStreetAddress()).isEqualTo("123 Main Street"); - assertThat(r.getAddress().getCity()).isEqualTo("Bedrock"); - assertThat(r.getAddress().getState()).isEqualTo("IN"); + assertThat(r.id()).isEqualTo(1); + assertThat(r.employed()).isTrue(); + assertThat(r.firstName()).isEqualTo("Fred"); + assertThat(r.lastName()).isEqualTo(new LastName("Flintstone")); + assertThat(r.occupation()).isEqualTo("Brontosaurus Operator"); + assertThat(r.birthDate()).isNotNull(); + assertThat(r.address().id()).isEqualTo(1); + assertThat(r.address().streetAddress()).isEqualTo("123 Main Street"); + assertThat(r.address().city()).isEqualTo("Bedrock"); + assertThat(r.address().state()).isEqualTo("IN"); }); } @@ -759,36 +712,24 @@ void testJoinCountWithSubCriteria() { } private final RowMapper<PersonWithAddress> personWithAddressRowMapper = - (rs, i) -> { - PersonWithAddress row = new PersonWithAddress(); - row.setId(rs.getInt(1)); - row.setFirstName(rs.getString(2)); - row.setLastName(LastName.of(rs.getString(3))); - row.setBirthDate(rs.getTimestamp(4)); - row.setEmployed("Yes".equals(rs.getString(5))); - row.setOccupation(rs.getString(6)); - - AddressRecord address = new AddressRecord(); - row.setAddress(address); - address.setId(rs.getInt(7)); - address.setStreetAddress(rs.getString(8)); - address.setCity(rs.getString(9)); - address.setState(rs.getString(10)); - - return row; - }; + (rs, i) -> new PersonWithAddress(rs.getInt(1), + rs.getString(2), + new LastName(rs.getString(3)), + rs.getTimestamp(4), + "Yes".equals(rs.getString(5)), + rs.getString(6), + new AddressRecord(rs.getInt(7), + rs.getString(8), + rs.getString(9), + rs.getString(10))); static final RowMapper<PersonRecord> personRowMapper = - (rs, i) -> { - PersonRecord row = new PersonRecord(); - row.setId(rs.getInt(1)); - row.setFirstName(rs.getString(2)); - row.setLastName(LastName.of(rs.getString(3))); - row.setBirthDate(rs.getTimestamp(4)); - row.setEmployed("Yes".equals(rs.getString(5))); - row.setOccupation(rs.getString(6)); - row.setAddressId(rs.getInt(7)); - return row; - }; + (rs, i) -> new PersonRecord(rs.getInt(1), + rs.getString(2), + new LastName(rs.getString(3)), + rs.getTimestamp(4), + "Yes".equals(rs.getString(5)), + rs.getString(6), + rs.getInt(7)); } diff --git a/src/test/java/examples/spring/PersonWithAddress.java b/src/test/java/examples/spring/PersonWithAddress.java index 7dd143e6f..7cf524553 100644 --- a/src/test/java/examples/spring/PersonWithAddress.java +++ b/src/test/java/examples/spring/PersonWithAddress.java @@ -17,68 +17,5 @@ import java.util.Date; -public class PersonWithAddress { - private Integer id; - private String firstName; - private LastName lastName; - private Date birthDate; - private Boolean employed; - private String occupation; - private AddressRecord address; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public LastName getLastName() { - return lastName; - } - - public void setLastName(LastName lastName) { - this.lastName = lastName; - } - - public Date getBirthDate() { - return birthDate; - } - - public void setBirthDate(Date birthDate) { - this.birthDate = birthDate; - } - - public String getOccupation() { - return occupation; - } - - public void setOccupation(String occupation) { - this.occupation = occupation; - } - - public Boolean getEmployed() { - return employed; - } - - public void setEmployed(Boolean employed) { - this.employed = employed; - } - - public AddressRecord getAddress() { - return address; - } - - public void setAddress(AddressRecord address) { - this.address = address; - } -} +public record PersonWithAddress(Integer id, String firstName, LastName lastName, Date birthDate, Boolean employed, + String occupation, AddressRecord address) { } diff --git a/src/test/java/examples/spring/YesNoParameterConverter.java b/src/test/java/examples/spring/YesNoParameterConverter.java index f86cc7b0f..9801fe1ae 100644 --- a/src/test/java/examples/spring/YesNoParameterConverter.java +++ b/src/test/java/examples/spring/YesNoParameterConverter.java @@ -15,10 +15,8 @@ */ package examples.spring; -import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.ParameterTypeConverter; -@NullMarked public class YesNoParameterConverter implements ParameterTypeConverter<Boolean, String> { @Override diff --git a/src/test/java/examples/spring/package-info.java b/src/test/java/examples/spring/package-info.java new file mode 100644 index 000000000..27fa1f118 --- /dev/null +++ b/src/test/java/examples/spring/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package examples.spring; + +import org.jspecify.annotations.NullMarked; From 27e82d114ead76e4bf391b46834f9024a6b9838f Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 4 Apr 2025 09:05:52 -0400 Subject: [PATCH 230/260] Convert to records in the Animal Data example --- .../java/examples/animal/data/AnimalData.java | 39 +---- .../animal/data/AnimalDataMapper.java | 44 +++-- .../examples/animal/data/AnimalDataTest.java | 103 +++++------ .../animal/data/CommonSelectMapperTest.java | 37 ++-- .../examples/animal/data/FetchFirstTest.java | 12 +- .../animal/data/LimitAndOffsetTest.java | 18 +- .../examples/animal/data/MyInCondition.java | 5 +- .../OptionalConditionsAnimalDataTest.java | 100 +++++------ ...onditionsWithPredicatesAnimalDataTest.java | 161 +++++++++--------- .../examples/animal/data/package-info.java | 19 +++ .../examples/paging/LimitAndOffsetMapper.java | 13 +- .../examples/paging/LimitAndOffsetTest.java | 2 +- .../java/examples/paging/package-info.java | 19 +++ 13 files changed, 279 insertions(+), 293 deletions(-) create mode 100644 src/test/java/examples/animal/data/package-info.java create mode 100644 src/test/java/examples/paging/package-info.java diff --git a/src/test/java/examples/animal/data/AnimalData.java b/src/test/java/examples/animal/data/AnimalData.java index aff740d2f..0c4a49321 100644 --- a/src/test/java/examples/animal/data/AnimalData.java +++ b/src/test/java/examples/animal/data/AnimalData.java @@ -15,41 +15,4 @@ */ package examples.animal.data; -public class AnimalData { - private int id; - private String animalName; - private double brainWeight; - private double bodyWeight; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getAnimalName() { - return animalName; - } - - public void setAnimalName(String animalName) { - this.animalName = animalName; - } - - public double getBrainWeight() { - return brainWeight; - } - - public void setBrainWeight(double brainWeight) { - this.brainWeight = brainWeight; - } - - public double getBodyWeight() { - return bodyWeight; - } - - public void setBodyWeight(double bodyWeight) { - this.bodyWeight = bodyWeight; - } -} +public record AnimalData(int id, String animalName, double brainWeight, double bodyWeight) {} diff --git a/src/test/java/examples/animal/data/AnimalDataMapper.java b/src/test/java/examples/animal/data/AnimalDataMapper.java index 39fcd1875..26a2cbac2 100644 --- a/src/test/java/examples/animal/data/AnimalDataMapper.java +++ b/src/test/java/examples/animal/data/AnimalDataMapper.java @@ -17,10 +17,8 @@ import java.util.List; +import org.apache.ibatis.annotations.Arg; import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.annotations.Result; -import org.apache.ibatis.annotations.ResultMap; -import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.SelectProvider; import org.apache.ibatis.session.RowBounds; @@ -34,20 +32,24 @@ public interface AnimalDataMapper extends CommonDeleteMapper, CommonInsertMapper<AnimalData>, CommonUpdateMapper { @SelectProvider(type=SqlProviderAdapter.class, method="select") - @Results(id="AnimalDataResult", value={ - @Result(column="id", property="id", id=true), - @Result(column="animal_name", property="animalName"), - @Result(column="brain_weight", property="brainWeight"), - @Result(column="body_weight", property="bodyWeight") - }) + @Arg(column = "id", javaType = int.class, id = true) + @Arg(column = "animal_name", javaType = String.class) + @Arg(column = "brain_weight", javaType = double.class) + @Arg(column = "body_weight", javaType = double.class) List<AnimalData> selectMany(SelectStatementProvider selectStatement); @SelectProvider(type = SqlProviderAdapter.class, method = "select") - @ResultMap("AnimalDataResult") + @Arg(column = "id", javaType = int.class, id = true) + @Arg(column = "animal_name", javaType = String.class) + @Arg(column = "brain_weight", javaType = double.class) + @Arg(column = "body_weight", javaType = double.class) List<AnimalData> selectManyWithRowBounds(SelectStatementProvider selectStatement, RowBounds rowBounds); @SelectProvider(type = SqlProviderAdapter.class, method = "select") - @ResultMap("AnimalDataResult") + @Arg(column = "id", javaType = int.class, id = true) + @Arg(column = "animal_name", javaType = String.class) + @Arg(column = "brain_weight", javaType = double.class) + @Arg(column = "body_weight", javaType = double.class) AnimalData selectOne(SelectStatementProvider selectStatement); @Select({ @@ -55,7 +57,10 @@ public interface AnimalDataMapper extends CommonDeleteMapper, CommonInsertMapper "from AnimalData", "${whereClause}" }) - @ResultMap("AnimalDataResult") + @Arg(column = "id", javaType = int.class, id = true) + @Arg(column = "animal_name", javaType = String.class) + @Arg(column = "brain_weight", javaType = double.class) + @Arg(column = "body_weight", javaType = double.class) List<AnimalData> selectWithWhereClause(WhereClauseProvider whereClause); @Select({ @@ -63,7 +68,10 @@ public interface AnimalDataMapper extends CommonDeleteMapper, CommonInsertMapper "from AnimalData a", "${whereClause}" }) - @ResultMap("AnimalDataResult") + @Arg(column = "id", javaType = int.class, id = true) + @Arg(column = "animal_name", javaType = String.class) + @Arg(column = "brain_weight", javaType = double.class) + @Arg(column = "body_weight", javaType = double.class) List<AnimalData> selectWithWhereClauseAndAlias(WhereClauseProvider whereClause); @Select({ @@ -73,7 +81,10 @@ public interface AnimalDataMapper extends CommonDeleteMapper, CommonInsertMapper "order by id", "OFFSET #{offset,jdbcType=INTEGER} LIMIT #{limit,jdbcType=INTEGER}" }) - @ResultMap("AnimalDataResult") + @Arg(column = "id", javaType = int.class, id = true) + @Arg(column = "animal_name", javaType = String.class) + @Arg(column = "brain_weight", javaType = double.class) + @Arg(column = "body_weight", javaType = double.class) List<AnimalData> selectWithWhereClauseLimitAndOffset(@Param("whereClauseProvider") WhereClauseProvider whereClause, @Param("limit") int limit, @Param("offset") int offset); @@ -84,7 +95,10 @@ List<AnimalData> selectWithWhereClauseLimitAndOffset(@Param("whereClauseProvider "order by id", "OFFSET #{offset,jdbcType=INTEGER} LIMIT #{limit,jdbcType=INTEGER}" }) - @ResultMap("AnimalDataResult") + @Arg(column = "id", javaType = int.class, id = true) + @Arg(column = "animal_name", javaType = String.class) + @Arg(column = "brain_weight", javaType = double.class) + @Arg(column = "body_weight", javaType = double.class) List<AnimalData> selectWithWhereClauseAliasLimitAndOffset(@Param("whereClauseProvider") WhereClauseProvider whereClause, @Param("limit") int limit, @Param("offset") int offset); } diff --git a/src/test/java/examples/animal/data/AnimalDataTest.java b/src/test/java/examples/animal/data/AnimalDataTest.java index 90c247116..df53051f1 100644 --- a/src/test/java/examples/animal/data/AnimalDataTest.java +++ b/src/test/java/examples/animal/data/AnimalDataTest.java @@ -46,6 +46,7 @@ import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.BasicColumn; @@ -103,7 +104,7 @@ void testSelectAllRows() { assertAll( () -> assertThat(animals).hasSize(65), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -121,7 +122,7 @@ void testSelectAllRowsWithNullLimit() { assertAll( () -> assertThat(animals).hasSize(65), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -140,7 +141,7 @@ void testSelectAllRowsWithRowBounds() { List<AnimalData> animals = mapper.selectManyWithRowBounds(selectStatement, rowBounds); assertAll( () -> assertThat(animals).hasSize(6), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(5) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(5) ); } } @@ -157,7 +158,7 @@ void testSelectAllRowsWithOrder() { List<AnimalData> animals = mapper.selectMany(selectStatement); assertAll( () -> assertThat(animals).hasSize(65), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(65) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(65) ); } } @@ -196,7 +197,7 @@ void testSelectAllRowsAllColumnsWithOrder() { () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData order by id DESC"), () -> assertThat(animals).hasSize(65), () -> assertThat(animals).first().isNotNull() - .extracting(AnimalData::getId).isEqualTo(65) + .extracting(AnimalData::id).isEqualTo(65) ); } } @@ -214,7 +215,7 @@ void testSelectAllRowsAllColumnsWithOrderAndAlias() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select ad.* from AnimalData ad order by id DESC"), () -> assertThat(animals).hasSize(65), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(65) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(65) ); } } @@ -380,7 +381,7 @@ void testSelectRowsNotBetweenWithStandaloneWhereClauseLimitAndOffset() { assertThat(whereClause).hasValueSatisfying(wc -> { List<AnimalData> animals = mapper.selectWithWhereClauseLimitAndOffset(wc, 5, 15); assertThat(animals).hasSize(5); - assertThat(animals.get(0).getId()).isEqualTo(16); + assertThat(animals.get(0).id()).isEqualTo(16); }); } } @@ -398,7 +399,7 @@ void testSelectRowsNotBetweenWithStandaloneWhereClauseAliasLimitAndOffset() { assertThat(whereClause).hasValueSatisfying(wc -> { List<AnimalData> animals = mapper.selectWithWhereClauseAliasLimitAndOffset(wc, 3, 24); assertThat(animals).hasSize(3); - assertThat(animals.get(0).getId()).isEqualTo(25); + assertThat(animals.get(0).id()).isEqualTo(25); }); } @@ -710,14 +711,14 @@ void testInConditionWithEventuallyEmptyList() { @Test void testInConditionWithEventuallyEmptyListForceRendering() { - List<Integer> inValues = new ArrayList<>(); + List<@Nullable Integer> inValues = new ArrayList<>(); inValues.add(null); inValues.add(22); inValues.add(null); SelectModel selectModel = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isInWhenPresent(inValues).filter(Objects::nonNull).filter(i -> i != 22)) + .where(id, isInWhenPresent(inValues).filter(i -> i != 22)) .build(); assertThatExceptionOfType(NonRenderingWhereClauseException.class).isThrownBy(() -> @@ -864,8 +865,8 @@ void testLikeCaseInsensitive() { assertAll( () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).element(0).isNotNull().extracting(AnimalData::getAnimalName).isEqualTo("Ground squirrel"), - () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::getAnimalName).isEqualTo("Artic ground squirrel") + () -> assertThat(animals).element(0).isNotNull().extracting(AnimalData::animalName).isEqualTo("Ground squirrel"), + () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::animalName).isEqualTo("Artic ground squirrel") ); } } @@ -1587,11 +1588,9 @@ void testComplexCondition() { void testUpdate() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); - AnimalData row = new AnimalData(); - row.setBodyWeight(2.6); UpdateStatementProvider updateStatement = update(animalData) - .set(bodyWeight).equalTo(row.getBodyWeight()) + .set(bodyWeight).equalTo(2.6) .set(animalName).equalToNull() .where(id, isIn(1, 5, 7)) .or(id, isIn(2, 6, 8), and(animalName, isLike("%bat"))) @@ -1645,11 +1644,7 @@ void testUpdateValueOrNullWithNull() { void testInsert() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); - AnimalData row = new AnimalData(); - row.setId(100); - row.setAnimalName("Old Shep"); - row.setBodyWeight(22.5); - row.setBrainWeight(1.2); + AnimalData row = new AnimalData(100, "Old Shep", 22.5, 1.2); InsertStatementProvider<AnimalData> insertStatement = insert(row) .into(animalData) @@ -1669,11 +1664,7 @@ void testInsert() { void testInsertNull() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); - AnimalData row = new AnimalData(); - row.setId(100); - row.setAnimalName("Old Shep"); - row.setBodyWeight(22.5); - row.setBrainWeight(1.2); + AnimalData row = new AnimalData(100, "Old Shep", 22.5, 1.2); InsertStatementProvider<AnimalData> insertStatement = insert(row) .into(animalData) @@ -1693,18 +1684,10 @@ void testInsertNull() { void testBulkInsert() { try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); - List<AnimalData> records = new ArrayList<>(); - AnimalData row = new AnimalData(); - row.setId(100); - row.setAnimalName("Old Shep"); - row.setBodyWeight(22.5); - records.add(row); - - row = new AnimalData(); - row.setId(101); - row.setAnimalName("Old Dan"); - row.setBodyWeight(22.5); - records.add(row); + List<AnimalData> records = List.of( + new AnimalData(100, "Old Shep", 0.0, 22.5), + new AnimalData(101, "Old Dan", 0.0, 22.5) + ); BatchInsert<AnimalData> batchInsert = insertBatch(records) .into(animalData) @@ -1730,10 +1713,10 @@ void testBulkInsert() { assertAll( () -> assertThat(animals).hasSize(2), () -> assertThat(animals).element(0).isNotNull() - .extracting(AnimalData::getId, AnimalData::getBrainWeight, AnimalData::getAnimalName) + .extracting(AnimalData::id, AnimalData::brainWeight, AnimalData::animalName) .containsExactly(100, 1.2, null), () -> assertThat(animals).element(1).isNotNull() - .extracting(AnimalData::getId, AnimalData::getBrainWeight, AnimalData::getAnimalName) + .extracting(AnimalData::id, AnimalData::brainWeight, AnimalData::animalName) .containsExactly(101, 1.2, null) ); } @@ -1743,18 +1726,10 @@ void testBulkInsert() { void testBulkInsert2() { try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); - List<AnimalData> records = new ArrayList<>(); - AnimalData row = new AnimalData(); - row.setId(100); - row.setAnimalName("Old Shep"); - row.setBodyWeight(22.5); - records.add(row); - - row = new AnimalData(); - row.setId(101); - row.setAnimalName("Old Dan"); - row.setBodyWeight(22.5); - records.add(row); + List<AnimalData> records = List.of( + new AnimalData(100, "Old Shep", 0.0, 22.5), + new AnimalData(101, "Old Dan", 0.0, 22.5) + ); BatchInsert<AnimalData> batchInsert = insertBatch(records) .into(animalData) @@ -1780,10 +1755,10 @@ void testBulkInsert2() { assertAll( () -> assertThat(animals).hasSize(2), () -> assertThat(animals).element(0).isNotNull() - .extracting(AnimalData::getId, AnimalData::getBrainWeight, AnimalData::getAnimalName) + .extracting(AnimalData::id, AnimalData::brainWeight, AnimalData::animalName) .containsExactly(100, 1.2, "Old Fred"), () -> assertThat(animals).element(1).isNotNull() - .extracting(AnimalData::getId, AnimalData::getBrainWeight, AnimalData::getAnimalName) + .extracting(AnimalData::id, AnimalData::brainWeight, AnimalData::animalName) .containsExactly(101, 1.2, "Old Fred") ); } @@ -1806,7 +1781,7 @@ void testOrderByAndDistinct() { assertAll( () -> assertThat(rows).hasSize(14), - () -> assertThat(rows).first().isNotNull().extracting(AnimalData::getId).isEqualTo(65) + () -> assertThat(rows).first().isNotNull().extracting(AnimalData::id).isEqualTo(65) ); } } @@ -1828,7 +1803,7 @@ void testOrderByWithFullClause() { assertAll( () -> assertThat(rows).hasSize(14), - () -> assertThat(rows).first().isNotNull().extracting(AnimalData::getId).isEqualTo(65) + () -> assertThat(rows).first().isNotNull().extracting(AnimalData::id).isEqualTo(65) ); } } @@ -1944,7 +1919,7 @@ void testMaxSubselect() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select a.id, a.animal_name, a.body_weight, a.brain_weight from AnimalData a where a.brain_weight = (select max(b.brain_weight) from AnimalData b)"), () -> assertThat(records).hasSize(1), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getAnimalName).isEqualTo("Brachiosaurus") + () -> assertThat(records).first().isNotNull().extracting(AnimalData::animalName).isEqualTo("Brachiosaurus") ); } } @@ -2004,7 +1979,7 @@ void testMinSubselect() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select a.id, a.animal_name, a.body_weight, a.brain_weight from AnimalData a where a.brain_weight <> (select min(b.brain_weight) from AnimalData b) order by animal_name"), () -> assertThat(records).hasSize(64), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getAnimalName).isEqualTo("African elephant") + () -> assertThat(records).first().isNotNull().extracting(AnimalData::animalName).isEqualTo("African elephant") ); } } @@ -2026,7 +2001,7 @@ void testMinSubselectNoAlias() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where brain_weight <> (select min(brain_weight) from AnimalData) order by animal_name"), () -> assertThat(records).hasSize(64), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getAnimalName).isEqualTo("African elephant") + () -> assertThat(records).first().isNotNull().extracting(AnimalData::animalName).isEqualTo("African elephant") ); } } @@ -2335,13 +2310,13 @@ void testUpdateWithAddAndSubtract() { assertThat(rows).isEqualTo(1); AnimalData row = MyBatis3Utils.selectOne(mapper::selectOne, - BasicColumn.columnList(id, bodyWeight, brainWeight), + BasicColumn.columnList(id, animalName, bodyWeight, brainWeight), animalData, c -> c.where(id, isEqualTo(1)) ); - assertThat(row.getBodyWeight()).isEqualTo(-2.86); - assertThat(row.getBrainWeight()).isEqualTo(2.005); + assertThat(row.bodyWeight()).isEqualTo(-2.86); + assertThat(row.brainWeight()).isEqualTo(2.005); } } @@ -2368,13 +2343,13 @@ void testUpdateWithMultiplyAndDivide() { assertThat(rows).isEqualTo(1); AnimalData row = MyBatis3Utils.selectOne(mapper::selectOne, - BasicColumn.columnList(id, bodyWeight, brainWeight), + BasicColumn.columnList(id, animalName, bodyWeight, brainWeight), animalData, c -> c.where(id, isEqualTo(1)) ); - assertThat(row.getBodyWeight()).isEqualTo(0.42, within(.001)); - assertThat(row.getBrainWeight()).isEqualTo(.0025); + assertThat(row.bodyWeight()).isEqualTo(0.42, within(.001)); + assertThat(row.brainWeight()).isEqualTo(.0025); } } } diff --git a/src/test/java/examples/animal/data/CommonSelectMapperTest.java b/src/test/java/examples/animal/data/CommonSelectMapperTest.java index 863df85e6..e90f4cec7 100644 --- a/src/test/java/examples/animal/data/CommonSelectMapperTest.java +++ b/src/test/java/examples/animal/data/CommonSelectMapperTest.java @@ -69,14 +69,11 @@ void setup() throws Exception { sqlSessionFactory = new SqlSessionFactoryBuilder().build(config); } - private final Function<Map<String, Object>, AnimalData> rowMapper = map -> { - AnimalData ad = new AnimalData(); - ad.setId((Integer) map.get("ID")); - ad.setAnimalName((String) map.get("ANIMAL_NAME")); - ad.setBodyWeight((Double) map.get("BODY_WEIGHT")); - ad.setBrainWeight((Double) map.get("BRAIN_WEIGHT")); - return ad; - }; + private final Function<Map<String, Object>, AnimalData> rowMapper = map -> new AnimalData( + (Integer) map.get("ID"), + (String) map.get("ANIMAL_NAME"), + (Double) map.get("BRAIN_WEIGHT"), + (Double) map.get("BODY_WEIGHT")); @Test void testGeneralSelectOne() { @@ -106,10 +103,10 @@ void testGeneralSelectOneWithRowMapper() { AnimalData animal = mapper.selectOne(selectStatement, rowMapper); - assertThat(animal.getId()).isEqualTo(1); - assertThat(animal.getAnimalName()).isEqualTo("Lesser short-tailed shrew"); - assertThat(animal.getBodyWeight()).isEqualTo(0.14); - assertThat(animal.getBrainWeight()).isEqualTo(0.005); + assertThat(animal.id()).isEqualTo(1); + assertThat(animal.animalName()).isEqualTo("Lesser short-tailed shrew"); + assertThat(animal.bodyWeight()).isEqualTo(0.14); + assertThat(animal.brainWeight()).isEqualTo(0.005); } } @@ -148,14 +145,14 @@ void testGeneralSelectManyWithRowMapper() { assertThat(rows).hasSize(2); - assertThat(rows.get(0).getId()).isEqualTo(1); - assertThat(rows.get(0).getAnimalName()).isEqualTo("Lesser short-tailed shrew"); - assertThat(rows.get(0).getBodyWeight()).isEqualTo(0.14); - assertThat(rows.get(0).getBrainWeight()).isEqualTo(0.005); - assertThat(rows.get(1).getId()).isEqualTo(2); - assertThat(rows.get(1).getAnimalName()).isEqualTo("Little brown bat"); - assertThat(rows.get(1).getBodyWeight()).isEqualTo(0.25); - assertThat(rows.get(1).getBrainWeight()).isEqualTo(0.01); + assertThat(rows.get(0).id()).isEqualTo(1); + assertThat(rows.get(0).animalName()).isEqualTo("Lesser short-tailed shrew"); + assertThat(rows.get(0).bodyWeight()).isEqualTo(0.14); + assertThat(rows.get(0).brainWeight()).isEqualTo(0.005); + assertThat(rows.get(1).id()).isEqualTo(2); + assertThat(rows.get(1).animalName()).isEqualTo("Little brown bat"); + assertThat(rows.get(1).bodyWeight()).isEqualTo(0.25); + assertThat(rows.get(1).brainWeight()).isEqualTo(0.01); } } diff --git a/src/test/java/examples/animal/data/FetchFirstTest.java b/src/test/java/examples/animal/data/FetchFirstTest.java index 1c73532f1..9a1a10c00 100644 --- a/src/test/java/examples/animal/data/FetchFirstTest.java +++ b/src/test/java/examples/animal/data/FetchFirstTest.java @@ -80,7 +80,7 @@ void testOffsetAndFetchFirstAfterFrom() { assertAll( () -> assertThat(records).hasSize(3), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getId).isEqualTo(23), + () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23), () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData offset #{parameters.p1} rows fetch first #{parameters.p2} rows only"), () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 3L), () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 22L) @@ -102,7 +102,7 @@ void testFetchFirstOnlyAfterFrom() { assertAll( () -> assertThat(records).hasSize(3), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1), + () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(1), () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData fetch first #{parameters.p1} rows only"), () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L) ); @@ -126,7 +126,7 @@ void testOffsetAndFetchFirstAfterWhere() { assertAll( () -> assertThat(records).hasSize(3), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getId).isEqualTo(45), + () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(45), () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData where id < #{parameters.p1,jdbcType=INTEGER} and id > #{parameters.p2,jdbcType=INTEGER} offset #{parameters.p3} rows fetch first #{parameters.p4} rows only"), () -> assertThat(selectStatement.getParameters()).contains(entry("p4", 3L), entry("p3", 22L)) ); @@ -148,7 +148,7 @@ void testFetchFirstOnlyAfterWhere() { assertAll( () -> assertThat(records).hasSize(3), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1), + () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(1), () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData where id < #{parameters.p1,jdbcType=INTEGER} fetch first #{parameters.p2} rows only"), () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 3L) ); @@ -171,7 +171,7 @@ void testOffsetAndFetchFirstAfterOrderBy() { assertAll( () -> assertThat(records).hasSize(3), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getId).isEqualTo(23), + () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23), () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData order by id offset #{parameters.p1} rows fetch first #{parameters.p2} rows only"), () -> assertThat(selectStatement) .extracting(SelectStatementProvider::getParameters) @@ -196,7 +196,7 @@ void testLimitOnlyAfterOrderBy() { assertAll( () -> assertThat(records).hasSize(3), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1), + () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(1), () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData order by id fetch first #{parameters.p1} rows only"), () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L) ); diff --git a/src/test/java/examples/animal/data/LimitAndOffsetTest.java b/src/test/java/examples/animal/data/LimitAndOffsetTest.java index a5ffc67e5..9569d0751 100644 --- a/src/test/java/examples/animal/data/LimitAndOffsetTest.java +++ b/src/test/java/examples/animal/data/LimitAndOffsetTest.java @@ -79,7 +79,7 @@ void testLimitAndOffsetAfterFrom() { assertAll( () -> assertThat(records).hasSize(3), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getId).isEqualTo(23), + () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23), () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData limit #{parameters.p1} offset #{parameters.p2}"), () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L), () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 22L) @@ -101,7 +101,7 @@ void testLimitOnlyAfterFrom() { assertAll( () -> assertThat(records).hasSize(3), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1), + () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(1), () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData limit #{parameters.p1}"), () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L) ); @@ -122,7 +122,7 @@ void testOffsetOnlyAfterFrom() { assertAll( () -> assertThat(records).hasSize(43), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getId).isEqualTo(23), + () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23), () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData offset #{parameters.p1} rows"), () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 22L) ); @@ -146,7 +146,7 @@ void testLimitAndOffsetAfterWhere() { assertAll( () -> assertThat(records).hasSize(3), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getId).isEqualTo(45), + () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(45), () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData where id < #{parameters.p1,jdbcType=INTEGER} and id > #{parameters.p2,jdbcType=INTEGER} limit #{parameters.p3} offset #{parameters.p4}"), () -> assertThat(selectStatement.getParameters()).containsEntry("p3", 3L), () -> assertThat(selectStatement.getParameters()).containsEntry("p4", 22L) @@ -169,7 +169,7 @@ void testLimitOnlyAfterWhere() { assertAll( () -> assertThat(records).hasSize(3), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1), + () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(1), () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData where id < #{parameters.p1,jdbcType=INTEGER} limit #{parameters.p2}"), () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 3L) ); @@ -191,7 +191,7 @@ void testOffsetOnlyAfterWhere() { assertAll( () -> assertThat(records).hasSize(27), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getId).isEqualTo(23), + () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23), () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData where id < #{parameters.p1,jdbcType=INTEGER} offset #{parameters.p2} rows"), () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 22L) ); @@ -214,7 +214,7 @@ void testLimitAndOffsetAfterOrderBy() { assertAll( () -> assertThat(records).hasSize(3), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getId).isEqualTo(23), + () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23), () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData order by id limit #{parameters.p1} offset #{parameters.p2}"), () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L), () -> assertThat(selectStatement.getParameters()).containsEntry("p2", 22L) @@ -237,7 +237,7 @@ void testLimitOnlyAfterOrderBy() { assertAll( () -> assertThat(records).hasSize(3), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1), + () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(1), () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData order by id limit #{parameters.p1}"), () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 3L) ); @@ -259,7 +259,7 @@ void testOffsetOnlyAfterOrderBy() { assertAll( () -> assertThat(records).hasSize(43), - () -> assertThat(records).first().isNotNull().extracting(AnimalData::getId).isEqualTo(23), + () -> assertThat(records).first().isNotNull().extracting(AnimalData::id).isEqualTo(23), () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select * from AnimalData order by id offset #{parameters.p1} rows"), () -> assertThat(selectStatement.getParameters()).containsEntry("p1", 22L) ); diff --git a/src/test/java/examples/animal/data/MyInCondition.java b/src/test/java/examples/animal/data/MyInCondition.java index e31782dbc..7203e4fb5 100644 --- a/src/test/java/examples/animal/data/MyInCondition.java +++ b/src/test/java/examples/animal/data/MyInCondition.java @@ -19,14 +19,15 @@ import java.util.Objects; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlBuilder; import org.mybatis.dynamic.sql.where.condition.IsIn; public class MyInCondition { - public static IsIn<String> isIn(String...values) { + public static IsIn<String> isIn(@Nullable String...values) { return SqlBuilder.isIn(values) .filter(Objects::nonNull) - .map((String::trim)) + .map(String::trim) .filter(not(String::isEmpty)); } } diff --git a/src/test/java/examples/animal/data/OptionalConditionsAnimalDataTest.java b/src/test/java/examples/animal/data/OptionalConditionsAnimalDataTest.java index f09c2544e..166c21a05 100644 --- a/src/test/java/examples/animal/data/OptionalConditionsAnimalDataTest.java +++ b/src/test/java/examples/animal/data/OptionalConditionsAnimalDataTest.java @@ -80,8 +80,8 @@ void testAllIgnored() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData order by id"), () -> assertThat(animals).hasSize(65), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1), - () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::getId).isEqualTo(2) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1), + () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::id).isEqualTo(2) ); } } @@ -102,8 +102,8 @@ void testIgnoredBetweenRendered() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id = #{parameters.p1,jdbcType=INTEGER} or id = #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(3), - () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(3), + () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -124,8 +124,8 @@ void testIgnoredInWhere() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id = #{parameters.p1,jdbcType=INTEGER} or id = #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(3), - () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(3), + () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -147,8 +147,8 @@ void testManyIgnored() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id = #{parameters.p1,jdbcType=INTEGER} or id = #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(3), - () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(3), + () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -168,8 +168,8 @@ void testIgnoredInitialWhere() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id = #{parameters.p1,jdbcType=INTEGER} or id = #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(3), - () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(3), + () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -188,7 +188,7 @@ void testEqualWhenPresentWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id = #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(1), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -208,7 +208,7 @@ void testEqualWhenPresentWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -228,7 +228,7 @@ void testNotEqualWhenPresentWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <> #{parameters.p1,jdbcType=INTEGER} and id <= #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(9), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -248,7 +248,7 @@ void testNotEqualWhenPresentWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -268,7 +268,7 @@ void testGreaterThanWhenPresentWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id > #{parameters.p1,jdbcType=INTEGER} and id <= #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(6), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(5) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(5) ); } } @@ -288,7 +288,7 @@ void testGreaterThanWhenPresentWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -308,7 +308,7 @@ void testGreaterThanOrEqualToWhenPresentWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id >= #{parameters.p1,jdbcType=INTEGER} and id <= #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(7), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -328,7 +328,7 @@ void testGreaterThanOrEqualToWhenPresentWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -347,7 +347,7 @@ void testLessThanWhenPresentWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id < #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(3), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -367,7 +367,7 @@ void testLessThanWhenPresentWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -386,7 +386,7 @@ void testLessThanOrEqualToWhenPresentWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(4), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -406,7 +406,7 @@ void testLessThanOrEqualToWhenPresentWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -425,7 +425,7 @@ void testIsInWhenPresentWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id in (#{parameters.p1,jdbcType=INTEGER},#{parameters.p2,jdbcType=INTEGER},#{parameters.p3,jdbcType=INTEGER}) order by id"), () -> assertThat(animals).hasSize(3), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -444,7 +444,7 @@ void testIsInWhenPresentWithSomeValues() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id in (#{parameters.p1,jdbcType=INTEGER},#{parameters.p2,jdbcType=INTEGER}) order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(3) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(3) ); } } @@ -464,7 +464,7 @@ void testIsInWhenPresentWithNoValues() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -483,7 +483,7 @@ void testIsInCaseInsensitiveWhenPresentWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where upper(animal_name) in (#{parameters.p1,jdbcType=VARCHAR},#{parameters.p2,jdbcType=VARCHAR}) order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -502,7 +502,7 @@ void testIsInCaseInsensitiveWhenPresentWithSomeValues() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where upper(animal_name) in (#{parameters.p1,jdbcType=VARCHAR},#{parameters.p2,jdbcType=VARCHAR}) order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -522,7 +522,7 @@ void testIsInCaseInsensitiveWhenPresentWithNoValues() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -542,7 +542,7 @@ void testIsNotInWhenPresentWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id not in (#{parameters.p1,jdbcType=INTEGER},#{parameters.p2,jdbcType=INTEGER},#{parameters.p3,jdbcType=INTEGER}) and id <= #{parameters.p4,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(7), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -562,7 +562,7 @@ void testIsNotInWhenPresentWithSomeValues() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id not in (#{parameters.p1,jdbcType=INTEGER},#{parameters.p2,jdbcType=INTEGER}) and id <= #{parameters.p3,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(8), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -582,7 +582,7 @@ void testIsNotInWhenPresentWithNoValues() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -602,7 +602,7 @@ void testIsNotInCaseInsensitiveWhenPresentWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where upper(animal_name) not in (#{parameters.p1,jdbcType=VARCHAR},#{parameters.p2,jdbcType=VARCHAR}) and id <= #{parameters.p3,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(8), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -622,7 +622,7 @@ void testIsNotInCaseInsensitiveWhenPresentWithSomeValues() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where upper(animal_name) not in (#{parameters.p1,jdbcType=VARCHAR},#{parameters.p2,jdbcType=VARCHAR}) and id <= #{parameters.p3,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(8), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -642,7 +642,7 @@ void testIsNotInCaseInsensitiveWhenPresentWithNoValues() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -661,7 +661,7 @@ void testIsBetweenWhenPresentWithValues() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id between #{parameters.p1,jdbcType=INTEGER} and #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(4), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(3) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(3) ); } } @@ -681,7 +681,7 @@ void testIsBetweenWhenPresentWithFirstMissing() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -701,7 +701,7 @@ void testIsBetweenWhenPresentWithSecondMissing() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -721,7 +721,7 @@ void testIsBetweenWhenPresentWithBothMissing() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -741,7 +741,7 @@ void testIsNotBetweenWhenPresentWithValues() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id not between #{parameters.p1,jdbcType=INTEGER} and #{parameters.p2,jdbcType=INTEGER} and id <= #{parameters.p3,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(6), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -761,7 +761,7 @@ void testIsNotBetweenWhenPresentWithFirstMissing() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -781,7 +781,7 @@ void testIsNotBetweenWhenPresentWithSecondMissing() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -801,7 +801,7 @@ void testIsNotBetweenWhenPresentWithBothMissing() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -821,7 +821,7 @@ void testIsLikeWhenPresentWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where animal_name like #{parameters.p1,jdbcType=VARCHAR} and id <= #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(6) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(6) ); } } @@ -841,7 +841,7 @@ void testIsLikeWhenPresentWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -861,7 +861,7 @@ void testIsLikeCaseInsensitiveWhenPresentWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where upper(animal_name) like #{parameters.p1,jdbcType=VARCHAR} and id <= #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(6) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(6) ); } } @@ -881,7 +881,7 @@ void testIsLikeCaseInsensitiveWhenPresentWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -901,7 +901,7 @@ void testIsNotLikeWhenPresentWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where animal_name not like #{parameters.p1,jdbcType=VARCHAR} and id <= #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(8), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -921,7 +921,7 @@ void testIsNotLikeWhenPresentWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -941,7 +941,7 @@ void testIsNotLikeCaseInsensitiveWhenPresentWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where upper(animal_name) not like #{parameters.p1,jdbcType=VARCHAR} and id <= #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(8), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -961,7 +961,7 @@ void testIsNotLikeCaseInsensitiveWhenPresentWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } diff --git a/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java b/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java index a46190941..2ed08cad7 100644 --- a/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java +++ b/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java @@ -40,6 +40,7 @@ import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.render.RenderingStrategies; @@ -50,7 +51,7 @@ class OptionalConditionsWithPredicatesAnimalDataTest { private static final String JDBC_URL = "jdbc:hsqldb:mem:aname"; private static final String JDBC_DRIVER = "org.hsqldb.jdbcDriver"; - private static final Integer NULL_INTEGER = null; + private static final @Nullable Integer NULL_INTEGER = null; private SqlSessionFactory sqlSessionFactory; @@ -78,7 +79,7 @@ void testAllIgnored() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isGreaterThan(NULL_INTEGER).filter(Objects::nonNull)) // the where clause should not render + .where(id, isGreaterThanWhenPresent(NULL_INTEGER)) // the where clause should not render .orderBy(id) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() @@ -87,8 +88,8 @@ void testAllIgnored() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData order by id"), () -> assertThat(animals).hasSize(65), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1), - () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::getId).isEqualTo(2) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1), + () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::id).isEqualTo(2) ); } } @@ -120,7 +121,7 @@ void testIgnoredBetweenRendered() { SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) .where(id, isEqualTo(3)) - .and(id, isNotEqualTo(NULL_INTEGER).filter(Objects::nonNull)) + .and(id, isNotEqualToWhenPresent(NULL_INTEGER)) .or(id, isEqualTo(4).filter(Objects::nonNull)) .orderBy(id) .build() @@ -129,8 +130,8 @@ void testIgnoredBetweenRendered() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id = #{parameters.p1,jdbcType=INTEGER} or id = #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(3), - () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(3), + () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -141,7 +142,7 @@ void testIgnoredInWhere() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isLessThanWhenPresent(NULL_INTEGER)) .and(id, isEqualTo(3).filter(Objects::nonNull)) .or(id, isEqualTo(4).filter(Objects::nonNull)) .orderBy(id) @@ -151,8 +152,8 @@ void testIgnoredInWhere() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id = #{parameters.p1,jdbcType=INTEGER} or id = #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(3), - () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(3), + () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -163,10 +164,10 @@ void testManyIgnored() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull), and(id, isGreaterThanOrEqualTo(NULL_INTEGER).filter(Objects::nonNull))) - .and(id, isEqualTo(NULL_INTEGER).filter(Objects::nonNull), or(id, isEqualTo(3), and(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull)))) - .or(id, isEqualTo(4).filter(Objects::nonNull), and(id, isGreaterThanOrEqualTo(NULL_INTEGER).filter(Objects::nonNull))) - .and(id, isNotEqualTo(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isLessThanWhenPresent(NULL_INTEGER), and(id, isGreaterThanOrEqualToWhenPresent(NULL_INTEGER))) + .and(id, isEqualToWhenPresent(NULL_INTEGER), or(id, isEqualTo(3), and(id, isLessThanWhenPresent(NULL_INTEGER)))) + .or(id, isEqualToWhenPresent(4), and(id, isGreaterThanOrEqualToWhenPresent(NULL_INTEGER))) + .and(id, isNotEqualToWhenPresent(NULL_INTEGER)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -174,8 +175,8 @@ void testManyIgnored() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id = #{parameters.p1,jdbcType=INTEGER} or id = #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(3), - () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(3), + () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -186,7 +187,7 @@ void testIgnoredInitialWhere() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull), and(id, isEqualTo(3).filter(Objects::nonNull))) + .where(id, isLessThanWhenPresent(NULL_INTEGER), and(id, isEqualTo(3).filter(Objects::nonNull))) .or(id, isEqualTo(4).filter(Objects::nonNull)) .orderBy(id) .build() @@ -195,8 +196,8 @@ void testIgnoredInitialWhere() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id = #{parameters.p1,jdbcType=INTEGER} or id = #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(3), - () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(3), + () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -215,7 +216,7 @@ void testEqualWhenWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id = #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(1), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -226,7 +227,7 @@ void testEqualWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isEqualTo(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isEqualToWhenPresent(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -235,7 +236,7 @@ void testEqualWhenWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -255,7 +256,7 @@ void testNotEqualWhenWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <> #{parameters.p1,jdbcType=INTEGER} and id <= #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(9), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -266,7 +267,7 @@ void testNotEqualWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isNotEqualTo(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isNotEqualToWhenPresent(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -275,7 +276,7 @@ void testNotEqualWhenWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -295,7 +296,7 @@ void testGreaterThanWhenWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id > #{parameters.p1,jdbcType=INTEGER} and id <= #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(6), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(5) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(5) ); } } @@ -306,7 +307,7 @@ void testGreaterThanWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isGreaterThan(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isGreaterThanWhenPresent(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -315,7 +316,7 @@ void testGreaterThanWhenWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -335,7 +336,7 @@ void testGreaterThanOrEqualToWhenWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id >= #{parameters.p1,jdbcType=INTEGER} and id <= #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(7), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -346,7 +347,7 @@ void testGreaterThanOrEqualToWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isGreaterThanOrEqualTo(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isGreaterThanOrEqualToWhenPresent(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -355,7 +356,7 @@ void testGreaterThanOrEqualToWhenWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -374,7 +375,7 @@ void testLessThanWhenWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id < #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(3), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -385,7 +386,7 @@ void testLessThanWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isLessThanWhenPresent(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -394,7 +395,7 @@ void testLessThanWhenWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -413,7 +414,7 @@ void testLessThanOrEqualToWhenWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(4), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -424,7 +425,7 @@ void testLessThanOrEqualToWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThanOrEqualTo(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isLessThanOrEqualToWhenPresent(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -433,7 +434,7 @@ void testLessThanOrEqualToWhenWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -452,7 +453,7 @@ void testIsInWhenWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id in (#{parameters.p1,jdbcType=INTEGER},#{parameters.p2,jdbcType=INTEGER},#{parameters.p3,jdbcType=INTEGER}) order by id"), () -> assertThat(animals).hasSize(3), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -463,7 +464,7 @@ void testIsInWhenWithSomeValues() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isIn(3, NULL_INTEGER, 5).filter(Objects::nonNull).map(i -> i + 3)) + .where(id, isInWhenPresent(3, NULL_INTEGER, 5).map(i -> i + 3)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -471,8 +472,8 @@ void testIsInWhenWithSomeValues() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id in (#{parameters.p1,jdbcType=INTEGER},#{parameters.p2,jdbcType=INTEGER}) order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(6), - () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::getId).isEqualTo(8) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(6), + () -> assertThat(animals).element(1).isNotNull().extracting(AnimalData::id).isEqualTo(8) ); } } @@ -491,7 +492,7 @@ void testIsInCaseInsensitiveWhenWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where upper(animal_name) in (#{parameters.p1,jdbcType=VARCHAR},#{parameters.p2,jdbcType=VARCHAR}) order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -504,8 +505,8 @@ void testValueStreamTransformer() { .from(animalData) .where(animalName, isIn(" Mouse", " ", null, "", "Musk shrew ") .filter(Objects::nonNull) - .map(String::trim) - .filter(not(String::isEmpty))) + .map(String::trim) + .filter(not(String::isEmpty))) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -513,7 +514,7 @@ void testValueStreamTransformer() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where animal_name in (#{parameters.p1,jdbcType=VARCHAR},#{parameters.p2,jdbcType=VARCHAR}) order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -532,7 +533,7 @@ void testValueStreamTransformerWithCustomCondition() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where animal_name in (#{parameters.p1,jdbcType=VARCHAR},#{parameters.p2,jdbcType=VARCHAR}) order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(4) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(4) ); } } @@ -552,7 +553,7 @@ void testIsInCaseInsensitiveWhenWithNoValues() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -572,7 +573,7 @@ void testIsNotInWhenWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id not in (#{parameters.p1,jdbcType=INTEGER},#{parameters.p2,jdbcType=INTEGER},#{parameters.p3,jdbcType=INTEGER}) and id <= #{parameters.p4,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(7), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -583,7 +584,7 @@ void testIsNotInWhenWithSomeValues() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isNotIn(3, NULL_INTEGER, 5).filter(Objects::nonNull)) + .where(id, isNotInWhenPresent(3, NULL_INTEGER, 5)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -592,7 +593,7 @@ void testIsNotInWhenWithSomeValues() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id not in (#{parameters.p1,jdbcType=INTEGER},#{parameters.p2,jdbcType=INTEGER}) and id <= #{parameters.p3,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(8), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -612,7 +613,7 @@ void testIsNotInCaseInsensitiveWhenWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where upper(animal_name) not in (#{parameters.p1,jdbcType=VARCHAR},#{parameters.p2,jdbcType=VARCHAR}) and id <= #{parameters.p3,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(8), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -632,7 +633,7 @@ void testIsNotInCaseInsensitiveWhenWithNoValues() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -651,7 +652,7 @@ void testIsBetweenWhenWithValues() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id between #{parameters.p1,jdbcType=INTEGER} and #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(4), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(3) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(3) ); } } @@ -662,7 +663,7 @@ void testIsBetweenWhenWithFirstMissing() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isBetween(NULL_INTEGER).and(6).filter(Predicates.bothPresent())) + .where(id, isBetweenWhenPresent(NULL_INTEGER).and(6)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -671,7 +672,7 @@ void testIsBetweenWhenWithFirstMissing() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -682,7 +683,7 @@ void testIsBetweenWhenWithSecondMissing() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isBetween(3).and(NULL_INTEGER).filter(Predicates.bothPresent())) + .where(id, isBetweenWhenPresent(3).and(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -691,7 +692,7 @@ void testIsBetweenWhenWithSecondMissing() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -702,7 +703,7 @@ void testIsBetweenWhenWithBothMissing() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isBetween(NULL_INTEGER).and(NULL_INTEGER).filter(Predicates.bothPresent())) + .where(id, isBetweenWhenPresent(NULL_INTEGER).and(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -711,7 +712,7 @@ void testIsBetweenWhenWithBothMissing() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -731,7 +732,7 @@ void testIsNotBetweenWhenWithValues() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id not between #{parameters.p1,jdbcType=INTEGER} and #{parameters.p2,jdbcType=INTEGER} and id <= #{parameters.p3,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(6), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -742,7 +743,7 @@ void testIsNotBetweenWhenWithFirstMissing() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isNotBetween(NULL_INTEGER).and(6).filter(Predicates.bothPresent())) + .where(id, isNotBetweenWhenPresent(NULL_INTEGER).and(6)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -751,7 +752,7 @@ void testIsNotBetweenWhenWithFirstMissing() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -762,7 +763,7 @@ void testIsNotBetweenWhenWithSecondMissing() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isNotBetween(3).and(NULL_INTEGER).filter(Predicates.bothPresent())) + .where(id, isNotBetweenWhenPresent(3).and(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -771,7 +772,7 @@ void testIsNotBetweenWhenWithSecondMissing() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -782,7 +783,7 @@ void testIsNotBetweenWhenWithBothMissing() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isNotBetween(NULL_INTEGER).and(NULL_INTEGER).filter(Predicates.bothPresent())) + .where(id, isNotBetweenWhenPresent(NULL_INTEGER).and(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -791,7 +792,7 @@ void testIsNotBetweenWhenWithBothMissing() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -811,7 +812,7 @@ void testIsLikeWhenWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where animal_name like #{parameters.p1,jdbcType=VARCHAR} and id <= #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(6) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(6) ); } } @@ -822,7 +823,7 @@ void testIsLikeWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isLike((String) null).filter(Objects::nonNull)) + .where(animalName, isLikeWhenPresent((String) null)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -831,7 +832,7 @@ void testIsLikeWhenWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -842,7 +843,7 @@ void testIsLikeCaseInsensitiveWhenWithValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isLikeCaseInsensitive("%MoLe").filter(Objects::nonNull)) + .where(animalName, isLikeCaseInsensitive("%MoLe")) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -851,7 +852,7 @@ void testIsLikeCaseInsensitiveWhenWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where upper(animal_name) like #{parameters.p1,jdbcType=VARCHAR} and id <= #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(2), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(6) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(6) ); } } @@ -862,7 +863,7 @@ void testIsLikeCaseInsensitiveWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isLikeCaseInsensitive((String) null).filter(Objects::nonNull)) + .where(animalName, isLikeCaseInsensitiveWhenPresent((String) null)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -871,7 +872,7 @@ void testIsLikeCaseInsensitiveWhenWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -891,7 +892,7 @@ void testIsNotLikeWhenWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where animal_name not like #{parameters.p1,jdbcType=VARCHAR} and id <= #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(8), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -902,7 +903,7 @@ void testIsNotLikeWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isNotLike((String) null).filter(Objects::nonNull)) + .where(animalName, isNotLikeWhenPresent((String) null)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -911,7 +912,7 @@ void testIsNotLikeWhenWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -922,7 +923,7 @@ void testIsNotLikeCaseInsensitiveWhenWithValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isNotLikeCaseInsensitive("%MoLe").filter(Objects::nonNull)) + .where(animalName, isNotLikeCaseInsensitive("%MoLe")) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -931,7 +932,7 @@ void testIsNotLikeCaseInsensitiveWhenWithValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where upper(animal_name) not like #{parameters.p1,jdbcType=VARCHAR} and id <= #{parameters.p2,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(8), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } @@ -942,7 +943,7 @@ void testIsNotLikeCaseInsensitiveWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isNotLikeCaseInsensitive((String) null).filter(Objects::nonNull)) + .where(animalName, isNotLikeCaseInsensitiveWhenPresent((String) null)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -951,7 +952,7 @@ void testIsNotLikeCaseInsensitiveWhenWithoutValue() { assertAll( () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id <= #{parameters.p1,jdbcType=INTEGER} order by id"), () -> assertThat(animals).hasSize(10), - () -> assertThat(animals).first().isNotNull().extracting(AnimalData::getId).isEqualTo(1) + () -> assertThat(animals).first().isNotNull().extracting(AnimalData::id).isEqualTo(1) ); } } diff --git a/src/test/java/examples/animal/data/package-info.java b/src/test/java/examples/animal/data/package-info.java new file mode 100644 index 000000000..0b0ff393f --- /dev/null +++ b/src/test/java/examples/animal/data/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package examples.animal.data; + +import org.jspecify.annotations.NullMarked; diff --git a/src/test/java/examples/paging/LimitAndOffsetMapper.java b/src/test/java/examples/paging/LimitAndOffsetMapper.java index 84146d8b9..14bd2d8b0 100644 --- a/src/test/java/examples/paging/LimitAndOffsetMapper.java +++ b/src/test/java/examples/paging/LimitAndOffsetMapper.java @@ -19,8 +19,7 @@ import java.util.List; -import org.apache.ibatis.annotations.Result; -import org.apache.ibatis.annotations.Results; +import org.apache.ibatis.annotations.Arg; import org.apache.ibatis.annotations.SelectProvider; import org.mybatis.dynamic.sql.select.QueryExpressionDSL; import org.mybatis.dynamic.sql.select.SelectDSL; @@ -32,12 +31,10 @@ public interface LimitAndOffsetMapper { @SelectProvider(type=SqlProviderAdapter.class, method="select") - @Results(id="AnimalDataResult", value={ - @Result(column="id", property="id", id=true), - @Result(column="animal_name", property="animalName"), - @Result(column="brain_weight", property="brainWeight"), - @Result(column="body_weight", property="bodyWeight") - }) + @Arg(column = "id", javaType = int.class, id = true) + @Arg(column = "animal_name", javaType = String.class) + @Arg(column = "brain_weight", javaType = double.class) + @Arg(column = "body_weight", javaType = double.class) List<AnimalData> selectMany(SelectStatementProvider selectStatement); default QueryExpressionDSL<LimitAndOffsetAdapter<List<AnimalData>>> selectWithLimitAndOffset(int limit, int offset) { diff --git a/src/test/java/examples/paging/LimitAndOffsetTest.java b/src/test/java/examples/paging/LimitAndOffsetTest.java index e145568d4..6e8d68ae1 100644 --- a/src/test/java/examples/paging/LimitAndOffsetTest.java +++ b/src/test/java/examples/paging/LimitAndOffsetTest.java @@ -73,7 +73,7 @@ void testLimitAndOffset() { .execute(); assertThat(rows).hasSize(5); - assertThat(rows.get(0).getId()).isEqualTo(4); + assertThat(rows.get(0).id()).isEqualTo(4); } } } diff --git a/src/test/java/examples/paging/package-info.java b/src/test/java/examples/paging/package-info.java new file mode 100644 index 000000000..c8f8f4390 --- /dev/null +++ b/src/test/java/examples/paging/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package examples.paging; + +import org.jspecify.annotations.NullMarked; From a2fec6a935acb1bc04f00d1364ac41b40bedfc99 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Sun, 6 Apr 2025 18:16:55 -0400 Subject: [PATCH 231/260] Properly handle nullability in the when present conditions --- .../org/mybatis/dynamic/sql/SqlBuilder.java | 108 +++-- .../sql/where/condition/AndGatherer.java | 4 +- .../sql/where/condition/IsBetween.java | 20 - .../where/condition/IsBetweenWhenPresent.java | 108 +++++ .../where/condition/IsEqualToWhenPresent.java | 72 +++ .../IsGreaterThanOrEqualToWhenPresent.java | 71 +++ .../condition/IsGreaterThanWhenPresent.java | 71 +++ .../where/condition/IsInCaseInsensitive.java | 5 +- .../IsInCaseInsensitiveWhenPresent.java | 13 +- .../sql/where/condition/IsInWhenPresent.java | 12 +- .../IsLessThanOrEqualToWhenPresent.java | 71 +++ .../condition/IsLessThanWhenPresent.java | 72 +++ .../condition/IsLikeCaseInsensitive.java | 2 +- .../IsLikeCaseInsensitiveWhenPresent.java | 73 +++ .../where/condition/IsLikeWhenPresent.java | 72 +++ .../sql/where/condition/IsNotBetween.java | 21 - .../condition/IsNotBetweenWhenPresent.java | 109 +++++ .../condition/IsNotEqualToWhenPresent.java | 71 +++ .../condition/IsNotInCaseInsensitive.java | 5 +- .../IsNotInCaseInsensitiveWhenPresent.java | 13 +- .../where/condition/IsNotInWhenPresent.java | 13 +- .../condition/IsNotLikeCaseInsensitive.java | 2 +- .../IsNotLikeCaseInsensitiveWhenPresent.java | 73 +++ .../where/condition/IsNotLikeWhenPresent.java | 71 +++ .../sql/util/kotlin/elements/SqlElements.kt | 38 +- .../sql/where/condition/NullContractTest.java | 441 ++++++++++++++++++ .../sql/where/condition/SupplierTest.java | 48 +- 27 files changed, 1532 insertions(+), 147 deletions(-) create mode 100644 src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetweenWhenPresent.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToWhenPresent.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWhenPresent.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanWhenPresent.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToWhenPresent.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanWhenPresent.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitiveWhenPresent.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeWhenPresent.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetweenWhenPresent.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToWhenPresent.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitiveWhenPresent.java create mode 100644 src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeWhenPresent.java create mode 100644 src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java diff --git a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java index 2f365de1e..9790633b0 100644 --- a/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java +++ b/src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java @@ -21,6 +21,7 @@ import java.util.Objects; import java.util.function.Supplier; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.delete.DeleteDSL; import org.mybatis.dynamic.sql.delete.DeleteModel; @@ -62,14 +63,18 @@ import org.mybatis.dynamic.sql.util.Buildable; import org.mybatis.dynamic.sql.where.WhereDSL; import org.mybatis.dynamic.sql.where.condition.IsBetween; +import org.mybatis.dynamic.sql.where.condition.IsBetweenWhenPresent; import org.mybatis.dynamic.sql.where.condition.IsEqualTo; import org.mybatis.dynamic.sql.where.condition.IsEqualToColumn; +import org.mybatis.dynamic.sql.where.condition.IsEqualToWhenPresent; import org.mybatis.dynamic.sql.where.condition.IsEqualToWithSubselect; import org.mybatis.dynamic.sql.where.condition.IsGreaterThan; import org.mybatis.dynamic.sql.where.condition.IsGreaterThanColumn; import org.mybatis.dynamic.sql.where.condition.IsGreaterThanOrEqualTo; import org.mybatis.dynamic.sql.where.condition.IsGreaterThanOrEqualToColumn; +import org.mybatis.dynamic.sql.where.condition.IsGreaterThanOrEqualToWhenPresent; import org.mybatis.dynamic.sql.where.condition.IsGreaterThanOrEqualToWithSubselect; +import org.mybatis.dynamic.sql.where.condition.IsGreaterThanWhenPresent; import org.mybatis.dynamic.sql.where.condition.IsGreaterThanWithSubselect; import org.mybatis.dynamic.sql.where.condition.IsIn; import org.mybatis.dynamic.sql.where.condition.IsInCaseInsensitive; @@ -80,13 +85,19 @@ import org.mybatis.dynamic.sql.where.condition.IsLessThanColumn; import org.mybatis.dynamic.sql.where.condition.IsLessThanOrEqualTo; import org.mybatis.dynamic.sql.where.condition.IsLessThanOrEqualToColumn; +import org.mybatis.dynamic.sql.where.condition.IsLessThanOrEqualToWhenPresent; import org.mybatis.dynamic.sql.where.condition.IsLessThanOrEqualToWithSubselect; +import org.mybatis.dynamic.sql.where.condition.IsLessThanWhenPresent; import org.mybatis.dynamic.sql.where.condition.IsLessThanWithSubselect; import org.mybatis.dynamic.sql.where.condition.IsLike; import org.mybatis.dynamic.sql.where.condition.IsLikeCaseInsensitive; +import org.mybatis.dynamic.sql.where.condition.IsLikeCaseInsensitiveWhenPresent; +import org.mybatis.dynamic.sql.where.condition.IsLikeWhenPresent; import org.mybatis.dynamic.sql.where.condition.IsNotBetween; +import org.mybatis.dynamic.sql.where.condition.IsNotBetweenWhenPresent; import org.mybatis.dynamic.sql.where.condition.IsNotEqualTo; import org.mybatis.dynamic.sql.where.condition.IsNotEqualToColumn; +import org.mybatis.dynamic.sql.where.condition.IsNotEqualToWhenPresent; import org.mybatis.dynamic.sql.where.condition.IsNotEqualToWithSubselect; import org.mybatis.dynamic.sql.where.condition.IsNotIn; import org.mybatis.dynamic.sql.where.condition.IsNotInCaseInsensitive; @@ -95,6 +106,8 @@ import org.mybatis.dynamic.sql.where.condition.IsNotInWithSubselect; import org.mybatis.dynamic.sql.where.condition.IsNotLike; import org.mybatis.dynamic.sql.where.condition.IsNotLikeCaseInsensitive; +import org.mybatis.dynamic.sql.where.condition.IsNotLikeCaseInsensitiveWhenPresent; +import org.mybatis.dynamic.sql.where.condition.IsNotLikeWhenPresent; import org.mybatis.dynamic.sql.where.condition.IsNotNull; import org.mybatis.dynamic.sql.where.condition.IsNull; @@ -634,11 +647,11 @@ static <T> IsEqualToColumn<T> isEqualTo(BasicColumn column) { return IsEqualToColumn.of(column); } - static <T> IsEqualTo<T> isEqualToWhenPresent(@Nullable T value) { - return value == null ? IsEqualTo.empty() : IsEqualTo.of(value); + static <T> IsEqualToWhenPresent<T> isEqualToWhenPresent(@Nullable T value) { + return IsEqualToWhenPresent.of(value); } - static <T> IsEqualTo<T> isEqualToWhenPresent(Supplier<@Nullable T> valueSupplier) { + static <T> IsEqualToWhenPresent<T> isEqualToWhenPresent(Supplier<@Nullable T> valueSupplier) { return isEqualToWhenPresent(valueSupplier.get()); } @@ -658,11 +671,11 @@ static <T> IsNotEqualToColumn<T> isNotEqualTo(BasicColumn column) { return IsNotEqualToColumn.of(column); } - static <T> IsNotEqualTo<T> isNotEqualToWhenPresent(@Nullable T value) { - return value == null ? IsNotEqualTo.empty() : IsNotEqualTo.of(value); + static <T> IsNotEqualToWhenPresent<T> isNotEqualToWhenPresent(@Nullable T value) { + return IsNotEqualToWhenPresent.of(value); } - static <T> IsNotEqualTo<T> isNotEqualToWhenPresent(Supplier<@Nullable T> valueSupplier) { + static <T> IsNotEqualToWhenPresent<T> isNotEqualToWhenPresent(Supplier<@Nullable T> valueSupplier) { return isNotEqualToWhenPresent(valueSupplier.get()); } @@ -682,11 +695,11 @@ static <T> IsGreaterThanColumn<T> isGreaterThan(BasicColumn column) { return IsGreaterThanColumn.of(column); } - static <T> IsGreaterThan<T> isGreaterThanWhenPresent(@Nullable T value) { - return value == null ? IsGreaterThan.empty() : IsGreaterThan.of(value); + static <T> IsGreaterThanWhenPresent<T> isGreaterThanWhenPresent(@Nullable T value) { + return IsGreaterThanWhenPresent.of(value); } - static <T> IsGreaterThan<T> isGreaterThanWhenPresent(Supplier<@Nullable T> valueSupplier) { + static <T> IsGreaterThanWhenPresent<T> isGreaterThanWhenPresent(Supplier<@Nullable T> valueSupplier) { return isGreaterThanWhenPresent(valueSupplier.get()); } @@ -707,11 +720,12 @@ static <T> IsGreaterThanOrEqualToColumn<T> isGreaterThanOrEqualTo(BasicColumn co return IsGreaterThanOrEqualToColumn.of(column); } - static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualToWhenPresent(@Nullable T value) { - return value == null ? IsGreaterThanOrEqualTo.empty() : IsGreaterThanOrEqualTo.of(value); + static <T> IsGreaterThanOrEqualToWhenPresent<T> isGreaterThanOrEqualToWhenPresent(@Nullable T value) { + return IsGreaterThanOrEqualToWhenPresent.of(value); } - static <T> IsGreaterThanOrEqualTo<T> isGreaterThanOrEqualToWhenPresent(Supplier<@Nullable T> valueSupplier) { + static <T> IsGreaterThanOrEqualToWhenPresent<T> isGreaterThanOrEqualToWhenPresent( + Supplier<@Nullable T> valueSupplier) { return isGreaterThanOrEqualToWhenPresent(valueSupplier.get()); } @@ -731,11 +745,11 @@ static <T> IsLessThanColumn<T> isLessThan(BasicColumn column) { return IsLessThanColumn.of(column); } - static <T> IsLessThan<T> isLessThanWhenPresent(@Nullable T value) { - return value == null ? IsLessThan.empty() : IsLessThan.of(value); + static <T> IsLessThanWhenPresent<T> isLessThanWhenPresent(@Nullable T value) { + return IsLessThanWhenPresent.of(value); } - static <T> IsLessThan<T> isLessThanWhenPresent(Supplier<@Nullable T> valueSupplier) { + static <T> IsLessThanWhenPresent<T> isLessThanWhenPresent(Supplier<@Nullable T> valueSupplier) { return isLessThanWhenPresent(valueSupplier.get()); } @@ -755,20 +769,20 @@ static <T> IsLessThanOrEqualToColumn<T> isLessThanOrEqualTo(BasicColumn column) return IsLessThanOrEqualToColumn.of(column); } - static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualToWhenPresent(@Nullable T value) { - return value == null ? IsLessThanOrEqualTo.empty() : IsLessThanOrEqualTo.of(value); + static <T> IsLessThanOrEqualToWhenPresent<T> isLessThanOrEqualToWhenPresent(@Nullable T value) { + return IsLessThanOrEqualToWhenPresent.of(value); } - static <T> IsLessThanOrEqualTo<T> isLessThanOrEqualToWhenPresent(Supplier<@Nullable T> valueSupplier) { + static <T> IsLessThanOrEqualToWhenPresent<T> isLessThanOrEqualToWhenPresent(Supplier<@Nullable T> valueSupplier) { return isLessThanOrEqualToWhenPresent(valueSupplier.get()); } @SafeVarargs - static <T> IsIn<T> isIn(T... values) { + static <T> IsIn<T> isIn(@NonNull T... values) { return IsIn.of(values); } - static <T> IsIn<T> isIn(Collection<T> values) { + static <T> IsIn<T> isIn(Collection<@NonNull T> values) { return IsIn.of(values); } @@ -782,15 +796,15 @@ static <T> IsInWhenPresent<T> isInWhenPresent(@Nullable T... values) { } static <T> IsInWhenPresent<T> isInWhenPresent(@Nullable Collection<@Nullable T> values) { - return values == null ? IsInWhenPresent.empty() : IsInWhenPresent.of(values); + return IsInWhenPresent.of(values); } @SafeVarargs - static <T> IsNotIn<T> isNotIn(T... values) { + static <T> IsNotIn<T> isNotIn(@NonNull T... values) { return IsNotIn.of(values); } - static <T> IsNotIn<T> isNotIn(Collection<T> values) { + static <T> IsNotIn<T> isNotIn(Collection<@NonNull T> values) { return IsNotIn.of(values); } @@ -804,22 +818,22 @@ static <T> IsNotInWhenPresent<T> isNotInWhenPresent(@Nullable T... values) { } static <T> IsNotInWhenPresent<T> isNotInWhenPresent(@Nullable Collection<@Nullable T> values) { - return values == null ? IsNotInWhenPresent.empty() : IsNotInWhenPresent.of(values); + return IsNotInWhenPresent.of(values); } static <T> IsBetween.Builder<T> isBetween(T value1) { return IsBetween.isBetween(value1); } - static <T> IsBetween.Builder<T> isBetween(Supplier<T> valueSupplier1) { + static <T> IsBetween.Builder<T> isBetween(Supplier<@NonNull T> valueSupplier1) { return isBetween(valueSupplier1.get()); } - static <T> IsBetween.WhenPresentBuilder<T> isBetweenWhenPresent(@Nullable T value1) { - return IsBetween.isBetweenWhenPresent(value1); + static <T> IsBetweenWhenPresent.Builder<T> isBetweenWhenPresent(@Nullable T value1) { + return IsBetweenWhenPresent.isBetweenWhenPresent(value1); } - static <T> IsBetween.WhenPresentBuilder<T> isBetweenWhenPresent(Supplier<@Nullable T> valueSupplier1) { + static <T> IsBetweenWhenPresent.Builder<T> isBetweenWhenPresent(Supplier<@Nullable T> valueSupplier1) { return isBetweenWhenPresent(valueSupplier1.get()); } @@ -827,15 +841,15 @@ static <T> IsNotBetween.Builder<T> isNotBetween(T value1) { return IsNotBetween.isNotBetween(value1); } - static <T> IsNotBetween.Builder<T> isNotBetween(Supplier<T> valueSupplier1) { + static <T> IsNotBetween.Builder<T> isNotBetween(Supplier<@NonNull T> valueSupplier1) { return isNotBetween(valueSupplier1.get()); } - static <T> IsNotBetween.WhenPresentBuilder<T> isNotBetweenWhenPresent(@Nullable T value1) { - return IsNotBetween.isNotBetweenWhenPresent(value1); + static <T> IsNotBetweenWhenPresent.Builder<T> isNotBetweenWhenPresent(@Nullable T value1) { + return IsNotBetweenWhenPresent.isNotBetweenWhenPresent(value1); } - static <T> IsNotBetween.WhenPresentBuilder<T> isNotBetweenWhenPresent(Supplier<@Nullable T> valueSupplier1) { + static <T> IsNotBetweenWhenPresent.Builder<T> isNotBetweenWhenPresent(Supplier<@Nullable T> valueSupplier1) { return isNotBetweenWhenPresent(valueSupplier1.get()); } @@ -848,11 +862,11 @@ static <T> IsLike<T> isLike(Supplier<T> valueSupplier) { return isLike(valueSupplier.get()); } - static <T> IsLike<T> isLikeWhenPresent(@Nullable T value) { - return value == null ? IsLike.empty() : IsLike.of(value); + static <T> IsLikeWhenPresent<T> isLikeWhenPresent(@Nullable T value) { + return IsLikeWhenPresent.of(value); } - static <T> IsLike<T> isLikeWhenPresent(Supplier<@Nullable T> valueSupplier) { + static <T> IsLikeWhenPresent<T> isLikeWhenPresent(Supplier<@Nullable T> valueSupplier) { return isLikeWhenPresent(valueSupplier.get()); } @@ -864,11 +878,11 @@ static <T> IsNotLike<T> isNotLike(Supplier<T> valueSupplier) { return isNotLike(valueSupplier.get()); } - static <T> IsNotLike<T> isNotLikeWhenPresent(@Nullable T value) { - return value == null ? IsNotLike.empty() : IsNotLike.of(value); + static <T> IsNotLikeWhenPresent<T> isNotLikeWhenPresent(@Nullable T value) { + return IsNotLikeWhenPresent.of(value); } - static <T> IsNotLike<T> isNotLikeWhenPresent(Supplier<@Nullable T> valueSupplier) { + static <T> IsNotLikeWhenPresent<T> isNotLikeWhenPresent(Supplier<@Nullable T> valueSupplier) { return isNotLikeWhenPresent(valueSupplier.get()); } @@ -890,11 +904,12 @@ static IsLikeCaseInsensitive<String> isLikeCaseInsensitive(Supplier<String> valu return isLikeCaseInsensitive(valueSupplier.get()); } - static IsLikeCaseInsensitive<String> isLikeCaseInsensitiveWhenPresent(@Nullable String value) { - return value == null ? IsLikeCaseInsensitive.empty() : IsLikeCaseInsensitive.of(value); + static IsLikeCaseInsensitiveWhenPresent<String> isLikeCaseInsensitiveWhenPresent(@Nullable String value) { + return IsLikeCaseInsensitiveWhenPresent.of(value); } - static IsLikeCaseInsensitive<String> isLikeCaseInsensitiveWhenPresent(Supplier<@Nullable String> valueSupplier) { + static IsLikeCaseInsensitiveWhenPresent<String> isLikeCaseInsensitiveWhenPresent( + Supplier<@Nullable String> valueSupplier) { return isLikeCaseInsensitiveWhenPresent(valueSupplier.get()); } @@ -906,11 +921,11 @@ static IsNotLikeCaseInsensitive<String> isNotLikeCaseInsensitive(Supplier<String return isNotLikeCaseInsensitive(valueSupplier.get()); } - static IsNotLikeCaseInsensitive<String> isNotLikeCaseInsensitiveWhenPresent(@Nullable String value) { - return value == null ? IsNotLikeCaseInsensitive.empty() : IsNotLikeCaseInsensitive.of(value); + static IsNotLikeCaseInsensitiveWhenPresent<String> isNotLikeCaseInsensitiveWhenPresent(@Nullable String value) { + return IsNotLikeCaseInsensitiveWhenPresent.of(value); } - static IsNotLikeCaseInsensitive<String> isNotLikeCaseInsensitiveWhenPresent( + static IsNotLikeCaseInsensitiveWhenPresent<String> isNotLikeCaseInsensitiveWhenPresent( Supplier<@Nullable String> valueSupplier) { return isNotLikeCaseInsensitiveWhenPresent(valueSupplier.get()); } @@ -929,7 +944,7 @@ static IsInCaseInsensitiveWhenPresent<String> isInCaseInsensitiveWhenPresent(@Nu static IsInCaseInsensitiveWhenPresent<String> isInCaseInsensitiveWhenPresent( @Nullable Collection<@Nullable String> values) { - return values == null ? IsInCaseInsensitiveWhenPresent.empty() : IsInCaseInsensitiveWhenPresent.of(values); + return IsInCaseInsensitiveWhenPresent.of(values); } static IsNotInCaseInsensitive<String> isNotInCaseInsensitive(String... values) { @@ -946,8 +961,7 @@ static IsNotInCaseInsensitiveWhenPresent<String> isNotInCaseInsensitiveWhenPrese static IsNotInCaseInsensitiveWhenPresent<String> isNotInCaseInsensitiveWhenPresent( @Nullable Collection<@Nullable String> values) { - return values == null ? IsNotInCaseInsensitiveWhenPresent.empty() : - IsNotInCaseInsensitiveWhenPresent.of(values); + return IsNotInCaseInsensitiveWhenPresent.of(values); } // order by support diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java index 8a587262a..c9514f3fa 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/AndGatherer.java @@ -17,6 +17,8 @@ import java.util.function.Supplier; +import org.jspecify.annotations.NonNull; + /** * Utility class supporting the "and" part of a between condition. This class supports builders, so it is mutable. * @@ -38,7 +40,7 @@ public R and(T value2) { return build(value2); } - public R and(Supplier<T> valueSupplier2) { + public R and(Supplier<@NonNull T> valueSupplier2) { return and(valueSupplier2.get()); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java index 0e6700fb0..fab5e70f6 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java @@ -20,7 +20,6 @@ import java.util.function.Function; import java.util.function.Predicate; -import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractTwoValueCondition; public class IsBetween<T> extends AbstractTwoValueCondition<T> @@ -86,10 +85,6 @@ public static <T> Builder<T> isBetween(T value1) { return new Builder<>(value1); } - public static <T> WhenPresentBuilder<T> isBetweenWhenPresent(@Nullable T value1) { - return new WhenPresentBuilder<>(value1); - } - public static class Builder<T> extends AndGatherer<T, IsBetween<T>> { private Builder(T value1) { super(value1); @@ -100,19 +95,4 @@ protected IsBetween<T> build(T value2) { return new IsBetween<>(value1, value2); } } - - public static class WhenPresentBuilder<T> extends AndWhenPresentGatherer<T, IsBetween<T>> { - private WhenPresentBuilder(@Nullable T value1) { - super(value1); - } - - @Override - protected IsBetween<T> build(@Nullable T value2) { - if (value1 == null || value2 == null) { - return empty(); - } else { - return new IsBetween<>(value1, value2); - } - } - } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetweenWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetweenWhenPresent.java new file mode 100644 index 000000000..8c23cdfbb --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetweenWhenPresent.java @@ -0,0 +1,108 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.where.condition; + +import java.util.NoSuchElementException; +import java.util.function.BiPredicate; +import java.util.function.Function; +import java.util.function.Predicate; + +import org.jspecify.annotations.Nullable; +import org.mybatis.dynamic.sql.AbstractTwoValueCondition; + +public class IsBetweenWhenPresent<T> extends AbstractTwoValueCondition<T> + implements AbstractTwoValueCondition.Filterable<T>, AbstractTwoValueCondition.Mappable<T> { + private static final IsBetweenWhenPresent<?> EMPTY = new IsBetweenWhenPresent<Object>(-1, -1) { + @Override + public Object value1() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public Object value2() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public boolean isEmpty() { + return true; + } + }; + + public static <T> IsBetweenWhenPresent<T> empty() { + @SuppressWarnings("unchecked") + IsBetweenWhenPresent<T> t = (IsBetweenWhenPresent<T>) EMPTY; + return t; + } + + protected IsBetweenWhenPresent(T value1, T value2) { + super(value1, value2); + } + + @Override + public String operator1() { + return "between"; //$NON-NLS-1$ + } + + @Override + public String operator2() { + return "and"; //$NON-NLS-1$ + } + + @Override + public IsBetweenWhenPresent<T> filter(BiPredicate<? super T, ? super T> predicate) { + return filterSupport(predicate, IsBetweenWhenPresent::empty, this); + } + + @Override + public IsBetweenWhenPresent<T> filter(Predicate<? super T> predicate) { + return filterSupport(predicate, IsBetweenWhenPresent::empty, this); + } + + @Override + public <R> IsBetweenWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper1, + Function<? super T, ? extends @Nullable R> mapper2) { + return mapSupport(mapper1, mapper2, IsBetweenWhenPresent::of, IsBetweenWhenPresent::empty); + } + + @Override + public <R> IsBetweenWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + return map(mapper, mapper); + } + + public static <T> IsBetweenWhenPresent<T> of(@Nullable T value1, @Nullable T value2) { + if (value1 == null || value2 == null) { + return empty(); + } else { + return new IsBetweenWhenPresent<>(value1, value2); + } + } + + public static <T> Builder<T> isBetweenWhenPresent(@Nullable T value1) { + return new Builder<>(value1); + } + + public static class Builder<T> extends AndWhenPresentGatherer<T, IsBetweenWhenPresent<T>> { + private Builder(@Nullable T value1) { + super(value1); + } + + @Override + protected IsBetweenWhenPresent<T> build(@Nullable T value2) { + return IsBetweenWhenPresent.of(value1, value2); + } + } +} diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToWhenPresent.java new file mode 100644 index 000000000..f06489076 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToWhenPresent.java @@ -0,0 +1,72 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.where.condition; + +import java.util.NoSuchElementException; +import java.util.function.Function; +import java.util.function.Predicate; + +import org.jspecify.annotations.Nullable; +import org.mybatis.dynamic.sql.AbstractSingleValueCondition; + +public class IsEqualToWhenPresent<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { + + private static final IsEqualToWhenPresent<?> EMPTY = new IsEqualToWhenPresent<Object>(-1) { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public boolean isEmpty() { + return true; + } + }; + + public static <T> IsEqualToWhenPresent<T> empty() { + @SuppressWarnings("unchecked") + IsEqualToWhenPresent<T> t = (IsEqualToWhenPresent<T>) EMPTY; + return t; + } + + protected IsEqualToWhenPresent(T value) { + super(value); + } + + @Override + public String operator() { + return "="; //$NON-NLS-1$ + } + + public static <T> IsEqualToWhenPresent<T> of(@Nullable T value) { + if (value == null) { + return empty(); + } else { + return new IsEqualToWhenPresent<>(value); + } + } + + @Override + public IsEqualToWhenPresent<T> filter(Predicate<? super T> predicate) { + return filterSupport(predicate, IsEqualToWhenPresent::empty, this); + } + + @Override + public <R> IsEqualToWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + return mapSupport(mapper, IsEqualToWhenPresent::of, IsEqualToWhenPresent::empty); + } +} diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWhenPresent.java new file mode 100644 index 000000000..89e8cda4f --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWhenPresent.java @@ -0,0 +1,71 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.where.condition; + +import java.util.NoSuchElementException; +import java.util.function.Function; +import java.util.function.Predicate; + +import org.jspecify.annotations.Nullable; +import org.mybatis.dynamic.sql.AbstractSingleValueCondition; + +public class IsGreaterThanOrEqualToWhenPresent<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { + private static final IsGreaterThanOrEqualToWhenPresent<?> EMPTY = new IsGreaterThanOrEqualToWhenPresent<Object>(-1) { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public boolean isEmpty() { + return true; + } + }; + + public static <T> IsGreaterThanOrEqualToWhenPresent<T> empty() { + @SuppressWarnings("unchecked") + IsGreaterThanOrEqualToWhenPresent<T> t = (IsGreaterThanOrEqualToWhenPresent<T>) EMPTY; + return t; + } + + protected IsGreaterThanOrEqualToWhenPresent(T value) { + super(value); + } + + @Override + public String operator() { + return ">="; //$NON-NLS-1$ + } + + public static <T> IsGreaterThanOrEqualToWhenPresent<T> of(@Nullable T value) { + if (value == null) { + return empty(); + } else { + return new IsGreaterThanOrEqualToWhenPresent<>(value); + } + } + + @Override + public IsGreaterThanOrEqualToWhenPresent<T> filter(Predicate<? super T> predicate) { + return filterSupport(predicate, IsGreaterThanOrEqualToWhenPresent::empty, this); + } + + @Override + public <R> IsGreaterThanOrEqualToWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + return mapSupport(mapper, IsGreaterThanOrEqualToWhenPresent::of, IsGreaterThanOrEqualToWhenPresent::empty); + } +} diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanWhenPresent.java new file mode 100644 index 000000000..175b5fcf6 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanWhenPresent.java @@ -0,0 +1,71 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.where.condition; + +import java.util.NoSuchElementException; +import java.util.function.Function; +import java.util.function.Predicate; + +import org.jspecify.annotations.Nullable; +import org.mybatis.dynamic.sql.AbstractSingleValueCondition; + +public class IsGreaterThanWhenPresent<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { + private static final IsGreaterThanWhenPresent<?> EMPTY = new IsGreaterThanWhenPresent<Object>(-1) { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public boolean isEmpty() { + return true; + } + }; + + public static <T> IsGreaterThanWhenPresent<T> empty() { + @SuppressWarnings("unchecked") + IsGreaterThanWhenPresent<T> t = (IsGreaterThanWhenPresent<T>) EMPTY; + return t; + } + + protected IsGreaterThanWhenPresent(T value) { + super(value); + } + + @Override + public String operator() { + return ">"; //$NON-NLS-1$ + } + + public static <T> IsGreaterThanWhenPresent<T> of(@Nullable T value) { + if (value == null) { + return empty(); + } else { + return new IsGreaterThanWhenPresent<>(value); + } + } + + @Override + public IsGreaterThanWhenPresent<T> filter(Predicate<? super T> predicate) { + return filterSupport(predicate, IsGreaterThanWhenPresent::empty, this); + } + + @Override + public <R> IsGreaterThanWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + return mapSupport(mapper, IsGreaterThanWhenPresent::of, IsGreaterThanWhenPresent::empty); + } +} diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java index bc8bfbdf9..3e2a22d2a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java @@ -62,11 +62,12 @@ public <R> IsInCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { return mapSupport(mapper, IsInCaseInsensitive::new, IsInCaseInsensitive::empty); } - public static IsInCaseInsensitive<String> of(String... values) { + @SafeVarargs + public static <T> IsInCaseInsensitive<T> of(T... values) { return of(Arrays.asList(values)); } - public static IsInCaseInsensitive<String> of(Collection<String> values) { + public static <T> IsInCaseInsensitive<T> of(Collection<T> values) { return new IsInCaseInsensitive<>(values); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java index fee942f7d..ac3ce2787 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java @@ -54,15 +54,20 @@ public IsInCaseInsensitiveWhenPresent<T> filter(Predicate<? super T> predicate) } @Override - public <R> IsInCaseInsensitiveWhenPresent<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsInCaseInsensitiveWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { return mapSupport(mapper, IsInCaseInsensitiveWhenPresent::new, IsInCaseInsensitiveWhenPresent::empty); } - public static IsInCaseInsensitiveWhenPresent<String> of(@Nullable String... values) { + @SafeVarargs + public static <T> IsInCaseInsensitiveWhenPresent<T> of(@Nullable T... values) { return of(Arrays.asList(values)); } - public static IsInCaseInsensitiveWhenPresent<String> of(Collection<@Nullable String> values) { - return new IsInCaseInsensitiveWhenPresent<>(values); + public static <T> IsInCaseInsensitiveWhenPresent<T> of(@Nullable Collection<@Nullable T> values) { + if (values == null || values.isEmpty()) { + return empty(); + } else { + return new IsInCaseInsensitiveWhenPresent<>(values); + } } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java index 5c431fea3..1ec8185ee 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java @@ -50,8 +50,8 @@ public IsInWhenPresent<T> filter(Predicate<? super T> predicate) { } @Override - public <R> IsInWhenPresent<R> map(Function<? super T, ? extends R> mapper) { - return mapSupport(mapper, IsInWhenPresent::new, IsInWhenPresent::empty); + public <R> IsInWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + return mapSupport(mapper, IsInWhenPresent::of, IsInWhenPresent::empty); } @SafeVarargs @@ -59,7 +59,11 @@ public static <T> IsInWhenPresent<T> of(@Nullable T... values) { return of(Arrays.asList(values)); } - public static <T> IsInWhenPresent<T> of(Collection<@Nullable T> values) { - return new IsInWhenPresent<>(values); + public static <T> IsInWhenPresent<T> of(@Nullable Collection<@Nullable T> values) { + if (values == null || values.isEmpty()) { + return empty(); + } else { + return new IsInWhenPresent<>(values); + } } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToWhenPresent.java new file mode 100644 index 000000000..3cdc8ff39 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToWhenPresent.java @@ -0,0 +1,71 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.where.condition; + +import java.util.NoSuchElementException; +import java.util.function.Function; +import java.util.function.Predicate; + +import org.jspecify.annotations.Nullable; +import org.mybatis.dynamic.sql.AbstractSingleValueCondition; + +public class IsLessThanOrEqualToWhenPresent<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { + private static final IsLessThanOrEqualToWhenPresent<?> EMPTY = new IsLessThanOrEqualToWhenPresent<Object>(-1) { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public boolean isEmpty() { + return true; + } + }; + + public static <T> IsLessThanOrEqualToWhenPresent<T> empty() { + @SuppressWarnings("unchecked") + IsLessThanOrEqualToWhenPresent<T> t = (IsLessThanOrEqualToWhenPresent<T>) EMPTY; + return t; + } + + protected IsLessThanOrEqualToWhenPresent(T value) { + super(value); + } + + @Override + public String operator() { + return "<="; //$NON-NLS-1$ + } + + public static <T> IsLessThanOrEqualToWhenPresent<T> of(@Nullable T value) { + if (value == null) { + return empty(); + } else { + return new IsLessThanOrEqualToWhenPresent<>(value); + } + } + + @Override + public IsLessThanOrEqualToWhenPresent<T> filter(Predicate<? super T> predicate) { + return filterSupport(predicate, IsLessThanOrEqualToWhenPresent::empty, this); + } + + @Override + public <R> IsLessThanOrEqualToWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + return mapSupport(mapper, IsLessThanOrEqualToWhenPresent::of, IsLessThanOrEqualToWhenPresent::empty); + } +} diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanWhenPresent.java new file mode 100644 index 000000000..78a07f9a2 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanWhenPresent.java @@ -0,0 +1,72 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.where.condition; + +import java.util.NoSuchElementException; +import java.util.function.Function; +import java.util.function.Predicate; + +import org.jspecify.annotations.Nullable; +import org.mybatis.dynamic.sql.AbstractSingleValueCondition; + +public class IsLessThanWhenPresent<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { + + private static final IsLessThanWhenPresent<?> EMPTY = new IsLessThanWhenPresent<Object>(-1) { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public boolean isEmpty() { + return true; + } + }; + + public static <T> IsLessThanWhenPresent<T> empty() { + @SuppressWarnings("unchecked") + IsLessThanWhenPresent<T> t = (IsLessThanWhenPresent<T>) EMPTY; + return t; + } + + protected IsLessThanWhenPresent(T value) { + super(value); + } + + @Override + public String operator() { + return "<"; //$NON-NLS-1$ + } + + public static <T> IsLessThanWhenPresent<T> of(@Nullable T value) { + if (value == null) { + return empty(); + } else { + return new IsLessThanWhenPresent<>(value); + } + } + + @Override + public IsLessThanWhenPresent<T> filter(Predicate<? super T> predicate) { + return filterSupport(predicate, IsLessThanWhenPresent::empty, this); + } + + @Override + public <R> IsLessThanWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + return mapSupport(mapper, IsLessThanWhenPresent::of, IsLessThanWhenPresent::empty); + } +} diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java index e4d31c126..ffdc2bc7d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java @@ -62,7 +62,7 @@ public <R> IsLikeCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) return mapSupport(mapper, IsLikeCaseInsensitive::new, IsLikeCaseInsensitive::empty); } - public static IsLikeCaseInsensitive<String> of(String value) { + public static <T> IsLikeCaseInsensitive<T> of(T value) { return new IsLikeCaseInsensitive<>(value); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitiveWhenPresent.java new file mode 100644 index 000000000..89ab9b038 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitiveWhenPresent.java @@ -0,0 +1,73 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.where.condition; + +import java.util.NoSuchElementException; +import java.util.function.Function; +import java.util.function.Predicate; + +import org.jspecify.annotations.Nullable; +import org.mybatis.dynamic.sql.AbstractSingleValueCondition; +import org.mybatis.dynamic.sql.util.StringUtilities; + +public class IsLikeCaseInsensitiveWhenPresent<T> extends AbstractSingleValueCondition<T> + implements CaseInsensitiveRenderableCondition<T>, AbstractSingleValueCondition.Filterable<T>, + AbstractSingleValueCondition.Mappable<T> { + private static final IsLikeCaseInsensitiveWhenPresent<?> EMPTY = new IsLikeCaseInsensitiveWhenPresent<>("") { //$NON-NLS-1$ + @Override + public String value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public boolean isEmpty() { + return true; + } + }; + + public static <T> IsLikeCaseInsensitiveWhenPresent<T> empty() { + @SuppressWarnings("unchecked") + IsLikeCaseInsensitiveWhenPresent<T> t = (IsLikeCaseInsensitiveWhenPresent<T>) EMPTY; + return t; + } + + protected IsLikeCaseInsensitiveWhenPresent(T value) { + super(StringUtilities.upperCaseIfPossible(value)); + } + + @Override + public String operator() { + return "like"; //$NON-NLS-1$ + } + + @Override + public IsLikeCaseInsensitiveWhenPresent<T> filter(Predicate<? super T> predicate) { + return filterSupport(predicate, IsLikeCaseInsensitiveWhenPresent::empty, this); + } + + @Override + public <R> IsLikeCaseInsensitiveWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + return mapSupport(mapper, IsLikeCaseInsensitiveWhenPresent::of, IsLikeCaseInsensitiveWhenPresent::empty); + } + + public static <T> IsLikeCaseInsensitiveWhenPresent<T> of(@Nullable T value) { + if (value == null) { + return empty(); + } else { + return new IsLikeCaseInsensitiveWhenPresent<>(value); + } + } +} diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeWhenPresent.java new file mode 100644 index 000000000..a69e55356 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeWhenPresent.java @@ -0,0 +1,72 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.where.condition; + +import java.util.NoSuchElementException; +import java.util.function.Function; +import java.util.function.Predicate; + +import org.jspecify.annotations.Nullable; +import org.mybatis.dynamic.sql.AbstractSingleValueCondition; + +public class IsLikeWhenPresent<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { + + private static final IsLikeWhenPresent<?> EMPTY = new IsLikeWhenPresent<Object>(-1) { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public boolean isEmpty() { + return true; + } + }; + + public static <T> IsLikeWhenPresent<T> empty() { + @SuppressWarnings("unchecked") + IsLikeWhenPresent<T> t = (IsLikeWhenPresent<T>) EMPTY; + return t; + } + + protected IsLikeWhenPresent(T value) { + super(value); + } + + @Override + public String operator() { + return "like"; //$NON-NLS-1$ + } + + public static <T> IsLikeWhenPresent<T> of(@Nullable T value) { + if (value == null) { + return empty(); + } else { + return new IsLikeWhenPresent<>(value); + } + } + + @Override + public IsLikeWhenPresent<T> filter(Predicate<? super T> predicate) { + return filterSupport(predicate, IsLikeWhenPresent::empty, this); + } + + @Override + public <R> IsLikeWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + return mapSupport(mapper, IsLikeWhenPresent::of, IsLikeWhenPresent::empty); + } +} diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java index 6a515d4ac..836e3c741 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java @@ -20,7 +20,6 @@ import java.util.function.Function; import java.util.function.Predicate; -import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractTwoValueCondition; public class IsNotBetween<T> extends AbstractTwoValueCondition<T> @@ -87,10 +86,6 @@ public static <T> Builder<T> isNotBetween(T value1) { return new Builder<>(value1); } - public static <T> WhenPresentBuilder<T> isNotBetweenWhenPresent(@Nullable T value1) { - return new WhenPresentBuilder<>(value1); - } - public static class Builder<T> extends AndGatherer<T, IsNotBetween<T>> { private Builder(T value1) { @@ -102,20 +97,4 @@ protected IsNotBetween<T> build(T value2) { return new IsNotBetween<>(value1, value2); } } - - public static class WhenPresentBuilder<T> extends AndWhenPresentGatherer<T, IsNotBetween<T>> { - - private WhenPresentBuilder(@Nullable T value1) { - super(value1); - } - - @Override - protected IsNotBetween<T> build(@Nullable T value2) { - if (value1 == null || value2 == null) { - return empty(); - } else { - return new IsNotBetween<>(value1, value2); - } - } - } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetweenWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetweenWhenPresent.java new file mode 100644 index 000000000..23b6507d5 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetweenWhenPresent.java @@ -0,0 +1,109 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.where.condition; + +import java.util.NoSuchElementException; +import java.util.function.BiPredicate; +import java.util.function.Function; +import java.util.function.Predicate; + +import org.jspecify.annotations.Nullable; +import org.mybatis.dynamic.sql.AbstractTwoValueCondition; + +public class IsNotBetweenWhenPresent<T> extends AbstractTwoValueCondition<T> + implements AbstractTwoValueCondition.Filterable<T>, AbstractTwoValueCondition.Mappable<T> { + private static final IsNotBetweenWhenPresent<?> EMPTY = new IsNotBetweenWhenPresent<Object>(-1, -1) { + @Override + public Object value1() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public Object value2() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public boolean isEmpty() { + return true; + } + }; + + public static <T> IsNotBetweenWhenPresent<T> empty() { + @SuppressWarnings("unchecked") + IsNotBetweenWhenPresent<T> t = (IsNotBetweenWhenPresent<T>) EMPTY; + return t; + } + + protected IsNotBetweenWhenPresent(T value1, T value2) { + super(value1, value2); + } + + @Override + public String operator1() { + return "not between"; //$NON-NLS-1$ + } + + @Override + public String operator2() { + return "and"; //$NON-NLS-1$ + } + + @Override + public IsNotBetweenWhenPresent<T> filter(BiPredicate<? super T, ? super T> predicate) { + return filterSupport(predicate, IsNotBetweenWhenPresent::empty, this); + } + + @Override + public IsNotBetweenWhenPresent<T> filter(Predicate<? super T> predicate) { + return filterSupport(predicate, IsNotBetweenWhenPresent::empty, this); + } + + @Override + public <R> IsNotBetweenWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper1, + Function<? super T, ? extends @Nullable R> mapper2) { + return mapSupport(mapper1, mapper2, IsNotBetweenWhenPresent::of, IsNotBetweenWhenPresent::empty); + } + + @Override + public <R> IsNotBetweenWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + return map(mapper, mapper); + } + + public static <T> IsNotBetweenWhenPresent<T> of(@Nullable T value1, @Nullable T value2) { + if (value1 == null || value2 == null) { + return empty(); + } else { + return new IsNotBetweenWhenPresent<>(value1, value2); + } + } + + public static <T> Builder<T> isNotBetweenWhenPresent(@Nullable T value1) { + return new Builder<>(value1); + } + + public static class Builder<T> extends AndWhenPresentGatherer<T, IsNotBetweenWhenPresent<T>> { + + private Builder(@Nullable T value1) { + super(value1); + } + + @Override + protected IsNotBetweenWhenPresent<T> build(@Nullable T value2) { + return IsNotBetweenWhenPresent.of(value1, value2); + } + } +} diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToWhenPresent.java new file mode 100644 index 000000000..07ab3f6cf --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToWhenPresent.java @@ -0,0 +1,71 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.where.condition; + +import java.util.NoSuchElementException; +import java.util.function.Function; +import java.util.function.Predicate; + +import org.jspecify.annotations.Nullable; +import org.mybatis.dynamic.sql.AbstractSingleValueCondition; + +public class IsNotEqualToWhenPresent<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { + private static final IsNotEqualToWhenPresent<?> EMPTY = new IsNotEqualToWhenPresent<Object>(-1) { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public boolean isEmpty() { + return true; + } + }; + + public static <T> IsNotEqualToWhenPresent<T> empty() { + @SuppressWarnings("unchecked") + IsNotEqualToWhenPresent<T> t = (IsNotEqualToWhenPresent<T>) EMPTY; + return t; + } + + protected IsNotEqualToWhenPresent(T value) { + super(value); + } + + @Override + public String operator() { + return "<>"; //$NON-NLS-1$ + } + + public static <T> IsNotEqualToWhenPresent<T> of(@Nullable T value) { + if (value == null) { + return empty(); + } else { + return new IsNotEqualToWhenPresent<>(value); + } + } + + @Override + public IsNotEqualToWhenPresent<T> filter(Predicate<? super T> predicate) { + return filterSupport(predicate, IsNotEqualToWhenPresent::empty, this); + } + + @Override + public <R> IsNotEqualToWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + return mapSupport(mapper, IsNotEqualToWhenPresent::of, IsNotEqualToWhenPresent::empty); + } +} diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java index 4486d1df7..2bc802ab8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java @@ -62,11 +62,12 @@ public <R> IsNotInCaseInsensitive<R> map(Function<? super T, ? extends R> mapper return mapSupport(mapper, IsNotInCaseInsensitive::new, IsNotInCaseInsensitive::empty); } - public static IsNotInCaseInsensitive<String> of(String... values) { + @SafeVarargs + public static <T> IsNotInCaseInsensitive<T> of(T... values) { return of(Arrays.asList(values)); } - public static IsNotInCaseInsensitive<String> of(Collection<String> values) { + public static <T> IsNotInCaseInsensitive<T> of(Collection<T> values) { return new IsNotInCaseInsensitive<>(values); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java index 992a231eb..82d9d6e27 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java @@ -54,15 +54,20 @@ public IsNotInCaseInsensitiveWhenPresent<T> filter(Predicate<? super T> predicat } @Override - public <R> IsNotInCaseInsensitiveWhenPresent<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsNotInCaseInsensitiveWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { return mapSupport(mapper, IsNotInCaseInsensitiveWhenPresent::new, IsNotInCaseInsensitiveWhenPresent::empty); } - public static IsNotInCaseInsensitiveWhenPresent<String> of(@Nullable String... values) { + @SafeVarargs + public static <T> IsNotInCaseInsensitiveWhenPresent<T> of(@Nullable T... values) { return of(Arrays.asList(values)); } - public static IsNotInCaseInsensitiveWhenPresent<String> of(Collection<@Nullable String> values) { - return new IsNotInCaseInsensitiveWhenPresent<>(values); + public static <T> IsNotInCaseInsensitiveWhenPresent<T> of(@Nullable Collection<@Nullable T> values) { + if (values == null || values.isEmpty()) { + return empty(); + } else { + return new IsNotInCaseInsensitiveWhenPresent<>(values); + } } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java index ddc8e5470..ed4b27389 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java @@ -22,6 +22,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; public class IsNotInWhenPresent<T> extends AbstractListValueCondition<T> @@ -49,16 +50,20 @@ public IsNotInWhenPresent<T> filter(Predicate<? super T> predicate) { } @Override - public <R> IsNotInWhenPresent<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsNotInWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { return mapSupport(mapper, IsNotInWhenPresent::new, IsNotInWhenPresent::empty); } @SafeVarargs - public static <T> IsNotInWhenPresent<T> of(T... values) { + public static <T> IsNotInWhenPresent<T> of(@Nullable T... values) { return of(Arrays.asList(values)); } - public static <T> IsNotInWhenPresent<T> of(Collection<T> values) { - return new IsNotInWhenPresent<>(values); + public static <T> IsNotInWhenPresent<T> of(@Nullable Collection<@Nullable T> values) { + if (values == null || values.isEmpty()) { + return empty(); + } else { + return new IsNotInWhenPresent<>(values); + } } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java index 715a19a8d..6bd943227 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java @@ -62,7 +62,7 @@ public <R> IsNotLikeCaseInsensitive<R> map(Function<? super T, ? extends R> mapp return mapSupport(mapper, IsNotLikeCaseInsensitive::new, IsNotLikeCaseInsensitive::empty); } - public static IsNotLikeCaseInsensitive<String> of(String value) { + public static <T> IsNotLikeCaseInsensitive<T> of(T value) { return new IsNotLikeCaseInsensitive<>(value); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitiveWhenPresent.java new file mode 100644 index 000000000..891525295 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitiveWhenPresent.java @@ -0,0 +1,73 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.where.condition; + +import java.util.NoSuchElementException; +import java.util.function.Function; +import java.util.function.Predicate; + +import org.jspecify.annotations.Nullable; +import org.mybatis.dynamic.sql.AbstractSingleValueCondition; +import org.mybatis.dynamic.sql.util.StringUtilities; + +public class IsNotLikeCaseInsensitiveWhenPresent<T> extends AbstractSingleValueCondition<T> + implements CaseInsensitiveRenderableCondition<T>, AbstractSingleValueCondition.Filterable<T>, + AbstractSingleValueCondition.Mappable<T> { + private static final IsNotLikeCaseInsensitiveWhenPresent<?> EMPTY = new IsNotLikeCaseInsensitiveWhenPresent<>("") { //$NON-NLS-1$ + @Override + public String value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public boolean isEmpty() { + return true; + } + }; + + public static <T> IsNotLikeCaseInsensitiveWhenPresent<T> empty() { + @SuppressWarnings("unchecked") + IsNotLikeCaseInsensitiveWhenPresent<T> t = (IsNotLikeCaseInsensitiveWhenPresent<T>) EMPTY; + return t; + } + + protected IsNotLikeCaseInsensitiveWhenPresent(T value) { + super(StringUtilities.upperCaseIfPossible(value)); + } + + @Override + public String operator() { + return "not like"; //$NON-NLS-1$ + } + + @Override + public IsNotLikeCaseInsensitiveWhenPresent<T> filter(Predicate<? super T> predicate) { + return filterSupport(predicate, IsNotLikeCaseInsensitiveWhenPresent::empty, this); + } + + @Override + public <R> IsNotLikeCaseInsensitiveWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + return mapSupport(mapper, IsNotLikeCaseInsensitiveWhenPresent::of, IsNotLikeCaseInsensitiveWhenPresent::empty); + } + + public static <T> IsNotLikeCaseInsensitiveWhenPresent<T> of(@Nullable T value) { + if (value == null) { + return empty(); + } else { + return new IsNotLikeCaseInsensitiveWhenPresent<>(value); + } + } +} diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeWhenPresent.java new file mode 100644 index 000000000..d018c9062 --- /dev/null +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeWhenPresent.java @@ -0,0 +1,71 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.where.condition; + +import java.util.NoSuchElementException; +import java.util.function.Function; +import java.util.function.Predicate; + +import org.jspecify.annotations.Nullable; +import org.mybatis.dynamic.sql.AbstractSingleValueCondition; + +public class IsNotLikeWhenPresent<T> extends AbstractSingleValueCondition<T> + implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { + private static final IsNotLikeWhenPresent<?> EMPTY = new IsNotLikeWhenPresent<Object>(-1) { + @Override + public Object value() { + throw new NoSuchElementException("No value present"); //$NON-NLS-1$ + } + + @Override + public boolean isEmpty() { + return true; + } + }; + + public static <T> IsNotLikeWhenPresent<T> empty() { + @SuppressWarnings("unchecked") + IsNotLikeWhenPresent<T> t = (IsNotLikeWhenPresent<T>) EMPTY; + return t; + } + + protected IsNotLikeWhenPresent(T value) { + super(value); + } + + @Override + public String operator() { + return "not like"; //$NON-NLS-1$ + } + + public static <T> IsNotLikeWhenPresent<T> of(@Nullable T value) { + if (value == null) { + return empty(); + } else { + return new IsNotLikeWhenPresent<>(value); + } + } + + @Override + public IsNotLikeWhenPresent<T> filter(Predicate<? super T> predicate) { + return filterSupport(predicate, IsNotLikeWhenPresent::empty, this); + } + + @Override + public <R> IsNotLikeWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + return mapSupport(mapper, IsNotLikeWhenPresent::of, IsNotLikeWhenPresent::empty); + } +} diff --git a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt index 530c962ed..f648496d0 100644 --- a/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt +++ b/src/main/kotlin/org/mybatis/dynamic/sql/util/kotlin/elements/SqlElements.kt @@ -51,14 +51,18 @@ import org.mybatis.dynamic.sql.util.kotlin.GroupingCriteriaReceiver import org.mybatis.dynamic.sql.util.kotlin.KotlinSubQueryBuilder import org.mybatis.dynamic.sql.util.kotlin.invalidIfNull import org.mybatis.dynamic.sql.where.condition.IsBetween +import org.mybatis.dynamic.sql.where.condition.IsBetweenWhenPresent import org.mybatis.dynamic.sql.where.condition.IsEqualTo import org.mybatis.dynamic.sql.where.condition.IsEqualToColumn +import org.mybatis.dynamic.sql.where.condition.IsEqualToWhenPresent import org.mybatis.dynamic.sql.where.condition.IsEqualToWithSubselect import org.mybatis.dynamic.sql.where.condition.IsGreaterThan import org.mybatis.dynamic.sql.where.condition.IsGreaterThanColumn import org.mybatis.dynamic.sql.where.condition.IsGreaterThanOrEqualTo import org.mybatis.dynamic.sql.where.condition.IsGreaterThanOrEqualToColumn +import org.mybatis.dynamic.sql.where.condition.IsGreaterThanOrEqualToWhenPresent import org.mybatis.dynamic.sql.where.condition.IsGreaterThanOrEqualToWithSubselect +import org.mybatis.dynamic.sql.where.condition.IsGreaterThanWhenPresent import org.mybatis.dynamic.sql.where.condition.IsGreaterThanWithSubselect import org.mybatis.dynamic.sql.where.condition.IsIn import org.mybatis.dynamic.sql.where.condition.IsInCaseInsensitive @@ -69,13 +73,19 @@ import org.mybatis.dynamic.sql.where.condition.IsLessThan import org.mybatis.dynamic.sql.where.condition.IsLessThanColumn import org.mybatis.dynamic.sql.where.condition.IsLessThanOrEqualTo import org.mybatis.dynamic.sql.where.condition.IsLessThanOrEqualToColumn +import org.mybatis.dynamic.sql.where.condition.IsLessThanOrEqualToWhenPresent import org.mybatis.dynamic.sql.where.condition.IsLessThanOrEqualToWithSubselect +import org.mybatis.dynamic.sql.where.condition.IsLessThanWhenPresent import org.mybatis.dynamic.sql.where.condition.IsLessThanWithSubselect import org.mybatis.dynamic.sql.where.condition.IsLike import org.mybatis.dynamic.sql.where.condition.IsLikeCaseInsensitive +import org.mybatis.dynamic.sql.where.condition.IsLikeCaseInsensitiveWhenPresent +import org.mybatis.dynamic.sql.where.condition.IsLikeWhenPresent import org.mybatis.dynamic.sql.where.condition.IsNotBetween +import org.mybatis.dynamic.sql.where.condition.IsNotBetweenWhenPresent import org.mybatis.dynamic.sql.where.condition.IsNotEqualTo import org.mybatis.dynamic.sql.where.condition.IsNotEqualToColumn +import org.mybatis.dynamic.sql.where.condition.IsNotEqualToWhenPresent import org.mybatis.dynamic.sql.where.condition.IsNotEqualToWithSubselect import org.mybatis.dynamic.sql.where.condition.IsNotIn import org.mybatis.dynamic.sql.where.condition.IsNotInCaseInsensitive @@ -84,6 +94,8 @@ import org.mybatis.dynamic.sql.where.condition.IsNotInWhenPresent import org.mybatis.dynamic.sql.where.condition.IsNotInWithSubselect import org.mybatis.dynamic.sql.where.condition.IsNotLike import org.mybatis.dynamic.sql.where.condition.IsNotLikeCaseInsensitive +import org.mybatis.dynamic.sql.where.condition.IsNotLikeCaseInsensitiveWhenPresent +import org.mybatis.dynamic.sql.where.condition.IsNotLikeWhenPresent import org.mybatis.dynamic.sql.where.condition.IsNotNull import org.mybatis.dynamic.sql.where.condition.IsNull @@ -216,7 +228,7 @@ fun <T : Any> isEqualTo(subQuery: KotlinSubQueryBuilder.() -> Unit): IsEqualToWi fun <T : Any> isEqualTo(column: BasicColumn): IsEqualToColumn<T> = SqlBuilder.isEqualTo(column) -fun <T : Any> isEqualToWhenPresent(value: T?): IsEqualTo<T> = SqlBuilder.isEqualToWhenPresent(value) +fun <T : Any> isEqualToWhenPresent(value: T?): IsEqualToWhenPresent<T> = SqlBuilder.isEqualToWhenPresent(value) fun <T : Any> isNotEqualTo(value: T): IsNotEqualTo<T> = SqlBuilder.isNotEqualTo(value) @@ -225,7 +237,8 @@ fun <T : Any> isNotEqualTo(subQuery: KotlinSubQueryBuilder.() -> Unit): IsNotEqu fun <T : Any> isNotEqualTo(column: BasicColumn): IsNotEqualToColumn<T> = SqlBuilder.isNotEqualTo(column) -fun <T : Any> isNotEqualToWhenPresent(value: T?): IsNotEqualTo<T> = SqlBuilder.isNotEqualToWhenPresent(value) +fun <T : Any> isNotEqualToWhenPresent(value: T?): IsNotEqualToWhenPresent<T> = + SqlBuilder.isNotEqualToWhenPresent(value) fun <T : Any> isGreaterThan(value: T): IsGreaterThan<T> = SqlBuilder.isGreaterThan(value) @@ -234,7 +247,8 @@ fun <T : Any> isGreaterThan(subQuery: KotlinSubQueryBuilder.() -> Unit): IsGreat fun <T : Any> isGreaterThan(column: BasicColumn): IsGreaterThanColumn<T> = SqlBuilder.isGreaterThan(column) -fun <T : Any> isGreaterThanWhenPresent(value: T?): IsGreaterThan<T> = SqlBuilder.isGreaterThanWhenPresent(value) +fun <T : Any> isGreaterThanWhenPresent(value: T?): IsGreaterThanWhenPresent<T> = + SqlBuilder.isGreaterThanWhenPresent(value) fun <T : Any> isGreaterThanOrEqualTo(value: T): IsGreaterThanOrEqualTo<T> = SqlBuilder.isGreaterThanOrEqualTo(value) @@ -244,7 +258,7 @@ fun <T : Any> isGreaterThanOrEqualTo(subQuery: KotlinSubQueryBuilder.() -> Unit) fun <T : Any> isGreaterThanOrEqualTo(column: BasicColumn): IsGreaterThanOrEqualToColumn<T> = SqlBuilder.isGreaterThanOrEqualTo(column) -fun <T : Any> isGreaterThanOrEqualToWhenPresent(value: T?): IsGreaterThanOrEqualTo<T> = +fun <T : Any> isGreaterThanOrEqualToWhenPresent(value: T?): IsGreaterThanOrEqualToWhenPresent<T> = SqlBuilder.isGreaterThanOrEqualToWhenPresent(value) fun <T : Any> isLessThan(value: T): IsLessThan<T> = SqlBuilder.isLessThan(value) @@ -254,7 +268,7 @@ fun <T : Any> isLessThan(subQuery: KotlinSubQueryBuilder.() -> Unit): IsLessThan fun <T : Any> isLessThan(column: BasicColumn): IsLessThanColumn<T> = SqlBuilder.isLessThan(column) -fun <T : Any> isLessThanWhenPresent(value: T?): IsLessThan<T> = SqlBuilder.isLessThanWhenPresent(value) +fun <T : Any> isLessThanWhenPresent(value: T?): IsLessThanWhenPresent<T> = SqlBuilder.isLessThanWhenPresent(value) fun <T : Any> isLessThanOrEqualTo(value: T): IsLessThanOrEqualTo<T> = SqlBuilder.isLessThanOrEqualTo(value) @@ -263,7 +277,7 @@ fun <T : Any> isLessThanOrEqualTo(subQuery: KotlinSubQueryBuilder.() -> Unit): I fun <T : Any> isLessThanOrEqualTo(column: BasicColumn): IsLessThanOrEqualToColumn<T> = SqlBuilder.isLessThanOrEqualTo(column) -fun <T : Any> isLessThanOrEqualToWhenPresent(value: T?): IsLessThanOrEqualTo<T> = +fun <T : Any> isLessThanOrEqualToWhenPresent(value: T?): IsLessThanOrEqualToWhenPresent<T> = SqlBuilder.isLessThanOrEqualToWhenPresent(value) fun <T : Any> isIn(vararg values: T): IsIn<T> = isIn(values.asList()) @@ -312,11 +326,11 @@ fun <T : Any> isNotBetweenWhenPresent(value1: T?): NotBetweenWhenPresentBuilder< // for string columns, but generic for columns with type handlers fun <T : Any> isLike(value: T): IsLike<T> = SqlBuilder.isLike(value) -fun <T : Any> isLikeWhenPresent(value: T?): IsLike<T> = SqlBuilder.isLikeWhenPresent(value) +fun <T : Any> isLikeWhenPresent(value: T?): IsLikeWhenPresent<T> = SqlBuilder.isLikeWhenPresent(value) fun <T : Any> isNotLike(value: T): IsNotLike<T> = SqlBuilder.isNotLike(value) -fun <T : Any> isNotLikeWhenPresent(value: T?): IsNotLike<T> = SqlBuilder.isNotLikeWhenPresent(value) +fun <T : Any> isNotLikeWhenPresent(value: T?): IsNotLikeWhenPresent<T> = SqlBuilder.isNotLikeWhenPresent(value) // shortcuts for booleans fun isTrue(): IsEqualTo<Boolean> = isEqualTo(true) @@ -326,12 +340,12 @@ fun isFalse(): IsEqualTo<Boolean> = isEqualTo(false) // conditions for strings only fun isLikeCaseInsensitive(value: String): IsLikeCaseInsensitive<String> = SqlBuilder.isLikeCaseInsensitive(value) -fun isLikeCaseInsensitiveWhenPresent(value: String?): IsLikeCaseInsensitive<String> = +fun isLikeCaseInsensitiveWhenPresent(value: String?): IsLikeCaseInsensitiveWhenPresent<String> = SqlBuilder.isLikeCaseInsensitiveWhenPresent(value) fun isNotLikeCaseInsensitive(value: String): IsNotLikeCaseInsensitive<String> = SqlBuilder.isNotLikeCaseInsensitive(value) -fun isNotLikeCaseInsensitiveWhenPresent(value: String?): IsNotLikeCaseInsensitive<String> = +fun isNotLikeCaseInsensitiveWhenPresent(value: String?): IsNotLikeCaseInsensitiveWhenPresent<String> = SqlBuilder.isNotLikeCaseInsensitiveWhenPresent(value) fun isInCaseInsensitive(vararg values: String): IsInCaseInsensitive<String> = isInCaseInsensitive(values.asList()) @@ -400,7 +414,7 @@ class BetweenBuilder<T : Any>(private val value1: T) { } class BetweenWhenPresentBuilder<T : Any>(private val value1: T?) { - fun and(value2: T?): IsBetween<T> { + fun and(value2: T?): IsBetweenWhenPresent<T> { return SqlBuilder.isBetweenWhenPresent<T>(value1).and(value2) } } @@ -410,7 +424,7 @@ class NotBetweenBuilder<T : Any>(private val value1: T) { } class NotBetweenWhenPresentBuilder<T : Any>(private val value1: T?) { - fun and(value2: T?): IsNotBetween<T> { + fun and(value2: T?): IsNotBetweenWhenPresent<T> { return SqlBuilder.isNotBetweenWhenPresent<T>(value1).and(value2) } } diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java new file mode 100644 index 000000000..35f0440d8 --- /dev/null +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java @@ -0,0 +1,441 @@ +package org.mybatis.dynamic.sql.where.condition; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import java.util.NoSuchElementException; + +import org.junit.jupiter.api.Test; +import org.mybatis.dynamic.sql.SqlBuilder; + +/** + * This set of tests verifies that the library handles null values in conditions as expected. + * + * <p>In version 2.0, we adopted JSpecify which brought several issues to light. + * In general, the library does not support passing null values into methods unless the method + * is a "whenPresent" method. However, from the beginning the library has handled null values in conditions + * by placing a null into the generated parameter map. We consider this a misuse of the library, but we are + * keeping that behavior for compatibility. + * + * <p>In a future version, we will stop supporting this misuse. + * + * <p>This set of tests should be the only tests in the library that verify this behavior. All other tests + * should use the library properly. + */ +public class NullContractTest { + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsBetween() { + IsBetween<Integer> nullCond = SqlBuilder.isBetween((Integer) null).and((Integer) null); + assertThat(nullCond.isEmpty()).isFalse(); + + IsBetween<Integer> cond = SqlBuilder.isBetween(1).and(10); + IsBetween<Integer> filtered = cond.filter(i -> i >= 1); + IsBetween<Integer> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isFalse(); + + mapped = filtered.map(v1 -> null, v2 -> null); + assertThat(mapped.isEmpty()).isFalse(); + assertThat(mapped.value1()).isNull(); + assertThat(mapped.value2()).isNull(); + } + + @Test + void testIsBetweenWhenPresent() { + IsBetweenWhenPresent<Integer> nullCond = SqlBuilder.isBetweenWhenPresent((Integer) null).and((Integer) null); + assertThat(nullCond.isEmpty()).isTrue(); + + IsBetweenWhenPresent<Integer> cond = SqlBuilder.isBetweenWhenPresent(1).and(10); + IsBetweenWhenPresent<Integer> filtered = cond.filter(i -> i == 1); + IsBetweenWhenPresent<Integer> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isTrue(); + + mapped = filtered.map(v1 -> null, v2 -> null); + assertThat(mapped.isEmpty()).isTrue(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(mapped::value1); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(mapped::value2); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsEqualTo() { + IsEqualTo<Integer> nullCond = SqlBuilder.isEqualTo((Integer) null); // should be an IDE warning + assertThat(nullCond.isEmpty()).isFalse(); + + IsEqualTo<Integer> cond = SqlBuilder.isEqualTo(1); + IsEqualTo<Integer> filtered = cond.filter(i -> i == 1); + IsEqualTo<Integer> mapped = filtered.map(i -> null); // should be an IDE warning + assertThat(mapped.isEmpty()).isFalse(); + assertThat(mapped.value()).isNull(); + } + + @Test + void testIsEqualToWhenPresent() { + IsEqualToWhenPresent<Integer> nullCond = SqlBuilder.isEqualToWhenPresent((Integer) null); + assertThat(nullCond.isEmpty()).isTrue(); + + IsEqualToWhenPresent<Integer> cond = SqlBuilder.isEqualToWhenPresent(1); + IsEqualToWhenPresent<Integer> filtered = cond.filter(i -> i == 1); + IsEqualToWhenPresent<Integer> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isTrue(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(mapped::value); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsGreaterThan() { + IsGreaterThan<Integer> nullCond = SqlBuilder.isGreaterThan((Integer) null); // should be an IDE warning + assertThat(nullCond.isEmpty()).isFalse(); + + IsGreaterThan<Integer> cond = SqlBuilder.isGreaterThan(1); + IsGreaterThan<Integer> filtered = cond.filter(i -> i == 1); + IsGreaterThan<Integer> mapped = filtered.map(i -> null); // should be an IDE warning + assertThat(mapped.isEmpty()).isFalse(); + assertThat(mapped.value()).isNull(); + } + + @Test + void testIsGreaterThanWhenPresent() { + IsGreaterThanWhenPresent<Integer> nullCond = SqlBuilder.isGreaterThanWhenPresent((Integer) null); + assertThat(nullCond.isEmpty()).isTrue(); + + IsGreaterThanWhenPresent<Integer> cond = SqlBuilder.isGreaterThanWhenPresent(1); + IsGreaterThanWhenPresent<Integer> filtered = cond.filter(i -> i == 1); + IsGreaterThanWhenPresent<Integer> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isTrue(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(mapped::value); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsGreaterThanOrEqualTo() { + IsGreaterThanOrEqualTo<Integer> nullCond = SqlBuilder.isGreaterThanOrEqualTo((Integer) null); // should be an IDE warning + assertThat(nullCond.isEmpty()).isFalse(); + + IsGreaterThanOrEqualTo<Integer> cond = SqlBuilder.isGreaterThanOrEqualTo(1); + IsGreaterThanOrEqualTo<Integer> filtered = cond.filter(i -> i == 1); + IsGreaterThanOrEqualTo<Integer> mapped = filtered.map(i -> null); // should be an IDE warning + assertThat(mapped.isEmpty()).isFalse(); + assertThat(mapped.value()).isNull(); + } + + @Test + void testIsGreaterThanOrEqualToWhenPresent() { + IsGreaterThanOrEqualToWhenPresent<Integer> nullCond = SqlBuilder.isGreaterThanOrEqualToWhenPresent((Integer) null); + assertThat(nullCond.isEmpty()).isTrue(); + + IsGreaterThanOrEqualToWhenPresent<Integer> cond = SqlBuilder.isGreaterThanOrEqualToWhenPresent(1); + IsGreaterThanOrEqualToWhenPresent<Integer> filtered = cond.filter(i -> i == 1); + IsGreaterThanOrEqualToWhenPresent<Integer> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isTrue(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(mapped::value); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsLessThan() { + IsLessThan<Integer> nullCond = SqlBuilder.isLessThan((Integer) null); // should be an IDE warning + assertThat(nullCond.isEmpty()).isFalse(); + + IsLessThan<Integer> cond = SqlBuilder.isLessThan(1); + IsLessThan<Integer> filtered = cond.filter(i -> i == 1); + IsLessThan<Integer> mapped = filtered.map(i -> null); // should be an IDE warning + assertThat(mapped.isEmpty()).isFalse(); + assertThat(mapped.value()).isNull(); + } + + @Test + void testIsLessThanWhenPresent() { + IsLessThanWhenPresent<Integer> nullCond = SqlBuilder.isLessThanWhenPresent((Integer) null); + assertThat(nullCond.isEmpty()).isTrue(); + + IsLessThanWhenPresent<Integer> cond = SqlBuilder.isLessThanWhenPresent(1); + IsLessThanWhenPresent<Integer> filtered = cond.filter(i -> i == 1); + IsLessThanWhenPresent<Integer> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isTrue(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(mapped::value); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsLessThanOrEqualTo() { + IsLessThanOrEqualTo<Integer> nullCond = SqlBuilder.isLessThanOrEqualTo((Integer) null); // should be an IDE warning + assertThat(nullCond.isEmpty()).isFalse(); + + IsLessThanOrEqualTo<Integer> cond = SqlBuilder.isLessThanOrEqualTo(1); + IsLessThanOrEqualTo<Integer> filtered = cond.filter(i -> i == 1); + IsLessThanOrEqualTo<Integer> mapped = filtered.map(i -> null); // should be an IDE warning + assertThat(mapped.isEmpty()).isFalse(); + assertThat(mapped.value()).isNull(); + } + + @Test + void testIsLessThanOrEqualToWhenPresent() { + IsLessThanOrEqualToWhenPresent<Integer> nullCond = SqlBuilder.isLessThanOrEqualToWhenPresent((Integer) null); + assertThat(nullCond.isEmpty()).isTrue(); + + IsLessThanOrEqualToWhenPresent<Integer> cond = SqlBuilder.isLessThanOrEqualToWhenPresent(1); + IsLessThanOrEqualToWhenPresent<Integer> filtered = cond.filter(i -> i == 1); + IsLessThanOrEqualToWhenPresent<Integer> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isTrue(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(mapped::value); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsNotBetween() { + IsNotBetween<Integer> nullCond = SqlBuilder.isNotBetween((Integer) null).and((Integer) null); + assertThat(nullCond.isEmpty()).isFalse(); + + IsNotBetween<Integer> cond = SqlBuilder.isNotBetween(1).and(10); + IsNotBetween<Integer> filtered = cond.filter(i -> i >= 1); + IsNotBetween<Integer> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isFalse(); + + mapped = filtered.map(v1 -> null, v2 -> null); + assertThat(mapped.isEmpty()).isFalse(); + assertThat(mapped.value1()).isNull(); + assertThat(mapped.value2()).isNull(); + } + + @Test + void testIsNotBetweenWhenPresent() { + IsNotBetweenWhenPresent<Integer> nullCond = SqlBuilder.isNotBetweenWhenPresent((Integer) null).and((Integer) null); + assertThat(nullCond.isEmpty()).isTrue(); + + IsNotBetweenWhenPresent<Integer> cond = SqlBuilder.isNotBetweenWhenPresent(1).and(10); + IsNotBetweenWhenPresent<Integer> filtered = cond.filter(i -> i == 1); + IsNotBetweenWhenPresent<Integer> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isTrue(); + + mapped = filtered.map(v1 -> null, v2 -> null); + assertThat(mapped.isEmpty()).isTrue(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(mapped::value1); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(mapped::value2); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsNotEqualTo() { + IsNotEqualTo<Integer> nullCond = SqlBuilder.isNotEqualTo((Integer) null); // should be an IDE warning + assertThat(nullCond.isEmpty()).isFalse(); + + IsNotEqualTo<Integer> cond = SqlBuilder.isNotEqualTo(1); + IsNotEqualTo<Integer> filtered = cond.filter(i -> i == 1); + IsNotEqualTo<Integer> mapped = filtered.map(i -> null); // should be an IDE warning + assertThat(mapped.isEmpty()).isFalse(); + assertThat(mapped.value()).isNull(); + } + + @Test + void testIsNotEqualToWhenPresent() { + IsNotEqualToWhenPresent<Integer> nullCond = SqlBuilder.isNotEqualToWhenPresent((Integer) null); + assertThat(nullCond.isEmpty()).isTrue(); + + IsNotEqualToWhenPresent<Integer> cond = SqlBuilder.isNotEqualToWhenPresent(1); + IsNotEqualToWhenPresent<Integer> filtered = cond.filter(i -> i == 1); + IsNotEqualToWhenPresent<Integer> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isTrue(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(mapped::value); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsLike() { + IsLike<String> nullCond = SqlBuilder.isLike((String) null); // should be an IDE warning + assertThat(nullCond.isEmpty()).isFalse(); + + IsLike<String> cond = SqlBuilder.isLike("fred"); + IsLike<String> filtered = cond.filter(i -> i.equals("fred")); + IsLike<String> mapped = filtered.map(i -> null); // should be an IDE warning + assertThat(mapped.isEmpty()).isFalse(); + assertThat(mapped.value()).isNull(); + } + + @Test + void testIsLikeWhenPresent() { + IsLikeWhenPresent<String> nullCond = SqlBuilder.isLikeWhenPresent((String) null); + assertThat(nullCond.isEmpty()).isTrue(); + + IsLikeWhenPresent<String> cond = SqlBuilder.isLikeWhenPresent("fred"); + IsLikeWhenPresent<String> filtered = cond.filter(i -> i.equals("fred")); + IsLikeWhenPresent<String> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isTrue(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(mapped::value); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsLikeCaseInsensitive() { + IsLikeCaseInsensitive<String> nullCond = SqlBuilder.isLikeCaseInsensitive((String) null); // should be an IDE warning + assertThat(nullCond.isEmpty()).isFalse(); + + IsLikeCaseInsensitive<String> cond = SqlBuilder.isLikeCaseInsensitive("fred"); + IsLikeCaseInsensitive<String> filtered = cond.filter(i -> i.equals("FRED")); + IsLikeCaseInsensitive<String> mapped = filtered.map(i -> null); // should be an IDE warning + assertThat(mapped.isEmpty()).isFalse(); + assertThat(mapped.value()).isNull(); + } + + @Test + void testIsLikeCaseInsensitiveWhenPresent() { + IsLikeCaseInsensitiveWhenPresent<String> nullCond = SqlBuilder.isLikeCaseInsensitiveWhenPresent((String) null); + assertThat(nullCond.isEmpty()).isTrue(); + + IsLikeCaseInsensitiveWhenPresent<String> cond = SqlBuilder.isLikeCaseInsensitiveWhenPresent("fred"); + IsLikeCaseInsensitiveWhenPresent<String> filtered = cond.filter(i -> i.equals("fred")); + IsLikeCaseInsensitiveWhenPresent<String> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isTrue(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(mapped::value); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsNotLike() { + IsNotLike<String> nullCond = SqlBuilder.isNotLike((String) null); // should be an IDE warning + assertThat(nullCond.isEmpty()).isFalse(); + + IsNotLike<String> cond = SqlBuilder.isNotLike("fred"); + IsNotLike<String> filtered = cond.filter(i -> i.equals("fred")); + IsNotLike<String> mapped = filtered.map(i -> null); // should be an IDE warning + assertThat(mapped.isEmpty()).isFalse(); + assertThat(mapped.value()).isNull(); + } + + @Test + void testIsNotLikeWhenPresent() { + IsNotLikeWhenPresent<String> nullCond = SqlBuilder.isNotLikeWhenPresent((String) null); + assertThat(nullCond.isEmpty()).isTrue(); + + IsNotLikeWhenPresent<String> cond = SqlBuilder.isNotLikeWhenPresent("fred"); + IsNotLikeWhenPresent<String> filtered = cond.filter(i -> i.equals("fred")); + IsNotLikeWhenPresent<String> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isTrue(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(mapped::value); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsNotLikeCaseInsensitive() { + IsNotLikeCaseInsensitive<String> nullCond = SqlBuilder.isNotLikeCaseInsensitive((String) null); // should be an IDE warning + assertThat(nullCond.isEmpty()).isFalse(); + + IsNotLikeCaseInsensitive<String> cond = SqlBuilder.isNotLikeCaseInsensitive("fred"); + IsNotLikeCaseInsensitive<String> filtered = cond.filter(i -> i.equals("FRED")); + IsNotLikeCaseInsensitive<String> mapped = filtered.map(i -> null); // should be an IDE warning + assertThat(mapped.isEmpty()).isFalse(); + assertThat(mapped.value()).isNull(); + } + + @Test + void testIsNotLikeCaseInsensitiveWhenPresent() { + IsNotLikeCaseInsensitiveWhenPresent<String> nullCond = SqlBuilder.isNotLikeCaseInsensitiveWhenPresent((String) null); + assertThat(nullCond.isEmpty()).isTrue(); + + IsNotLikeCaseInsensitiveWhenPresent<String> cond = SqlBuilder.isNotLikeCaseInsensitiveWhenPresent("fred"); + IsNotLikeCaseInsensitiveWhenPresent<String> filtered = cond.filter(i -> i.equals("FRED")); + IsNotLikeCaseInsensitiveWhenPresent<String> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isTrue(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(mapped::value); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsIn() { + IsIn<Integer> nullCond = SqlBuilder.isIn((Integer) null); // should be an IDE warning + assertThat(nullCond.isEmpty()).isFalse(); + + IsIn<Integer> cond = SqlBuilder.isIn(1); + IsIn<Integer> filtered = cond.filter(i -> i == 1); + IsIn<Integer> mapped = filtered.map(i -> null); // should be an IDE warning + assertThat(mapped.isEmpty()).isFalse(); + assertThat(mapped.values().toList()).containsExactly((Integer) null); + } + + @Test + void testIsInWhenPresent() { + IsInWhenPresent<Integer> nullCond = SqlBuilder.isInWhenPresent((Integer) null); + assertThat(nullCond.isEmpty()).isTrue(); + + IsInWhenPresent<Integer> cond = SqlBuilder.isInWhenPresent(1); + IsInWhenPresent<Integer> filtered = cond.filter(i -> i == 1); + IsInWhenPresent<Integer> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isTrue(); + assertThat(mapped.values().toList()).isEmpty();; + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsInCaseInsensitive() { + IsInCaseInsensitive<String> nullCond = SqlBuilder.isInCaseInsensitive((String) null); // should be an IDE warning + assertThat(nullCond.isEmpty()).isFalse(); + + IsInCaseInsensitive<String> cond = SqlBuilder.isInCaseInsensitive("fred"); + IsInCaseInsensitive<String> filtered = cond.filter(i -> i.equals("FRED")); + IsInCaseInsensitive<String> mapped = filtered.map(i -> null); // should be an IDE warning + assertThat(mapped.isEmpty()).isFalse(); + assertThat(mapped.values().toList()).containsExactly((String) null); + } + + @Test + void testIsInCaseInsensitiveWhenPresent() { + IsInCaseInsensitiveWhenPresent<String> nullCond = SqlBuilder.isInCaseInsensitiveWhenPresent((String) null); + assertThat(nullCond.isEmpty()).isTrue(); + + IsInCaseInsensitiveWhenPresent<String> cond = SqlBuilder.isInCaseInsensitiveWhenPresent("fred"); + IsInCaseInsensitiveWhenPresent<String> filtered = cond.filter(i -> i.equals("FRED")); + IsInCaseInsensitiveWhenPresent<String> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isTrue(); + assertThat(mapped.values().toList()).isEmpty();; + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsNotIn() { + IsNotIn<Integer> nullCond = SqlBuilder.isNotIn((Integer) null); // should be an IDE warning + assertThat(nullCond.isEmpty()).isFalse(); + + IsNotIn<Integer> cond = SqlBuilder.isNotIn(1); + IsNotIn<Integer> filtered = cond.filter(i -> i == 1); + IsNotIn<Integer> mapped = filtered.map(i -> null); // should be an IDE warning + assertThat(mapped.isEmpty()).isFalse(); + assertThat(mapped.values().toList()).containsExactly((Integer) null); + } + + @Test + void testIsNotInWhenPresent() { + IsNotInWhenPresent<Integer> nullCond = SqlBuilder.isNotInWhenPresent((Integer) null); + assertThat(nullCond.isEmpty()).isTrue(); + + IsNotInWhenPresent<Integer> cond = SqlBuilder.isNotInWhenPresent(1); + IsNotInWhenPresent<Integer> filtered = cond.filter(i -> i == 1); + IsNotInWhenPresent<Integer> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isTrue(); + assertThat(mapped.values().toList()).isEmpty();; + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsNotInCaseInsensitive() { + IsNotInCaseInsensitive<String> nullCond = SqlBuilder.isNotInCaseInsensitive((String) null); // should be an IDE warning + assertThat(nullCond.isEmpty()).isFalse(); + + IsNotInCaseInsensitive<String> cond = SqlBuilder.isNotInCaseInsensitive("fred"); + IsNotInCaseInsensitive<String> filtered = cond.filter(i -> i.equals("FRED")); + IsNotInCaseInsensitive<String> mapped = filtered.map(i -> null); // should be an IDE warning + assertThat(mapped.isEmpty()).isFalse(); + assertThat(mapped.values().toList()).containsExactly((String) null); + } + + @Test + void testIsNotInCaseInsensitiveWhenPresent() { + IsNotInCaseInsensitiveWhenPresent<String> nullCond = SqlBuilder.isNotInCaseInsensitiveWhenPresent((String) null); + assertThat(nullCond.isEmpty()).isTrue(); + + IsNotInCaseInsensitiveWhenPresent<String> cond = SqlBuilder.isNotInCaseInsensitiveWhenPresent("fred"); + IsNotInCaseInsensitiveWhenPresent<String> filtered = cond.filter(i -> i.equals("FRED")); + IsNotInCaseInsensitiveWhenPresent<String> mapped = filtered.map(i -> null); + assertThat(mapped.isEmpty()).isTrue(); + assertThat(mapped.values().toList()).isEmpty();; + } +} diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java index b85a7f412..c2bf40ddf 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java @@ -44,7 +44,7 @@ void testIsBetweenNull() { @Test void testIsBetweenWhenPresent() { - IsBetween<Integer> cond = SqlBuilder.isBetweenWhenPresent(() -> 3).and(() -> 4); + IsBetweenWhenPresent<Integer> cond = SqlBuilder.isBetweenWhenPresent(() -> 3).and(() -> 4); assertThat(cond.value1()).isEqualTo(3); assertThat(cond.value2()).isEqualTo(4); assertThat(cond.isEmpty()).isFalse(); @@ -52,7 +52,7 @@ void testIsBetweenWhenPresent() { @Test void testIsBetweenWhenPresentNull() { - IsBetween<Integer> cond = SqlBuilder.isBetweenWhenPresent(() -> (Integer) null).and(() -> null); + IsBetweenWhenPresent<Integer> cond = SqlBuilder.isBetweenWhenPresent(() -> (Integer) null).and(() -> null); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value1); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value2); assertThat(cond.isEmpty()).isTrue(); @@ -76,7 +76,7 @@ void testIsNotBetweenNull() { @Test void testIsNotBetweenWhenPresent() { - IsNotBetween<Integer> cond = SqlBuilder.isNotBetweenWhenPresent(() -> 3).and(() -> 4); + IsNotBetweenWhenPresent<Integer> cond = SqlBuilder.isNotBetweenWhenPresent(() -> 3).and(() -> 4); assertThat(cond.value1()).isEqualTo(3); assertThat(cond.value2()).isEqualTo(4); assertThat(cond.isEmpty()).isFalse(); @@ -84,7 +84,7 @@ void testIsNotBetweenWhenPresent() { @Test void testIsNotBetweenWhenPresentNull() { - IsNotBetween<Integer> cond = SqlBuilder.isNotBetweenWhenPresent(() -> (Integer) null).and(() -> null); + IsNotBetweenWhenPresent<Integer> cond = SqlBuilder.isNotBetweenWhenPresent(() -> (Integer) null).and(() -> null); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value1); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value2); assertThat(cond.isEmpty()).isTrue(); @@ -92,14 +92,14 @@ void testIsNotBetweenWhenPresentNull() { @Test void testIsEqualToWhenPresent() { - IsEqualTo<Integer> cond = SqlBuilder.isEqualToWhenPresent(() -> 3); + IsEqualToWhenPresent<Integer> cond = SqlBuilder.isEqualToWhenPresent(() -> 3); assertThat(cond.value()).isEqualTo(3); assertThat(cond.isEmpty()).isFalse(); } @Test void testIsEqualToWhenPresentNull() { - IsEqualTo<Integer> cond = SqlBuilder.isEqualToWhenPresent(() -> null); + IsEqualToWhenPresent<Integer> cond = SqlBuilder.isEqualToWhenPresent(() -> null); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -120,14 +120,14 @@ void testIsNotEqualToNull() { @Test void testIsNotEqualToWhenPresent() { - IsNotEqualTo<Integer> cond = SqlBuilder.isNotEqualToWhenPresent(() -> 3); + IsNotEqualToWhenPresent<Integer> cond = SqlBuilder.isNotEqualToWhenPresent(() -> 3); assertThat(cond.value()).isEqualTo(3); assertThat(cond.isEmpty()).isFalse(); } @Test void testIsNotEqualToWhenPresentNull() { - IsNotEqualTo<Integer> cond = SqlBuilder.isNotEqualToWhenPresent(() -> null); + IsNotEqualToWhenPresent<Integer> cond = SqlBuilder.isNotEqualToWhenPresent(() -> null); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -148,14 +148,14 @@ void testIsGreaterThanNull() { @Test void testIsGreaterThanWhenPresent() { - IsGreaterThan<Integer> cond = SqlBuilder.isGreaterThanWhenPresent(() -> 3); + IsGreaterThanWhenPresent<Integer> cond = SqlBuilder.isGreaterThanWhenPresent(() -> 3); assertThat(cond.value()).isEqualTo(3); assertThat(cond.isEmpty()).isFalse(); } @Test void testIsGreaterThanWhenPresentNull() { - IsGreaterThan<Integer> cond = SqlBuilder.isGreaterThanWhenPresent(() -> null); + IsGreaterThanWhenPresent<Integer> cond = SqlBuilder.isGreaterThanWhenPresent(() -> null); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -176,14 +176,14 @@ void testIsGreaterThanOrEqualToNull() { @Test void testIsGreaterThanOrEqualToWhenPresent() { - IsGreaterThanOrEqualTo<Integer> cond = SqlBuilder.isGreaterThanOrEqualToWhenPresent(() -> 3); + IsGreaterThanOrEqualToWhenPresent<Integer> cond = SqlBuilder.isGreaterThanOrEqualToWhenPresent(() -> 3); assertThat(cond.value()).isEqualTo(3); assertThat(cond.isEmpty()).isFalse(); } @Test void testIsGreaterThanOrEqualToWhenPresentNull() { - IsGreaterThanOrEqualTo<Integer> cond = SqlBuilder.isGreaterThanOrEqualToWhenPresent(() -> null); + IsGreaterThanOrEqualToWhenPresent<Integer> cond = SqlBuilder.isGreaterThanOrEqualToWhenPresent(() -> null); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -204,14 +204,14 @@ void testIsLessThanNull() { @Test void testIsLessThanWhenPresent() { - IsLessThan<Integer> cond = SqlBuilder.isLessThanWhenPresent(() -> 3); + IsLessThanWhenPresent<Integer> cond = SqlBuilder.isLessThanWhenPresent(() -> 3); assertThat(cond.value()).isEqualTo(3); assertThat(cond.isEmpty()).isFalse(); } @Test void testIsLessThanWhenPresentNull() { - IsLessThan<Integer> cond = SqlBuilder.isLessThanWhenPresent(() -> null); + IsLessThanWhenPresent<Integer> cond = SqlBuilder.isLessThanWhenPresent(() -> null); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -232,14 +232,14 @@ void testIsLessThanOrEqualToNull() { @Test void testIsLessThanOrEqualToWhenPresent() { - IsLessThanOrEqualTo<Integer> cond = SqlBuilder.isLessThanOrEqualToWhenPresent(() -> 3); + IsLessThanOrEqualToWhenPresent<Integer> cond = SqlBuilder.isLessThanOrEqualToWhenPresent(() -> 3); assertThat(cond.value()).isEqualTo(3); assertThat(cond.isEmpty()).isFalse(); } @Test void testIsLessThanOrEqualToWhenPresentNull() { - IsLessThanOrEqualTo<Integer> cond = SqlBuilder.isLessThanOrEqualToWhenPresent(() -> null); + IsLessThanOrEqualToWhenPresent<Integer> cond = SqlBuilder.isLessThanOrEqualToWhenPresent(() -> null); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -274,28 +274,28 @@ void testIsLikeCaseInsensitiveNull() { @Test void testIsLikeCaseInsensitiveWhenPresent() { - IsLikeCaseInsensitive<String> cond = SqlBuilder.isLikeCaseInsensitiveWhenPresent(() -> "%f%"); + IsLikeCaseInsensitiveWhenPresent<String> cond = SqlBuilder.isLikeCaseInsensitiveWhenPresent(() -> "%f%"); assertThat(cond.value()).isEqualTo("%F%"); assertThat(cond.isEmpty()).isFalse(); } @Test void testIsLikeCaseInsensitiveWhenPresentNull() { - IsLikeCaseInsensitive<String> cond = SqlBuilder.isLikeCaseInsensitiveWhenPresent(() -> null); + IsLikeCaseInsensitiveWhenPresent<String> cond = SqlBuilder.isLikeCaseInsensitiveWhenPresent(() -> null); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @Test void testIsLikeWhenPresent() { - IsLike<String> cond = SqlBuilder.isLikeWhenPresent(() -> "%F%"); + IsLikeWhenPresent<String> cond = SqlBuilder.isLikeWhenPresent(() -> "%F%"); assertThat(cond.value()).isEqualTo("%F%"); assertThat(cond.isEmpty()).isFalse(); } @Test void testIsLikeWhenPresentNull() { - IsLike<String> cond = SqlBuilder.isLikeWhenPresent(() -> null); + IsLikeWhenPresent<String> cond = SqlBuilder.isLikeWhenPresent(() -> null); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -316,14 +316,14 @@ void testIsNotLikeNull() { @Test void testIsNotLikeWhenPresent() { - IsNotLike<String> cond = SqlBuilder.isNotLikeWhenPresent(() -> "%F%"); + IsNotLikeWhenPresent<String> cond = SqlBuilder.isNotLikeWhenPresent(() -> "%F%"); assertThat(cond.value()).isEqualTo("%F%"); assertThat(cond.isEmpty()).isFalse(); } @Test void testIsNotLikeWhenPresentNull() { - IsNotLike<String> cond = SqlBuilder.isNotLikeWhenPresent(() -> null); + IsNotLikeWhenPresent<String> cond = SqlBuilder.isNotLikeWhenPresent(() -> null); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } @@ -344,14 +344,14 @@ void testIsNotLikeCaseInsensitiveNull() { @Test void testIsNotLikeCaseInsensitiveWhenPresent() { - IsNotLikeCaseInsensitive<String> cond = SqlBuilder.isNotLikeCaseInsensitiveWhenPresent(() -> "%f%"); + IsNotLikeCaseInsensitiveWhenPresent<String> cond = SqlBuilder.isNotLikeCaseInsensitiveWhenPresent(() -> "%f%"); assertThat(cond.value()).isEqualTo("%F%"); assertThat(cond.isEmpty()).isFalse(); } @Test void testIsNotLikeCaseInsensitiveWhenPresentNull() { - IsNotLikeCaseInsensitive<String> cond = SqlBuilder.isNotLikeCaseInsensitiveWhenPresent(() -> null); + IsNotLikeCaseInsensitiveWhenPresent<String> cond = SqlBuilder.isNotLikeCaseInsensitiveWhenPresent(() -> null); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value); assertThat(cond.isEmpty()).isTrue(); } From d1771e82ab9177dca387c3060d9e839c48e80a8c Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Sun, 6 Apr 2025 18:19:37 -0400 Subject: [PATCH 232/260] Checkstyle --- .../dynamic/sql/where/condition/NullContractTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java index 35f0440d8..6ea7b2909 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java @@ -361,7 +361,7 @@ void testIsInWhenPresent() { IsInWhenPresent<Integer> filtered = cond.filter(i -> i == 1); IsInWhenPresent<Integer> mapped = filtered.map(i -> null); assertThat(mapped.isEmpty()).isTrue(); - assertThat(mapped.values().toList()).isEmpty();; + assertThat(mapped.values().toList()).isEmpty(); } @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing @@ -386,7 +386,7 @@ void testIsInCaseInsensitiveWhenPresent() { IsInCaseInsensitiveWhenPresent<String> filtered = cond.filter(i -> i.equals("FRED")); IsInCaseInsensitiveWhenPresent<String> mapped = filtered.map(i -> null); assertThat(mapped.isEmpty()).isTrue(); - assertThat(mapped.values().toList()).isEmpty();; + assertThat(mapped.values().toList()).isEmpty(); } @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing @@ -411,7 +411,7 @@ void testIsNotInWhenPresent() { IsNotInWhenPresent<Integer> filtered = cond.filter(i -> i == 1); IsNotInWhenPresent<Integer> mapped = filtered.map(i -> null); assertThat(mapped.isEmpty()).isTrue(); - assertThat(mapped.values().toList()).isEmpty();; + assertThat(mapped.values().toList()).isEmpty(); } @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing @@ -436,6 +436,6 @@ void testIsNotInCaseInsensitiveWhenPresent() { IsNotInCaseInsensitiveWhenPresent<String> filtered = cond.filter(i -> i.equals("FRED")); IsNotInCaseInsensitiveWhenPresent<String> mapped = filtered.map(i -> null); assertThat(mapped.isEmpty()).isTrue(); - assertThat(mapped.values().toList()).isEmpty();; + assertThat(mapped.values().toList()).isEmpty(); } } From ee2ccbf6c0e3f7c4a2b1f408351af28ff4a58682 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 7 Apr 2025 10:32:22 -0400 Subject: [PATCH 233/260] Add missing jSpecify annotations --- src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java | 2 +- src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java index 3724e5395..aeebc5498 100644 --- a/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/delete/DeleteDSL.java @@ -120,7 +120,7 @@ public DeleteDSL<R> limit(long limit) { return limitWhenPresent(limit); } - public DeleteDSL<R> limitWhenPresent(Long limit) { + public DeleteDSL<R> limitWhenPresent(@Nullable Long limit) { return DeleteDSL.this.limitWhenPresent(limit); } diff --git a/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java index f33bbc074..fbac97595 100644 --- a/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java +++ b/src/main/java/org/mybatis/dynamic/sql/update/UpdateDSL.java @@ -202,7 +202,7 @@ public UpdateDSL<R> limit(long limit) { return limitWhenPresent(limit); } - public UpdateDSL<R> limitWhenPresent(Long limit) { + public UpdateDSL<R> limitWhenPresent(@Nullable Long limit) { return UpdateDSL.this.limitWhenPresent(limit); } From 6315e94d65638b82d311a2214013e9c702285c1d Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 7 Apr 2025 10:43:12 -0400 Subject: [PATCH 234/260] Properly handle null row in sommon select mapper --- .../sql/util/mybatis3/CommonSelectMapper.java | 18 ++++++++++-------- .../animal/data/CommonSelectMapperTest.java | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java index 1faa0bd05..789538fed 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java @@ -22,6 +22,7 @@ import java.util.function.Function; import org.apache.ibatis.annotations.SelectProvider; +import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.mybatis.dynamic.sql.util.SqlProviderAdapter; @@ -58,7 +59,7 @@ public interface CommonSelectMapper { * @return A Map containing the row values. */ @SelectProvider(type = SqlProviderAdapter.class, method = "select") - Map<String, Object> selectOneMappedRow(SelectStatementProvider selectStatement); + @Nullable Map<String, Object> selectOneMappedRow(SelectStatementProvider selectStatement); /** * Select a single row of values and then convert the values to a custom type. This is similar @@ -74,9 +75,10 @@ public interface CommonSelectMapper { * @param <R> the datatype of the converted object * @return the converted object */ - default <R> R selectOne(SelectStatementProvider selectStatement, + default <R> @Nullable R selectOne(SelectStatementProvider selectStatement, Function<Map<String, Object>, R> rowMapper) { - return rowMapper.apply(selectOneMappedRow(selectStatement)); + var result = selectOneMappedRow(selectStatement); + return result == null ? null : rowMapper.apply(result); } /** @@ -122,7 +124,7 @@ default <R> List<R> selectMany(SelectStatementProvider selectStatement, * column is null */ @SelectProvider(type = SqlProviderAdapter.class, method = "select") - BigDecimal selectOneBigDecimal(SelectStatementProvider selectStatement); + @Nullable BigDecimal selectOneBigDecimal(SelectStatementProvider selectStatement); /** * Retrieve a single {@link java.math.BigDecimal} from a result set. The result set must have @@ -157,7 +159,7 @@ default <R> List<R> selectMany(SelectStatementProvider selectStatement, * column is null */ @SelectProvider(type = SqlProviderAdapter.class, method = "select") - Double selectOneDouble(SelectStatementProvider selectStatement); + @Nullable Double selectOneDouble(SelectStatementProvider selectStatement); /** * Retrieve a single {@link java.lang.Double} from a result set. The result set must have @@ -192,7 +194,7 @@ default <R> List<R> selectMany(SelectStatementProvider selectStatement, * column is null */ @SelectProvider(type = SqlProviderAdapter.class, method = "select") - Integer selectOneInteger(SelectStatementProvider selectStatement); + @Nullable Integer selectOneInteger(SelectStatementProvider selectStatement); /** * Retrieve a single {@link java.lang.Integer} from a result set. The result set must have @@ -227,7 +229,7 @@ default <R> List<R> selectMany(SelectStatementProvider selectStatement, * column is null */ @SelectProvider(type = SqlProviderAdapter.class, method = "select") - Long selectOneLong(SelectStatementProvider selectStatement); + @Nullable Long selectOneLong(SelectStatementProvider selectStatement); /** * Retrieve a single {@link java.lang.Long} from a result set. The result set must have @@ -262,7 +264,7 @@ default <R> List<R> selectMany(SelectStatementProvider selectStatement, * column is null */ @SelectProvider(type = SqlProviderAdapter.class, method = "select") - String selectOneString(SelectStatementProvider selectStatement); + @Nullable String selectOneString(SelectStatementProvider selectStatement); /** * Retrieve a single {@link java.lang.String} from a result set. The result set must have diff --git a/src/test/java/examples/animal/data/CommonSelectMapperTest.java b/src/test/java/examples/animal/data/CommonSelectMapperTest.java index 863df85e6..380d888f7 100644 --- a/src/test/java/examples/animal/data/CommonSelectMapperTest.java +++ b/src/test/java/examples/animal/data/CommonSelectMapperTest.java @@ -106,6 +106,7 @@ void testGeneralSelectOneWithRowMapper() { AnimalData animal = mapper.selectOne(selectStatement, rowMapper); + assertThat(animal).isNotNull(); assertThat(animal.getId()).isEqualTo(1); assertThat(animal.getAnimalName()).isEqualTo("Lesser short-tailed shrew"); assertThat(animal.getBodyWeight()).isEqualTo(0.14); @@ -113,6 +114,21 @@ void testGeneralSelectOneWithRowMapper() { } } + @Test + void testGeneralSelectOneWithRowMapperAndNullRow() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + CommonSelectMapper mapper = sqlSession.getMapper(CommonSelectMapper.class); + SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) + .from(animalData) + .where(id, isEqualTo(-237)) + .build() + .render(RenderingStrategies.MYBATIS3); + + AnimalData animal = mapper.selectOne(selectStatement, rowMapper); + assertThat(animal).isNull(); + } + } + @Test void testGeneralSelectMany() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { From 37fa65f2339ca2cf31a32b706c4b0d9506ebfd80 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 7 Apr 2025 10:50:44 -0400 Subject: [PATCH 235/260] Documentation --- .../mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java index 789538fed..8f0f350ee 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/mybatis3/CommonSelectMapper.java @@ -50,7 +50,7 @@ public interface CommonSelectMapper { /** * Select a single row as a Map of values. The row may have any number of columns. * The Map key will be the column name as returned from the - * database (may be aliased if an alias is specified in the select statement). Map entries will be + * database (the key will be aliased if an alias is specified in the select statement). Map entries will be * of data types determined by the JDBC driver. MyBatis will call ResultSet.getObject() to retrieve * values from the ResultSet. Reference your JDBC driver documentation to learn about type mappings * for your specific database. @@ -85,7 +85,7 @@ public interface CommonSelectMapper { * Select any number of rows and return a List of Maps containing row values (one Map for each row returned). * The rows may have any number of columns. * The Map key will be the column name as returned from the - * database (may be aliased if an alias is specified in the select statement). Map entries will be + * database (the key will be aliased if an alias is specified in the select statement). Map entries will be * of data types determined by the JDBC driver. MyBatis will call ResultSet.getObject() to retrieve * values from the ResultSet. Reference your JDBC driver documentation to learn about type mappings * for your specific database. From 26c973a6dfd9846975f0aa2d9afa2f10b2d38c07 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 7 Apr 2025 10:52:32 -0400 Subject: [PATCH 236/260] Fully denote the nullability of filter and map methods. Also fix al the tests that were, essentially, misuses of the library. --- .../sql/AbstractListValueCondition.java | 5 +- .../sql/AbstractSingleValueCondition.java | 5 +- .../sql/AbstractTwoValueCondition.java | 11 +- .../sql/where/condition/IsBetween.java | 12 +- .../where/condition/IsBetweenWhenPresent.java | 11 +- .../sql/where/condition/IsEqualTo.java | 5 +- .../where/condition/IsEqualToWhenPresent.java | 5 +- .../sql/where/condition/IsGreaterThan.java | 5 +- .../condition/IsGreaterThanOrEqualTo.java | 5 +- .../IsGreaterThanOrEqualToWhenPresent.java | 5 +- .../condition/IsGreaterThanWhenPresent.java | 5 +- .../dynamic/sql/where/condition/IsIn.java | 5 +- .../where/condition/IsInCaseInsensitive.java | 5 +- .../IsInCaseInsensitiveWhenPresent.java | 7 +- .../sql/where/condition/IsInWhenPresent.java | 7 +- .../sql/where/condition/IsLessThan.java | 5 +- .../where/condition/IsLessThanOrEqualTo.java | 5 +- .../IsLessThanOrEqualToWhenPresent.java | 5 +- .../condition/IsLessThanWhenPresent.java | 5 +- .../dynamic/sql/where/condition/IsLike.java | 5 +- .../condition/IsLikeCaseInsensitive.java | 5 +- .../IsLikeCaseInsensitiveWhenPresent.java | 5 +- .../where/condition/IsLikeWhenPresent.java | 5 +- .../sql/where/condition/IsNotBetween.java | 11 +- .../condition/IsNotBetweenWhenPresent.java | 11 +- .../sql/where/condition/IsNotEqualTo.java | 5 +- .../condition/IsNotEqualToWhenPresent.java | 5 +- .../dynamic/sql/where/condition/IsNotIn.java | 5 +- .../condition/IsNotInCaseInsensitive.java | 5 +- .../IsNotInCaseInsensitiveWhenPresent.java | 7 +- .../where/condition/IsNotInWhenPresent.java | 7 +- .../sql/where/condition/IsNotLike.java | 5 +- .../condition/IsNotLikeCaseInsensitive.java | 5 +- .../IsNotLikeCaseInsensitiveWhenPresent.java | 5 +- .../where/condition/IsNotLikeWhenPresent.java | 5 +- ...onditionsWithPredicatesAnimalDataTest.java | 109 +++++++----------- .../complexquery/ComplexQueryTest.java | 10 +- .../examples/emptywhere/EmptyWhereTest.java | 43 +++---- .../examples/simple/PersonMapperTest.java | 3 +- src/test/java/issues/gh105/Issue105Test.java | 43 ++++--- .../sql/where/condition/FilterAndMapTest.java | 27 ++--- .../sql/where/condition/NullContractTest.java | 90 +++++++++++++++ .../sql/where/condition/SupplierTest.java | 79 ------------- .../render/OptionalCriterionRenderTest.java | 3 +- 44 files changed, 315 insertions(+), 306 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java index 41c6a56e2..e178c6bf3 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java @@ -23,6 +23,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.render.RenderedParameterInfo; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; @@ -113,7 +114,7 @@ public interface Filterable<T> { * @return this condition if renderable and the value matches the predicate, otherwise a condition * that will not render. */ - AbstractListValueCondition<T> filter(Predicate<? super T> predicate); + AbstractListValueCondition<T> filter(Predicate<? super @NonNull T> predicate); } /** @@ -138,6 +139,6 @@ public interface Mappable<T> { * @return a new condition with the result of applying the mapper to the value of this condition, * if renderable, otherwise a condition that will not render. */ - <R> AbstractListValueCondition<R> map(Function<? super T, ? extends R> mapper); + <R> AbstractListValueCondition<R> map(Function<? super @NonNull T, ? extends R> mapper); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java index c16dbf08c..eb56eef39 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractSingleValueCondition.java @@ -21,6 +21,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.render.RenderedParameterInfo; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; @@ -88,7 +89,7 @@ public interface Filterable<T> { * @return this condition if renderable and the value matches the predicate, otherwise a condition * that will not render. */ - AbstractSingleValueCondition<T> filter(Predicate<? super T> predicate); + AbstractSingleValueCondition<T> filter(Predicate<? super @NonNull T> predicate); } /** @@ -113,6 +114,6 @@ public interface Mappable<T> { * @return a new condition with the result of applying the mapper to the value of this condition, * if renderable, otherwise a condition that will not render. */ - <R> AbstractSingleValueCondition<R> map(Function<? super T, ? extends R> mapper); + <R> AbstractSingleValueCondition<R> map(Function<? super @NonNull T, ? extends R> mapper); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java index 6cceff16e..d409ffbb8 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractTwoValueCondition.java @@ -23,6 +23,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.render.RenderedParameterInfo; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; @@ -110,7 +111,7 @@ public interface Filterable<T> { * @return this condition if renderable and the values match the predicate, otherwise a condition * that will not render. */ - AbstractTwoValueCondition<T> filter(BiPredicate<? super T, ? super T> predicate); + AbstractTwoValueCondition<T> filter(BiPredicate<? super @NonNull T, ? super @NonNull T> predicate); /** * If renderable and both values match the predicate, returns this condition. Else returns a condition @@ -121,7 +122,7 @@ public interface Filterable<T> { * @return this condition if renderable and the values match the predicate, otherwise a condition * that will not render. */ - AbstractTwoValueCondition<T> filter(Predicate<? super T> predicate); + AbstractTwoValueCondition<T> filter(Predicate<? super @NonNull T> predicate); } /** @@ -147,8 +148,8 @@ public interface Mappable<T> { * @return a new condition with the result of applying the mappers to the values of this condition, * if renderable, otherwise a condition that will not render. */ - <R> AbstractTwoValueCondition<R> map(Function<? super T, ? extends R> mapper1, - Function<? super T, ? extends R> mapper2); + <R> AbstractTwoValueCondition<R> map(Function<? super @NonNull T, ? extends R> mapper1, + Function<? super @NonNull T, ? extends R> mapper2); /** * If renderable, apply the mapping to both values and return a new condition with the new values. Else return a @@ -159,6 +160,6 @@ <R> AbstractTwoValueCondition<R> map(Function<? super T, ? extends R> mapper1, * @return a new condition with the result of applying the mappers to the values of this condition, * if renderable, otherwise a condition that will not render. */ - <R> AbstractTwoValueCondition<R> map(Function<? super T, ? extends R> mapper); + <R> AbstractTwoValueCondition<R> map(Function<? super @NonNull T, ? extends R> mapper); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java index fab5e70f6..0f7fcd66a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetween.java @@ -20,9 +20,10 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.AbstractTwoValueCondition; -public class IsBetween<T> extends AbstractTwoValueCondition<T> +public class IsBetween<T> extends AbstractTwoValueCondition<@NonNull T> implements AbstractTwoValueCondition.Filterable<T>, AbstractTwoValueCondition.Mappable<T> { private static final IsBetween<?> EMPTY = new IsBetween<Object>(-1, -1) { @Override @@ -62,22 +63,23 @@ public String operator2() { } @Override - public IsBetween<T> filter(BiPredicate<? super T, ? super T> predicate) { + public IsBetween<T> filter(BiPredicate<? super @NonNull T, ? super @NonNull T> predicate) { return filterSupport(predicate, IsBetween::empty, this); } @Override - public IsBetween<T> filter(Predicate<? super T> predicate) { + public IsBetween<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsBetween::empty, this); } @Override - public <R> IsBetween<R> map(Function<? super T, ? extends R> mapper1, Function<? super T, ? extends R> mapper2) { + public <R> IsBetween<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper1, + Function<? super @NonNull T, ? extends @NonNull R> mapper2) { return mapSupport(mapper1, mapper2, IsBetween::new, IsBetween::empty); } @Override - public <R> IsBetween<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsBetween<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper) { return map(mapper, mapper); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetweenWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetweenWhenPresent.java index 8c23cdfbb..a3eb2a91e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetweenWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetweenWhenPresent.java @@ -20,6 +20,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractTwoValueCondition; @@ -63,23 +64,23 @@ public String operator2() { } @Override - public IsBetweenWhenPresent<T> filter(BiPredicate<? super T, ? super T> predicate) { + public IsBetweenWhenPresent<T> filter(BiPredicate<? super @NonNull T, ? super @NonNull T> predicate) { return filterSupport(predicate, IsBetweenWhenPresent::empty, this); } @Override - public IsBetweenWhenPresent<T> filter(Predicate<? super T> predicate) { + public IsBetweenWhenPresent<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsBetweenWhenPresent::empty, this); } @Override - public <R> IsBetweenWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper1, - Function<? super T, ? extends @Nullable R> mapper2) { + public <R> IsBetweenWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper1, + Function<? super @NonNull T, ? extends @Nullable R> mapper2) { return mapSupport(mapper1, mapper2, IsBetweenWhenPresent::of, IsBetweenWhenPresent::empty); } @Override - public <R> IsBetweenWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + public <R> IsBetweenWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper) { return map(mapper, mapper); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java index 51e6e4d47..db8548f61 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualTo.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsEqualTo<T> extends AbstractSingleValueCondition<T> @@ -56,12 +57,12 @@ public static <T> IsEqualTo<T> of(T value) { } @Override - public IsEqualTo<T> filter(Predicate<? super T> predicate) { + public IsEqualTo<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsEqualTo::empty, this); } @Override - public <R> IsEqualTo<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsEqualTo<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper) { return mapSupport(mapper, IsEqualTo::new, IsEqualTo::empty); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToWhenPresent.java index f06489076..2dd8c746d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsEqualToWhenPresent.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; @@ -61,12 +62,12 @@ public static <T> IsEqualToWhenPresent<T> of(@Nullable T value) { } @Override - public IsEqualToWhenPresent<T> filter(Predicate<? super T> predicate) { + public IsEqualToWhenPresent<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsEqualToWhenPresent::empty, this); } @Override - public <R> IsEqualToWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + public <R> IsEqualToWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper) { return mapSupport(mapper, IsEqualToWhenPresent::of, IsEqualToWhenPresent::empty); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java index 93be70911..577a400f2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThan.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsGreaterThan<T> extends AbstractSingleValueCondition<T> @@ -55,12 +56,12 @@ public static <T> IsGreaterThan<T> of(T value) { } @Override - public IsGreaterThan<T> filter(Predicate<? super T> predicate) { + public IsGreaterThan<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsGreaterThan::empty, this); } @Override - public <R> IsGreaterThan<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsGreaterThan<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper) { return mapSupport(mapper, IsGreaterThan::new, IsGreaterThan::empty); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java index 8373bf352..5fb4bd0d4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualTo.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsGreaterThanOrEqualTo<T> extends AbstractSingleValueCondition<T> @@ -55,12 +56,12 @@ public static <T> IsGreaterThanOrEqualTo<T> of(T value) { } @Override - public IsGreaterThanOrEqualTo<T> filter(Predicate<? super T> predicate) { + public IsGreaterThanOrEqualTo<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsGreaterThanOrEqualTo::empty, this); } @Override - public <R> IsGreaterThanOrEqualTo<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsGreaterThanOrEqualTo<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper) { return mapSupport(mapper, IsGreaterThanOrEqualTo::new, IsGreaterThanOrEqualTo::empty); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWhenPresent.java index 89e8cda4f..825b5c6cf 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWhenPresent.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; @@ -60,12 +61,12 @@ public static <T> IsGreaterThanOrEqualToWhenPresent<T> of(@Nullable T value) { } @Override - public IsGreaterThanOrEqualToWhenPresent<T> filter(Predicate<? super T> predicate) { + public IsGreaterThanOrEqualToWhenPresent<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsGreaterThanOrEqualToWhenPresent::empty, this); } @Override - public <R> IsGreaterThanOrEqualToWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + public <R> IsGreaterThanOrEqualToWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper) { return mapSupport(mapper, IsGreaterThanOrEqualToWhenPresent::of, IsGreaterThanOrEqualToWhenPresent::empty); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanWhenPresent.java index 175b5fcf6..779a15596 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanWhenPresent.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; @@ -60,12 +61,12 @@ public static <T> IsGreaterThanWhenPresent<T> of(@Nullable T value) { } @Override - public IsGreaterThanWhenPresent<T> filter(Predicate<? super T> predicate) { + public IsGreaterThanWhenPresent<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsGreaterThanWhenPresent::empty, this); } @Override - public <R> IsGreaterThanWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + public <R> IsGreaterThanWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper) { return mapSupport(mapper, IsGreaterThanWhenPresent::of, IsGreaterThanWhenPresent::empty); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java index 8beeacc8d..886980610 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java @@ -21,6 +21,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.Validator; @@ -51,12 +52,12 @@ public String operator() { } @Override - public IsIn<T> filter(Predicate<? super T> predicate) { + public IsIn<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsIn::new, this, IsIn::empty); } @Override - public <R> IsIn<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsIn<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper) { return mapSupport(mapper, IsIn::new, IsIn::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java index 3e2a22d2a..d26a9c30f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitive.java @@ -21,6 +21,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.StringUtilities; @@ -53,12 +54,12 @@ public String operator() { } @Override - public IsInCaseInsensitive<T> filter(Predicate<? super T> predicate) { + public IsInCaseInsensitive<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsInCaseInsensitive::new, this, IsInCaseInsensitive::empty); } @Override - public <R> IsInCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsInCaseInsensitive<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper) { return mapSupport(mapper, IsInCaseInsensitive::new, IsInCaseInsensitive::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java index ac3ce2787..934df359b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java @@ -22,6 +22,7 @@ import java.util.Objects; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; @@ -48,13 +49,13 @@ public String operator() { } @Override - public IsInCaseInsensitiveWhenPresent<T> filter(Predicate<? super T> predicate) { + public IsInCaseInsensitiveWhenPresent<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsInCaseInsensitiveWhenPresent::new, this, IsInCaseInsensitiveWhenPresent::empty); } @Override - public <R> IsInCaseInsensitiveWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + public <R> IsInCaseInsensitiveWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper) { return mapSupport(mapper, IsInCaseInsensitiveWhenPresent::new, IsInCaseInsensitiveWhenPresent::empty); } @@ -64,7 +65,7 @@ public static <T> IsInCaseInsensitiveWhenPresent<T> of(@Nullable T... values) { } public static <T> IsInCaseInsensitiveWhenPresent<T> of(@Nullable Collection<@Nullable T> values) { - if (values == null || values.isEmpty()) { + if (values == null) { return empty(); } else { return new IsInCaseInsensitiveWhenPresent<>(values); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java index 1ec8185ee..2dec62d72 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java @@ -22,6 +22,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; @@ -45,12 +46,12 @@ public String operator() { } @Override - public IsInWhenPresent<T> filter(Predicate<? super T> predicate) { + public IsInWhenPresent<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsInWhenPresent::new, this, IsInWhenPresent::empty); } @Override - public <R> IsInWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + public <R> IsInWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper) { return mapSupport(mapper, IsInWhenPresent::of, IsInWhenPresent::empty); } @@ -60,7 +61,7 @@ public static <T> IsInWhenPresent<T> of(@Nullable T... values) { } public static <T> IsInWhenPresent<T> of(@Nullable Collection<@Nullable T> values) { - if (values == null || values.isEmpty()) { + if (values == null) { return empty(); } else { return new IsInWhenPresent<>(values); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java index 3ed383fbd..ffe66bd97 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThan.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsLessThan<T> extends AbstractSingleValueCondition<T> @@ -56,12 +57,12 @@ public static <T> IsLessThan<T> of(T value) { } @Override - public IsLessThan<T> filter(Predicate<? super T> predicate) { + public IsLessThan<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsLessThan::empty, this); } @Override - public <R> IsLessThan<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsLessThan<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper) { return mapSupport(mapper, IsLessThan::new, IsLessThan::empty); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java index 1b92e0c40..a73707e3e 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualTo.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsLessThanOrEqualTo<T> extends AbstractSingleValueCondition<T> @@ -55,12 +56,12 @@ public static <T> IsLessThanOrEqualTo<T> of(T value) { } @Override - public IsLessThanOrEqualTo<T> filter(Predicate<? super T> predicate) { + public IsLessThanOrEqualTo<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsLessThanOrEqualTo::empty, this); } @Override - public <R> IsLessThanOrEqualTo<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsLessThanOrEqualTo<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper) { return mapSupport(mapper, IsLessThanOrEqualTo::new, IsLessThanOrEqualTo::empty); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToWhenPresent.java index 3cdc8ff39..d944b7a45 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanOrEqualToWhenPresent.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; @@ -60,12 +61,12 @@ public static <T> IsLessThanOrEqualToWhenPresent<T> of(@Nullable T value) { } @Override - public IsLessThanOrEqualToWhenPresent<T> filter(Predicate<? super T> predicate) { + public IsLessThanOrEqualToWhenPresent<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsLessThanOrEqualToWhenPresent::empty, this); } @Override - public <R> IsLessThanOrEqualToWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + public <R> IsLessThanOrEqualToWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper) { return mapSupport(mapper, IsLessThanOrEqualToWhenPresent::of, IsLessThanOrEqualToWhenPresent::empty); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanWhenPresent.java index 78a07f9a2..830bf788c 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLessThanWhenPresent.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; @@ -61,12 +62,12 @@ public static <T> IsLessThanWhenPresent<T> of(@Nullable T value) { } @Override - public IsLessThanWhenPresent<T> filter(Predicate<? super T> predicate) { + public IsLessThanWhenPresent<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsLessThanWhenPresent::empty, this); } @Override - public <R> IsLessThanWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + public <R> IsLessThanWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper) { return mapSupport(mapper, IsLessThanWhenPresent::of, IsLessThanWhenPresent::empty); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java index e738bda4c..f2d2a419a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLike.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsLike<T> extends AbstractSingleValueCondition<T> @@ -56,12 +57,12 @@ public static <T> IsLike<T> of(T value) { } @Override - public IsLike<T> filter(Predicate<? super T> predicate) { + public IsLike<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsLike::empty, this); } @Override - public <R> IsLike<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsLike<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper) { return mapSupport(mapper, IsLike::new, IsLike::empty); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java index ffdc2bc7d..43525e287 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitive.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; @@ -53,12 +54,12 @@ public String operator() { } @Override - public IsLikeCaseInsensitive<T> filter(Predicate<? super T> predicate) { + public IsLikeCaseInsensitive<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsLikeCaseInsensitive::empty, this); } @Override - public <R> IsLikeCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsLikeCaseInsensitive<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper) { return mapSupport(mapper, IsLikeCaseInsensitive::new, IsLikeCaseInsensitive::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitiveWhenPresent.java index 89ab9b038..bebbff30d 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitiveWhenPresent.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; @@ -54,12 +55,12 @@ public String operator() { } @Override - public IsLikeCaseInsensitiveWhenPresent<T> filter(Predicate<? super T> predicate) { + public IsLikeCaseInsensitiveWhenPresent<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsLikeCaseInsensitiveWhenPresent::empty, this); } @Override - public <R> IsLikeCaseInsensitiveWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + public <R> IsLikeCaseInsensitiveWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper) { return mapSupport(mapper, IsLikeCaseInsensitiveWhenPresent::of, IsLikeCaseInsensitiveWhenPresent::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeWhenPresent.java index a69e55356..fc20722a2 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeWhenPresent.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; @@ -61,12 +62,12 @@ public static <T> IsLikeWhenPresent<T> of(@Nullable T value) { } @Override - public IsLikeWhenPresent<T> filter(Predicate<? super T> predicate) { + public IsLikeWhenPresent<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsLikeWhenPresent::empty, this); } @Override - public <R> IsLikeWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + public <R> IsLikeWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper) { return mapSupport(mapper, IsLikeWhenPresent::of, IsLikeWhenPresent::empty); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java index 836e3c741..b3d0d59ff 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetween.java @@ -20,6 +20,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.AbstractTwoValueCondition; public class IsNotBetween<T> extends AbstractTwoValueCondition<T> @@ -62,23 +63,23 @@ public String operator2() { } @Override - public IsNotBetween<T> filter(BiPredicate<? super T, ? super T> predicate) { + public IsNotBetween<T> filter(BiPredicate<? super @NonNull T, ? super @NonNull T> predicate) { return filterSupport(predicate, IsNotBetween::empty, this); } @Override - public IsNotBetween<T> filter(Predicate<? super T> predicate) { + public IsNotBetween<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsNotBetween::empty, this); } @Override - public <R> IsNotBetween<R> map(Function<? super T, ? extends R> mapper1, - Function<? super T, ? extends R> mapper2) { + public <R> IsNotBetween<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper1, + Function<? super @NonNull T, ? extends @NonNull R> mapper2) { return mapSupport(mapper1, mapper2, IsNotBetween::new, IsNotBetween::empty); } @Override - public <R> IsNotBetween<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsNotBetween<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper) { return map(mapper, mapper); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetweenWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetweenWhenPresent.java index 23b6507d5..cb9860384 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetweenWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetweenWhenPresent.java @@ -20,6 +20,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractTwoValueCondition; @@ -63,23 +64,23 @@ public String operator2() { } @Override - public IsNotBetweenWhenPresent<T> filter(BiPredicate<? super T, ? super T> predicate) { + public IsNotBetweenWhenPresent<T> filter(BiPredicate<? super @NonNull T, ? super @NonNull T> predicate) { return filterSupport(predicate, IsNotBetweenWhenPresent::empty, this); } @Override - public IsNotBetweenWhenPresent<T> filter(Predicate<? super T> predicate) { + public IsNotBetweenWhenPresent<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsNotBetweenWhenPresent::empty, this); } @Override - public <R> IsNotBetweenWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper1, - Function<? super T, ? extends @Nullable R> mapper2) { + public <R> IsNotBetweenWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper1, + Function<? super @NonNull T, ? extends @Nullable R> mapper2) { return mapSupport(mapper1, mapper2, IsNotBetweenWhenPresent::of, IsNotBetweenWhenPresent::empty); } @Override - public <R> IsNotBetweenWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + public <R> IsNotBetweenWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper) { return map(mapper, mapper); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java index 39070c2e8..fc0292070 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualTo.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsNotEqualTo<T> extends AbstractSingleValueCondition<T> @@ -55,12 +56,12 @@ public static <T> IsNotEqualTo<T> of(T value) { } @Override - public IsNotEqualTo<T> filter(Predicate<? super T> predicate) { + public IsNotEqualTo<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsNotEqualTo::empty, this); } @Override - public <R> IsNotEqualTo<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsNotEqualTo<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper) { return mapSupport(mapper, IsNotEqualTo::new, IsNotEqualTo::empty); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToWhenPresent.java index 07ab3f6cf..1fff2d9ba 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotEqualToWhenPresent.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; @@ -60,12 +61,12 @@ public static <T> IsNotEqualToWhenPresent<T> of(@Nullable T value) { } @Override - public IsNotEqualToWhenPresent<T> filter(Predicate<? super T> predicate) { + public IsNotEqualToWhenPresent<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsNotEqualToWhenPresent::empty, this); } @Override - public <R> IsNotEqualToWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + public <R> IsNotEqualToWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper) { return mapSupport(mapper, IsNotEqualToWhenPresent::of, IsNotEqualToWhenPresent::empty); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java index 33f5d14c7..f6c70d180 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java @@ -21,6 +21,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.Validator; @@ -51,12 +52,12 @@ public String operator() { } @Override - public IsNotIn<T> filter(Predicate<? super T> predicate) { + public IsNotIn<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsNotIn::new, this, IsNotIn::empty); } @Override - public <R> IsNotIn<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsNotIn<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper) { return mapSupport(mapper, IsNotIn::new, IsNotIn::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java index 2bc802ab8..98a9ca9db 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitive.java @@ -21,6 +21,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.StringUtilities; @@ -53,12 +54,12 @@ public String operator() { } @Override - public IsNotInCaseInsensitive<T> filter(Predicate<? super T> predicate) { + public IsNotInCaseInsensitive<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsNotInCaseInsensitive::new, this, IsNotInCaseInsensitive::empty); } @Override - public <R> IsNotInCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsNotInCaseInsensitive<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper) { return mapSupport(mapper, IsNotInCaseInsensitive::new, IsNotInCaseInsensitive::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java index 82d9d6e27..5646168c1 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java @@ -22,6 +22,7 @@ import java.util.Objects; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; @@ -48,13 +49,13 @@ public String operator() { } @Override - public IsNotInCaseInsensitiveWhenPresent<T> filter(Predicate<? super T> predicate) { + public IsNotInCaseInsensitiveWhenPresent<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsNotInCaseInsensitiveWhenPresent::new, this, IsNotInCaseInsensitiveWhenPresent::empty); } @Override - public <R> IsNotInCaseInsensitiveWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + public <R> IsNotInCaseInsensitiveWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper) { return mapSupport(mapper, IsNotInCaseInsensitiveWhenPresent::new, IsNotInCaseInsensitiveWhenPresent::empty); } @@ -64,7 +65,7 @@ public static <T> IsNotInCaseInsensitiveWhenPresent<T> of(@Nullable T... values) } public static <T> IsNotInCaseInsensitiveWhenPresent<T> of(@Nullable Collection<@Nullable T> values) { - if (values == null || values.isEmpty()) { + if (values == null) { return empty(); } else { return new IsNotInCaseInsensitiveWhenPresent<>(values); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java index ed4b27389..375f7d69b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java @@ -22,6 +22,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractListValueCondition; @@ -45,12 +46,12 @@ public String operator() { } @Override - public IsNotInWhenPresent<T> filter(Predicate<? super T> predicate) { + public IsNotInWhenPresent<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsNotInWhenPresent::new, this, IsNotInWhenPresent::empty); } @Override - public <R> IsNotInWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + public <R> IsNotInWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper) { return mapSupport(mapper, IsNotInWhenPresent::new, IsNotInWhenPresent::empty); } @@ -60,7 +61,7 @@ public static <T> IsNotInWhenPresent<T> of(@Nullable T... values) { } public static <T> IsNotInWhenPresent<T> of(@Nullable Collection<@Nullable T> values) { - if (values == null || values.isEmpty()) { + if (values == null) { return empty(); } else { return new IsNotInWhenPresent<>(values); diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java index a62dc3e9e..b5b82d675 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLike.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; public class IsNotLike<T> extends AbstractSingleValueCondition<T> @@ -55,12 +56,12 @@ public static <T> IsNotLike<T> of(T value) { } @Override - public IsNotLike<T> filter(Predicate<? super T> predicate) { + public IsNotLike<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsNotLike::empty, this); } @Override - public <R> IsNotLike<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsNotLike<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper) { return mapSupport(mapper, IsNotLike::new, IsNotLike::empty); } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java index 6bd943227..1604deb3b 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitive.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; @@ -53,12 +54,12 @@ public String operator() { } @Override - public IsNotLikeCaseInsensitive<T> filter(Predicate<? super T> predicate) { + public IsNotLikeCaseInsensitive<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsNotLikeCaseInsensitive::empty, this); } @Override - public <R> IsNotLikeCaseInsensitive<R> map(Function<? super T, ? extends R> mapper) { + public <R> IsNotLikeCaseInsensitive<R> map(Function<? super @NonNull T, ? extends @NonNull R> mapper) { return mapSupport(mapper, IsNotLikeCaseInsensitive::new, IsNotLikeCaseInsensitive::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitiveWhenPresent.java index 891525295..e1e17f9da 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitiveWhenPresent.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; @@ -54,12 +55,12 @@ public String operator() { } @Override - public IsNotLikeCaseInsensitiveWhenPresent<T> filter(Predicate<? super T> predicate) { + public IsNotLikeCaseInsensitiveWhenPresent<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsNotLikeCaseInsensitiveWhenPresent::empty, this); } @Override - public <R> IsNotLikeCaseInsensitiveWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + public <R> IsNotLikeCaseInsensitiveWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper) { return mapSupport(mapper, IsNotLikeCaseInsensitiveWhenPresent::of, IsNotLikeCaseInsensitiveWhenPresent::empty); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeWhenPresent.java index d018c9062..a3571b0ee 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeWhenPresent.java @@ -19,6 +19,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.jspecify.annotations.NonNull; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; @@ -60,12 +61,12 @@ public static <T> IsNotLikeWhenPresent<T> of(@Nullable T value) { } @Override - public IsNotLikeWhenPresent<T> filter(Predicate<? super T> predicate) { + public IsNotLikeWhenPresent<T> filter(Predicate<? super @NonNull T> predicate) { return filterSupport(predicate, IsNotLikeWhenPresent::empty, this); } @Override - public <R> IsNotLikeWhenPresent<R> map(Function<? super T, ? extends @Nullable R> mapper) { + public <R> IsNotLikeWhenPresent<R> map(Function<? super @NonNull T, ? extends @Nullable R> mapper) { return mapSupport(mapper, IsNotLikeWhenPresent::of, IsNotLikeWhenPresent::empty); } } diff --git a/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java b/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java index a46190941..89d349825 100644 --- a/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java +++ b/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java @@ -30,7 +30,6 @@ import java.sql.Connection; import java.sql.DriverManager; import java.util.List; -import java.util.Objects; import org.apache.ibatis.datasource.unpooled.UnpooledDataSource; import org.apache.ibatis.jdbc.ScriptRunner; @@ -44,7 +43,6 @@ import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.render.RenderingStrategies; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; -import org.mybatis.dynamic.sql.util.Predicates; class OptionalConditionsWithPredicatesAnimalDataTest { @@ -78,7 +76,7 @@ void testAllIgnored() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isGreaterThan(NULL_INTEGER).filter(Objects::nonNull)) // the where clause should not render + .where(id, isGreaterThanWhenPresent(NULL_INTEGER)) // the where clause should not render .orderBy(id) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() @@ -93,26 +91,6 @@ void testAllIgnored() { } } - @Test - void testSelectByNull() { - // this method demonstrates that ignoring the null value warning will still work - try (SqlSession sqlSession = sqlSessionFactory.openSession()) { - AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); - SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) - .from(animalData) - .where(id, isGreaterThan(NULL_INTEGER)) // should be an IDE warning about passing null to a nonnull method - .orderBy(id) - .build() - .render(RenderingStrategies.MYBATIS3); - List<AnimalData> animals = mapper.selectMany(selectStatement); - assertAll( - () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id > #{parameters.p1,jdbcType=INTEGER} order by id"), - () -> assertThat(selectStatement.getParameters()).containsEntry("p1", null), - () -> assertThat(animals).isEmpty() - ); - } - } - @Test void testIgnoredBetweenRendered() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { @@ -120,8 +98,8 @@ void testIgnoredBetweenRendered() { SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) .where(id, isEqualTo(3)) - .and(id, isNotEqualTo(NULL_INTEGER).filter(Objects::nonNull)) - .or(id, isEqualTo(4).filter(Objects::nonNull)) + .and(id, isNotEqualToWhenPresent(NULL_INTEGER)) + .or(id, isEqualTo(4)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -141,9 +119,9 @@ void testIgnoredInWhere() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull)) - .and(id, isEqualTo(3).filter(Objects::nonNull)) - .or(id, isEqualTo(4).filter(Objects::nonNull)) + .where(id, isLessThanWhenPresent(NULL_INTEGER)) + .and(id, isEqualTo(3)) + .or(id, isEqualTo(4)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -163,10 +141,10 @@ void testManyIgnored() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull), and(id, isGreaterThanOrEqualTo(NULL_INTEGER).filter(Objects::nonNull))) - .and(id, isEqualTo(NULL_INTEGER).filter(Objects::nonNull), or(id, isEqualTo(3), and(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull)))) - .or(id, isEqualTo(4).filter(Objects::nonNull), and(id, isGreaterThanOrEqualTo(NULL_INTEGER).filter(Objects::nonNull))) - .and(id, isNotEqualTo(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isLessThanWhenPresent(NULL_INTEGER), and(id, isGreaterThanOrEqualToWhenPresent(NULL_INTEGER))) + .and(id, isEqualToWhenPresent(NULL_INTEGER), or(id, isEqualTo(3), and(id, isLessThanWhenPresent(NULL_INTEGER)))) + .or(id, isEqualTo(4), and(id, isGreaterThanOrEqualToWhenPresent(NULL_INTEGER))) + .and(id, isNotEqualToWhenPresent(NULL_INTEGER)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -186,8 +164,8 @@ void testIgnoredInitialWhere() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull), and(id, isEqualTo(3).filter(Objects::nonNull))) - .or(id, isEqualTo(4).filter(Objects::nonNull)) + .where(id, isLessThanWhenPresent(NULL_INTEGER), and(id, isEqualTo(3))) + .or(id, isEqualTo(4)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -207,7 +185,7 @@ void testEqualWhenWithValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isEqualTo(4).filter(Objects::nonNull)) + .where(id, isEqualTo(4)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -226,7 +204,7 @@ void testEqualWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isEqualTo(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isEqualToWhenPresent(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -246,7 +224,7 @@ void testNotEqualWhenWithValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isNotEqualTo(4).filter(Objects::nonNull)) + .where(id, isNotEqualTo(4)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -266,7 +244,7 @@ void testNotEqualWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isNotEqualTo(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isNotEqualToWhenPresent(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -286,7 +264,7 @@ void testGreaterThanWhenWithValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isGreaterThan(4).filter(Objects::nonNull)) + .where(id, isGreaterThan(4)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -306,7 +284,7 @@ void testGreaterThanWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isGreaterThan(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isGreaterThanWhenPresent(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -326,7 +304,7 @@ void testGreaterThanOrEqualToWhenWithValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isGreaterThanOrEqualTo(4).filter(Objects::nonNull)) + .where(id, isGreaterThanOrEqualTo(4)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -346,7 +324,7 @@ void testGreaterThanOrEqualToWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isGreaterThanOrEqualTo(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isGreaterThanOrEqualToWhenPresent(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -366,7 +344,7 @@ void testLessThanWhenWithValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThan(4).filter(Objects::nonNull)) + .where(id, isLessThan(4)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -385,7 +363,7 @@ void testLessThanWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThan(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isLessThanWhenPresent(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -405,7 +383,7 @@ void testLessThanOrEqualToWhenWithValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThanOrEqualTo(4).filter(Objects::nonNull)) + .where(id, isLessThanOrEqualTo(4)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -424,7 +402,7 @@ void testLessThanOrEqualToWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThanOrEqualTo(NULL_INTEGER).filter(Objects::nonNull)) + .where(id, isLessThanOrEqualToWhenPresent(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -463,7 +441,7 @@ void testIsInWhenWithSomeValues() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isIn(3, NULL_INTEGER, 5).filter(Objects::nonNull).map(i -> i + 3)) + .where(id, isInWhenPresent(3, NULL_INTEGER, 5).map(i -> i + 3)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -502,8 +480,7 @@ void testValueStreamTransformer() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isIn(" Mouse", " ", null, "", "Musk shrew ") - .filter(Objects::nonNull) + .where(animalName, isInWhenPresent(" Mouse", " ", null, "", "Musk shrew ") .map(String::trim) .filter(not(String::isEmpty))) .orderBy(id) @@ -583,7 +560,7 @@ void testIsNotInWhenWithSomeValues() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isNotIn(3, NULL_INTEGER, 5).filter(Objects::nonNull)) + .where(id, isNotInWhenPresent(3, NULL_INTEGER, 5)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -643,7 +620,7 @@ void testIsBetweenWhenWithValues() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isBetween(3).and(6).filter(Predicates.bothPresent())) + .where(id, isBetween(3).and(6)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -662,7 +639,7 @@ void testIsBetweenWhenWithFirstMissing() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isBetween(NULL_INTEGER).and(6).filter(Predicates.bothPresent())) + .where(id, isBetweenWhenPresent(NULL_INTEGER).and(6)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -682,7 +659,7 @@ void testIsBetweenWhenWithSecondMissing() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isBetween(3).and(NULL_INTEGER).filter(Predicates.bothPresent())) + .where(id, isBetweenWhenPresent(3).and(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -702,7 +679,7 @@ void testIsBetweenWhenWithBothMissing() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isBetween(NULL_INTEGER).and(NULL_INTEGER).filter(Predicates.bothPresent())) + .where(id, isBetweenWhenPresent(NULL_INTEGER).and(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -722,7 +699,7 @@ void testIsNotBetweenWhenWithValues() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isNotBetween(3).and(6).filter(Predicates.bothPresent())) + .where(id, isNotBetween(3).and(6)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -742,7 +719,7 @@ void testIsNotBetweenWhenWithFirstMissing() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isNotBetween(NULL_INTEGER).and(6).filter(Predicates.bothPresent())) + .where(id, isNotBetweenWhenPresent(NULL_INTEGER).and(6)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -762,7 +739,7 @@ void testIsNotBetweenWhenWithSecondMissing() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isNotBetween(3).and(NULL_INTEGER).filter(Predicates.bothPresent())) + .where(id, isNotBetweenWhenPresent(3).and(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -782,7 +759,7 @@ void testIsNotBetweenWhenWithBothMissing() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isNotBetween(NULL_INTEGER).and(NULL_INTEGER).filter(Predicates.bothPresent())) + .where(id, isNotBetweenWhenPresent(NULL_INTEGER).and(NULL_INTEGER)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -802,7 +779,7 @@ void testIsLikeWhenWithValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isLike("%mole").filter(Objects::nonNull)) + .where(animalName, isLike("%mole")) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -822,7 +799,7 @@ void testIsLikeWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isLike((String) null).filter(Objects::nonNull)) + .where(animalName, isLikeWhenPresent((String) null)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -842,7 +819,7 @@ void testIsLikeCaseInsensitiveWhenWithValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isLikeCaseInsensitive("%MoLe").filter(Objects::nonNull)) + .where(animalName, isLikeCaseInsensitive("%MoLe")) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -862,7 +839,7 @@ void testIsLikeCaseInsensitiveWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isLikeCaseInsensitive((String) null).filter(Objects::nonNull)) + .where(animalName, isLikeCaseInsensitiveWhenPresent((String) null)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -882,7 +859,7 @@ void testIsNotLikeWhenWithValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isNotLike("%mole").filter(Objects::nonNull)) + .where(animalName, isNotLike("%mole")) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -902,7 +879,7 @@ void testIsNotLikeWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isNotLike((String) null).filter(Objects::nonNull)) + .where(animalName, isNotLikeWhenPresent((String) null)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -922,7 +899,7 @@ void testIsNotLikeCaseInsensitiveWhenWithValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isNotLikeCaseInsensitive("%MoLe").filter(Objects::nonNull)) + .where(animalName, isNotLikeCaseInsensitive("%MoLe")) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -942,7 +919,7 @@ void testIsNotLikeCaseInsensitiveWhenWithoutValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isNotLikeCaseInsensitive((String) null).filter(Objects::nonNull)) + .where(animalName, isNotLikeCaseInsensitiveWhenPresent((String) null)) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() diff --git a/src/test/java/examples/complexquery/ComplexQueryTest.java b/src/test/java/examples/complexquery/ComplexQueryTest.java index fca43c133..3912040cb 100644 --- a/src/test/java/examples/complexquery/ComplexQueryTest.java +++ b/src/test/java/examples/complexquery/ComplexQueryTest.java @@ -22,8 +22,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mybatis.dynamic.sql.SqlBuilder.*; -import java.util.Objects; - +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.render.RenderingStrategies; import org.mybatis.dynamic.sql.select.QueryExpressionDSL; @@ -107,18 +106,17 @@ void testAllNull() { assertThat(selectStatement.getParameters()).containsEntry("p1", 50L); } - SelectStatementProvider search(Integer targetId, String fName, String lName) { + SelectStatementProvider search(@Nullable Integer targetId, @Nullable String fName, @Nullable String lName) { QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder builder = select(id, firstName, lastName) .from(person) .where() .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)); if (targetId != null) { - builder - .and(id, isEqualTo(targetId)); + builder.and(id, isEqualTo(targetId)); } else { builder - .and(firstName, isLike(fName).filter(Objects::nonNull).map(s -> "%" + s + "%")) + .and(firstName, isLikeWhenPresent(fName).map(s -> "%" + s + "%")) .and(lastName, isLikeWhenPresent(lName).map(this::addWildcards)); } diff --git a/src/test/java/examples/emptywhere/EmptyWhereTest.java b/src/test/java/examples/emptywhere/EmptyWhereTest.java index 4c02f4f66..fd699da23 100644 --- a/src/test/java/examples/emptywhere/EmptyWhereTest.java +++ b/src/test/java/examples/emptywhere/EmptyWhereTest.java @@ -20,7 +20,8 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mybatis.dynamic.sql.SqlBuilder.*; -import java.util.*; +import java.util.List; +import java.util.Optional; import java.util.stream.Stream; import org.junit.jupiter.api.Test; @@ -93,8 +94,8 @@ void testDeleteThreeConditions() { DeleteDSL<DeleteModel>.DeleteWhereBuilder builder = deleteFrom(person) .where(id, isEqualTo(3)); - builder.and(firstName, isEqualTo(fName).filter(Objects::nonNull)); - builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(lName).filter(Objects::nonNull)); + builder.and(firstName, isEqualTo(fName)); + builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(lName)); DeleteStatementProvider deleteStatement = builder.build().render(RenderingStrategies.MYBATIS3); @@ -112,8 +113,8 @@ void testDeleteVariations(Variation variation) { DeleteDSL<DeleteModel>.DeleteWhereBuilder builder = deleteFrom(person) .where(); - builder.and(firstName, isEqualTo(variation.firstName).filter(Objects::nonNull)); - builder.or(PersonDynamicSqlSupport.lastName, isEqualTo(variation.lastName).filter(Objects::nonNull)); + builder.and(firstName, isEqualToWhenPresent(variation.firstName)); + builder.or(PersonDynamicSqlSupport.lastName, isEqualToWhenPresent(variation.lastName)); builder.configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)); DeleteStatementProvider deleteStatement = builder.build().render(RenderingStrategies.MYBATIS3); @@ -132,8 +133,8 @@ void testSelectThreeConditions() { .from(person) .where(id, isEqualTo(3)); - builder.and(firstName, isEqualTo(fName).filter(Objects::nonNull)); - builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(lName).filter(Objects::nonNull)); + builder.and(firstName, isEqualTo(fName)); + builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(lName)); SelectStatementProvider selectStatement = builder.build().render(RenderingStrategies.MYBATIS3); @@ -153,8 +154,8 @@ void testSelectVariations(Variation variation) { .from(person) .where(); - builder.and(firstName, isEqualTo(variation.firstName).filter(Objects::nonNull)); - builder.or(PersonDynamicSqlSupport.lastName, isEqualTo(variation.lastName).filter(Objects::nonNull)); + builder.and(firstName, isEqualToWhenPresent(variation.firstName)); + builder.or(PersonDynamicSqlSupport.lastName, isEqualToWhenPresent(variation.lastName)); builder.configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)); SelectStatementProvider selectStatement = builder.build().render(RenderingStrategies.MYBATIS3); @@ -173,8 +174,8 @@ void testJoinThreeConditions() { .from(person).join(order).on(person.id, isEqualTo(order.personId)) .where(id, isEqualTo(3)); - builder.and(firstName, isEqualTo(fName).filter(Objects::nonNull)); - builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(lName).filter(Objects::nonNull)); + builder.and(firstName, isEqualTo(fName)); + builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(lName)); SelectStatementProvider selectStatement = builder.build().render(RenderingStrategies.MYBATIS3); @@ -195,8 +196,8 @@ void testJoinVariations(Variation variation) { .from(person).join(order).on(person.id, isEqualTo(order.personId)) .where(); - builder.and(firstName, isEqualTo(variation.firstName).filter(Objects::nonNull)); - builder.or(PersonDynamicSqlSupport.lastName, isEqualTo(variation.lastName).filter(Objects::nonNull)); + builder.and(firstName, isEqualToWhenPresent(variation.firstName)); + builder.or(PersonDynamicSqlSupport.lastName, isEqualToWhenPresent(variation.lastName)); builder.configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)); SelectStatementProvider selectStatement = builder.build().render(RenderingStrategies.MYBATIS3); @@ -218,8 +219,8 @@ void testUpdateThreeConditions() { .set(id).equalTo(3) .where(id, isEqualTo(3)); - builder.and(firstName, isEqualTo(fName).filter(Objects::nonNull)); - builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(lName).filter(Objects::nonNull)); + builder.and(firstName, isEqualTo(fName)); + builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(lName)); UpdateStatementProvider updateStatement = builder.build().render(RenderingStrategies.MYBATIS3); @@ -239,8 +240,8 @@ void testUpdateVariations(Variation variation) { .set(id).equalTo(3) .where(); - builder.and(firstName, isEqualTo(variation.firstName).filter(Objects::nonNull)); - builder.or(PersonDynamicSqlSupport.lastName, isEqualTo(variation.lastName).filter(Objects::nonNull)); + builder.and(firstName, isEqualToWhenPresent(variation.firstName)); + builder.or(PersonDynamicSqlSupport.lastName, isEqualToWhenPresent(variation.lastName)); builder.configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)); UpdateStatementProvider updateStatement = builder.build().render(RenderingStrategies.MYBATIS3); @@ -259,8 +260,8 @@ void testWhereThreeConditions() { WhereDSL.StandaloneWhereFinisher builder = where(id, isEqualTo(3)); - builder.and(firstName, isEqualTo(fName).filter(Objects::nonNull)); - builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(lName).filter(Objects::nonNull)); + builder.and(firstName, isEqualTo(fName)); + builder.and(PersonDynamicSqlSupport.lastName, isEqualTo(lName)); Optional<WhereClauseProvider> whereClause = builder.build().render(RenderingStrategies.MYBATIS3); @@ -278,8 +279,8 @@ void testWhereThreeConditions() { void testWhereVariations(Variation variation) { WhereDSL.StandaloneWhereFinisher builder = where(); - builder.and(firstName, isEqualTo(variation.firstName).filter(Objects::nonNull)); - builder.or(PersonDynamicSqlSupport.lastName, isEqualTo(variation.lastName).filter(Objects::nonNull)); + builder.and(firstName, isEqualToWhenPresent(variation.firstName)); + builder.or(PersonDynamicSqlSupport.lastName, isEqualToWhenPresent(variation.lastName)); builder.configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)); Optional<WhereClauseProvider> whereClause = builder.build().render(RenderingStrategies.MYBATIS3); diff --git a/src/test/java/examples/simple/PersonMapperTest.java b/src/test/java/examples/simple/PersonMapperTest.java index 7aed9182d..acbda68ad 100644 --- a/src/test/java/examples/simple/PersonMapperTest.java +++ b/src/test/java/examples/simple/PersonMapperTest.java @@ -36,7 +36,6 @@ import java.util.Collection; import java.util.Date; import java.util.List; -import java.util.Objects; import java.util.Optional; import org.apache.ibatis.datasource.unpooled.UnpooledDataSource; @@ -146,7 +145,7 @@ void testSelectWithTypeConversionAndFilterAndNull() { PersonMapper mapper = session.getMapper(PersonMapper.class); List<PersonRecord> rows = mapper.select(c -> - c.where(id, isEqualTo((String) null).filter(Objects::nonNull).map(Integer::parseInt)) + c.where(id, isEqualToWhenPresent((String) null).map(Integer::parseInt)) .or(occupation, isNull())); assertThat(rows).hasSize(2); diff --git a/src/test/java/issues/gh105/Issue105Test.java b/src/test/java/issues/gh105/Issue105Test.java index 8fb16f22d..81ecb79c2 100644 --- a/src/test/java/issues/gh105/Issue105Test.java +++ b/src/test/java/issues/gh105/Issue105Test.java @@ -19,12 +19,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mybatis.dynamic.sql.SqlBuilder.*; -import java.util.Objects; - import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.render.RenderingStrategies; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; -import org.mybatis.dynamic.sql.util.Predicates; class Issue105Test { @@ -35,8 +32,8 @@ void testFuzzyLikeBothPresent() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(firstName, isLike(fName).filter(Objects::nonNull).map(s -> "%" + s + "%")) - .and(lastName, isLike(lName).filter(Objects::nonNull).map(s -> "%" + s + "%")) + .where(firstName, isLike(fName).map(s -> "%" + s + "%")) + .and(lastName, isLike(lName).map(s -> "%" + s + "%")) .build() .render(RenderingStrategies.MYBATIS3); @@ -57,8 +54,8 @@ void testFuzzyLikeFirstNameNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(firstName, isLike(fName).filter(Objects::nonNull).map(SearchUtils::addWildcards)) - .and(lastName, isLike(lName).filter(Objects::nonNull).map(SearchUtils::addWildcards)) + .where(firstName, isLikeWhenPresent(fName).map(SearchUtils::addWildcards)) + .and(lastName, isLike(lName).map(SearchUtils::addWildcards)) .build() .render(RenderingStrategies.MYBATIS3); @@ -77,8 +74,8 @@ void testFuzzyLikeLastNameNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(firstName, isLike(fName).filter(Objects::nonNull).map(SearchUtils::addWildcards)) - .and(lastName, isLike(lName).filter(Objects::nonNull).map(SearchUtils::addWildcards)) + .where(firstName, isLike(fName).map(SearchUtils::addWildcards)) + .and(lastName, isLikeWhenPresent(lName).map(SearchUtils::addWildcards)) .build() .render(RenderingStrategies.MYBATIS3); @@ -97,8 +94,8 @@ void testFuzzyLikeBothNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(firstName, isLike(fName).filter(Objects::nonNull).map(SearchUtils::addWildcards)) - .and(lastName, isLike(lName).filter(Objects::nonNull).map(SearchUtils::addWildcards)) + .where(firstName, isLikeWhenPresent(fName).map(SearchUtils::addWildcards)) + .and(lastName, isLikeWhenPresent(lName).map(SearchUtils::addWildcards)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); @@ -527,7 +524,7 @@ void testBetweenTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(age, isBetween(1).and((Integer) null).filter(Predicates.bothPresent()).map(i1 -> i1 + 1, i2 -> i2 + 2)) + .where(age, isBetweenWhenPresent(1).and((Integer) null).map(i1 -> i1 + 1, i2 -> i2 + 2)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); @@ -559,7 +556,7 @@ void testEqualTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(age, isEqualTo((Integer) null).filter(Objects::nonNull).map(i -> i + 1)) + .where(age, isEqualToWhenPresent((Integer) null).map(i -> i + 1)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); @@ -591,7 +588,7 @@ void testGreaterThanTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(age, isGreaterThan((Integer) null).filter(Objects::nonNull).map(i -> i + 1)) + .where(age, isGreaterThanWhenPresent((Integer) null).map(i -> i + 1)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); @@ -607,7 +604,7 @@ void testGreaterThanOrEqualTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(age, isGreaterThanOrEqualTo((Integer) null).filter(Objects::nonNull).map(i -> i + 1)) + .where(age, isGreaterThanOrEqualToWhenPresent((Integer) null).map(i -> i + 1)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); @@ -655,7 +652,7 @@ void testLessThanTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(age, isLessThan((Integer) null).filter(Objects::nonNull).map(i -> i + 1)) + .where(age, isLessThanWhenPresent((Integer) null).map(i -> i + 1)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); @@ -671,7 +668,7 @@ void testLessThanOrEqualTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(age, isLessThanOrEqualTo((Integer) null).filter(Objects::nonNull).map(i -> i + 1)) + .where(age, isLessThanOrEqualToWhenPresent((Integer) null).map(i -> i + 1)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); @@ -719,7 +716,7 @@ void testLikeTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(firstName, isLike((String) null).filter(Objects::nonNull).map(SearchUtils::addWildcards)) + .where(firstName, isLikeWhenPresent((String) null).map(SearchUtils::addWildcards)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); @@ -735,7 +732,7 @@ void testLikeCaseInsensitiveTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(firstName, isLikeCaseInsensitive((String) null).filter(Objects::nonNull).map(SearchUtils::addWildcards)) + .where(firstName, isLikeCaseInsensitiveWhenPresent((String) null).map(SearchUtils::addWildcards)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); @@ -783,7 +780,7 @@ void testNotBetweenTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(age, isNotBetween((Integer) null).and(10).filter(Predicates.bothPresent()).map(i1 -> i1 + 1, i2 -> i2 + 2)) + .where(age, isNotBetweenWhenPresent((Integer) null).and(10).map(i1 -> i1 + 1, i2 -> i2 + 2)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); @@ -815,7 +812,7 @@ void testNotEqualTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(age, isNotEqualTo((Integer) null).filter(Objects::nonNull).map(i -> i + 1)) + .where(age, isNotEqualToWhenPresent((Integer) null).map(i -> i + 1)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); @@ -847,7 +844,7 @@ void testNotLikeTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(firstName, isNotLike((String) null).filter(Objects::nonNull).map(SearchUtils::addWildcards)) + .where(firstName, isNotLikeWhenPresent((String) null).map(SearchUtils::addWildcards)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); @@ -863,7 +860,7 @@ void testNotLikeCaseInsensitiveTransformWithNull() { SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(firstName, isNotLikeCaseInsensitive((String) null).filter(Objects::nonNull).map(SearchUtils::addWildcards)) + .where(firstName, isNotLikeCaseInsensitiveWhenPresent((String) null).map(SearchUtils::addWildcards)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java index bd2e56fbb..a3bb3d620 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.NoSuchElementException; -import java.util.Objects; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.SqlBuilder; @@ -33,17 +32,9 @@ void testTypeConversion() { assertThat(cond.value()).isEqualTo(1); } - @Test - void testTypeConversionWithNullThrowsException() { - var cond = SqlBuilder.isEqualTo((String) null); - assertThatExceptionOfType(NumberFormatException.class).isThrownBy(() -> - cond.map(Integer::parseInt) - ); - } - @Test void testTypeConversionWithNullAndFilterDoesNotThrowException() { - var cond = SqlBuilder.isEqualTo((String) null).filter(Objects::nonNull).map(Integer::parseInt); + var cond = SqlBuilder.isEqualToWhenPresent((String) null).map(Integer::parseInt); assertThat(cond.isEmpty()).isTrue(); } @@ -479,17 +470,17 @@ void testBetweenUnRenderableFilterShouldReturnSameObject() { @Test void testBetweenUnRenderableFirstNullFilterShouldReturnSameObject() { - IsBetween<Integer> cond = SqlBuilder.isBetween((Integer) null).and(4).filter(Objects::nonNull); + IsBetweenWhenPresent<Integer> cond = SqlBuilder.isBetweenWhenPresent((Integer) null).and(4); assertThat(cond.isEmpty()).isTrue(); - IsBetween<Integer> filtered = cond.filter(v -> true); + IsBetweenWhenPresent<Integer> filtered = cond.filter(v -> true); assertThat(cond).isSameAs(filtered); } @Test void testBetweenUnRenderableSecondNullFilterShouldReturnSameObject() { - IsBetween<Integer> cond = SqlBuilder.isBetween(3).and((Integer) null).filter(Objects::nonNull); + IsBetweenWhenPresent<Integer> cond = SqlBuilder.isBetweenWhenPresent(3).and((Integer) null); assertThat(cond.isEmpty()).isTrue(); - IsBetween<Integer> filtered = cond.filter(v -> true); + IsBetweenWhenPresent<Integer> filtered = cond.filter(v -> true); assertThat(cond).isSameAs(filtered); } @@ -511,17 +502,17 @@ void testNotBetweenUnRenderableFilterShouldReturnSameObject() { @Test void testNotBetweenUnRenderableFirstNullFilterShouldReturnSameObject() { - IsNotBetween<Integer> cond = SqlBuilder.isNotBetween((Integer) null).and(4).filter(Objects::nonNull); + IsNotBetweenWhenPresent<Integer> cond = SqlBuilder.isNotBetweenWhenPresent((Integer) null).and(4); assertThat(cond.isEmpty()).isTrue(); - IsNotBetween<Integer> filtered = cond.filter(v -> true); + IsNotBetweenWhenPresent<Integer> filtered = cond.filter(v -> true); assertThat(cond).isSameAs(filtered); } @Test void testNotBetweenUnRenderableSecondNullFilterShouldReturnSameObject() { - IsNotBetween<Integer> cond = SqlBuilder.isNotBetween(3).and((Integer) null).filter(Objects::nonNull); + IsNotBetweenWhenPresent<Integer> cond = SqlBuilder.isNotBetweenWhenPresent(3).and((Integer) null); assertThat(cond.isEmpty()).isTrue(); - IsNotBetween<Integer> filtered = cond.filter(v -> true); + IsNotBetweenWhenPresent<Integer> filtered = cond.filter(v -> true); assertThat(cond).isSameAs(filtered); } diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java index 6ea7b2909..ed7d4e01c 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java @@ -438,4 +438,94 @@ void testIsNotInCaseInsensitiveWhenPresent() { assertThat(mapped.isEmpty()).isTrue(); assertThat(mapped.values().toList()).isEmpty(); } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsBetweenNull() { + IsBetween<Integer> cond = SqlBuilder.isBetween(() -> (Integer) null).and(() -> null); + assertThat(cond.value1()).isNull(); + assertThat(cond.value2()).isNull(); + assertThat(cond.isEmpty()).isFalse(); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsNotBetweenNull() { + IsNotBetween<Integer> cond = SqlBuilder.isNotBetween(() -> (Integer) null).and(() -> null); + assertThat(cond.value1()).isNull(); + assertThat(cond.value2()).isNull(); + assertThat(cond.isEmpty()).isFalse(); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsNotEqualToNull() { + IsNotEqualTo<Integer> cond = SqlBuilder.isNotEqualTo(() -> (Integer) null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsGreaterThanNull() { + IsGreaterThan<Integer> cond = SqlBuilder.isGreaterThan(() -> (Integer) null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsGreaterThanOrEqualToNull() { + IsGreaterThanOrEqualTo<Integer> cond = SqlBuilder.isGreaterThanOrEqualTo(() -> (Integer) null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsLessThanNull() { + IsLessThan<Integer> cond = SqlBuilder.isLessThan(() -> (Integer) null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsLessThanOrEqualToNull() { + IsLessThanOrEqualTo<Integer> cond = SqlBuilder.isLessThanOrEqualTo(() -> (Integer) null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsLikeNull() { + IsLike<String> cond = SqlBuilder.isLike(() -> null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsLikeCaseInsensitiveNull() { + IsLikeCaseInsensitive<String> cond = SqlBuilder.isLikeCaseInsensitive(() -> null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsNotLikeNull() { + IsNotLike<String> cond = SqlBuilder.isNotLike(() -> null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); + } + + @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing + @Test + void testIsNotLikeCaseInsensitiveNull() { + IsNotLikeCaseInsensitive<String> cond = SqlBuilder.isNotLikeCaseInsensitive(() -> null); + assertThat(cond.value()).isNull(); + assertThat(cond.isEmpty()).isFalse(); + } } diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java index c2bf40ddf..113c60321 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/SupplierTest.java @@ -34,14 +34,6 @@ void testIsBetween() { assertThat(cond.isEmpty()).isFalse(); } - @Test - void testIsBetweenNull() { - IsBetween<Integer> cond = SqlBuilder.isBetween(() -> (Integer) null).and(() -> null); - assertThat(cond.value1()).isNull(); - assertThat(cond.value2()).isNull(); - assertThat(cond.isEmpty()).isFalse(); - } - @Test void testIsBetweenWhenPresent() { IsBetweenWhenPresent<Integer> cond = SqlBuilder.isBetweenWhenPresent(() -> 3).and(() -> 4); @@ -66,14 +58,6 @@ void testIsNotBetween() { assertThat(cond.isEmpty()).isFalse(); } - @Test - void testIsNotBetweenNull() { - IsNotBetween<Integer> cond = SqlBuilder.isNotBetween(() -> (Integer) null).and(() -> null); - assertThat(cond.value1()).isNull(); - assertThat(cond.value2()).isNull(); - assertThat(cond.isEmpty()).isFalse(); - } - @Test void testIsNotBetweenWhenPresent() { IsNotBetweenWhenPresent<Integer> cond = SqlBuilder.isNotBetweenWhenPresent(() -> 3).and(() -> 4); @@ -111,13 +95,6 @@ void testIsNotEqualTo() { assertThat(cond.isEmpty()).isFalse(); } - @Test - void testIsNotEqualToNull() { - IsNotEqualTo<Integer> cond = SqlBuilder.isNotEqualTo(() -> (Integer) null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); - } - @Test void testIsNotEqualToWhenPresent() { IsNotEqualToWhenPresent<Integer> cond = SqlBuilder.isNotEqualToWhenPresent(() -> 3); @@ -139,13 +116,6 @@ void testIsGreaterThan() { assertThat(cond.isEmpty()).isFalse(); } - @Test - void testIsGreaterThanNull() { - IsGreaterThan<Integer> cond = SqlBuilder.isGreaterThan(() -> (Integer) null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); - } - @Test void testIsGreaterThanWhenPresent() { IsGreaterThanWhenPresent<Integer> cond = SqlBuilder.isGreaterThanWhenPresent(() -> 3); @@ -167,13 +137,6 @@ void testIsGreaterThanOrEqualTo() { assertThat(cond.isEmpty()).isFalse(); } - @Test - void testIsGreaterThanOrEqualToNull() { - IsGreaterThanOrEqualTo<Integer> cond = SqlBuilder.isGreaterThanOrEqualTo(() -> (Integer) null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); - } - @Test void testIsGreaterThanOrEqualToWhenPresent() { IsGreaterThanOrEqualToWhenPresent<Integer> cond = SqlBuilder.isGreaterThanOrEqualToWhenPresent(() -> 3); @@ -195,13 +158,6 @@ void testIsLessThan() { assertThat(cond.isEmpty()).isFalse(); } - @Test - void testIsLessThanNull() { - IsLessThan<Integer> cond = SqlBuilder.isLessThan(() -> (Integer) null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); - } - @Test void testIsLessThanWhenPresent() { IsLessThanWhenPresent<Integer> cond = SqlBuilder.isLessThanWhenPresent(() -> 3); @@ -223,13 +179,6 @@ void testIsLessThanOrEqualTo() { assertThat(cond.isEmpty()).isFalse(); } - @Test - void testIsLessThanOrEqualToNull() { - IsLessThanOrEqualTo<Integer> cond = SqlBuilder.isLessThanOrEqualTo(() -> (Integer) null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); - } - @Test void testIsLessThanOrEqualToWhenPresent() { IsLessThanOrEqualToWhenPresent<Integer> cond = SqlBuilder.isLessThanOrEqualToWhenPresent(() -> 3); @@ -251,13 +200,6 @@ void testIsLike() { assertThat(cond.isEmpty()).isFalse(); } - @Test - void testIsLikeNull() { - IsLike<String> cond = SqlBuilder.isLike(() -> null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); - } - @Test void testIsLikeCaseInsensitive() { IsLikeCaseInsensitive<String> cond = SqlBuilder.isLikeCaseInsensitive(() -> "%f%"); @@ -265,13 +207,6 @@ void testIsLikeCaseInsensitive() { assertThat(cond.isEmpty()).isFalse(); } - @Test - void testIsLikeCaseInsensitiveNull() { - IsLikeCaseInsensitive<String> cond = SqlBuilder.isLikeCaseInsensitive(() -> null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); - } - @Test void testIsLikeCaseInsensitiveWhenPresent() { IsLikeCaseInsensitiveWhenPresent<String> cond = SqlBuilder.isLikeCaseInsensitiveWhenPresent(() -> "%f%"); @@ -307,13 +242,6 @@ void testIsNotLike() { assertThat(cond.isEmpty()).isFalse(); } - @Test - void testIsNotLikeNull() { - IsNotLike<String> cond = SqlBuilder.isNotLike(() -> null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); - } - @Test void testIsNotLikeWhenPresent() { IsNotLikeWhenPresent<String> cond = SqlBuilder.isNotLikeWhenPresent(() -> "%F%"); @@ -335,13 +263,6 @@ void testIsNotLikeCaseInsensitive() { assertThat(cond.isEmpty()).isFalse(); } - @Test - void testIsNotLikeCaseInsensitiveNull() { - IsNotLikeCaseInsensitive<String> cond = SqlBuilder.isNotLikeCaseInsensitive(() -> null); - assertThat(cond.value()).isNull(); - assertThat(cond.isEmpty()).isFalse(); - } - @Test void testIsNotLikeCaseInsensitiveWhenPresent() { IsNotLikeCaseInsensitiveWhenPresent<String> cond = SqlBuilder.isNotLikeCaseInsensitiveWhenPresent(() -> "%f%"); 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 1e6e56a92..25ea36a3e 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 @@ -19,7 +19,6 @@ import static org.assertj.core.api.Assertions.entry; import static org.mybatis.dynamic.sql.SqlBuilder.*; -import java.util.Objects; import java.util.Optional; import org.junit.jupiter.api.Test; @@ -49,7 +48,7 @@ void testNoRenderableCriteria() { void testNoRenderableCriteriaWithIf() { Integer nullId = null; - Optional<WhereClauseProvider> whereClause = where(id, isEqualTo(nullId).filter(Objects::nonNull)) + Optional<WhereClauseProvider> whereClause = where(id, isEqualToWhenPresent(nullId)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.SPRING_NAMED_PARAMETER); From 384c758b0b865033d44df8eb8ad87470be64fcdd Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 7 Apr 2025 11:34:55 -0400 Subject: [PATCH 237/260] Licensing --- .../sql/where/condition/NullContractTest.java | 15 +++++++++++++++ .../kotlin/mybatis3/mariadb/KIsLikeEscape.kt | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java index ed7d4e01c..17b96973e 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java @@ -1,3 +1,18 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.where.condition; import static org.assertj.core.api.Assertions.assertThat; diff --git a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt index b47f09110..6746dc03e 100644 --- a/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt +++ b/src/test/kotlin/examples/kotlin/mybatis3/mariadb/KIsLikeEscape.kt @@ -1,3 +1,18 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.kotlin.mybatis3.mariadb import java.util.function.Predicate From a781f6ae35d62b0cbf992eb9ceccd5d8ed44ecd1 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 7 Apr 2025 12:36:02 -0400 Subject: [PATCH 238/260] Sonar should talk to localhost by default --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index cad1ea0b9..2f37f9c03 100644 --- a/pom.xml +++ b/pom.xml @@ -76,6 +76,8 @@ <sonar.sources>pom.xml,src/main/java,src/main/kotlin</sonar.sources> <sonar.tests>src/test/java,src/test/kotlin</sonar.tests> + <!-- setup sonar to run locally by default --> + <sonar.host.url>http://localhost:9000</sonar.host.url> <kotlin.code.style>official</kotlin.code.style> <test.containers.version>1.20.6</test.containers.version> From 428fc915dd94cfe8e162d75b2e0c4fb22698769f Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 7 Apr 2025 12:36:27 -0400 Subject: [PATCH 239/260] Checkstyle --- .../java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java | 3 ++- .../sql/where/condition/IsGreaterThanOrEqualToWhenPresent.java | 3 ++- .../java/org/mybatis/dynamic/sql/where/condition/IsIn.java | 2 +- .../sql/where/condition/IsInCaseInsensitiveWhenPresent.java | 2 +- .../mybatis/dynamic/sql/where/condition/IsInWhenPresent.java | 2 +- .../sql/where/condition/IsLikeCaseInsensitiveWhenPresent.java | 3 ++- .../java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java | 2 +- .../sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java | 2 +- .../dynamic/sql/where/condition/IsNotInWhenPresent.java | 2 +- .../where/condition/IsNotLikeCaseInsensitiveWhenPresent.java | 3 ++- 10 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java index 20e6251d6..71daa7763 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractNoValueCondition.java @@ -60,7 +60,8 @@ public interface Filterable { * @param <S> * condition type - not used except for compilation compliance * - * @return this condition if renderable and the supplier returns true, otherwise a condition that will not render. + * @return this condition if renderable and the supplier returns true, otherwise a condition that will not + * render. */ <S> AbstractNoValueCondition<S> filter(BooleanSupplier booleanSupplier); } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWhenPresent.java index 825b5c6cf..01f895dc9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsGreaterThanOrEqualToWhenPresent.java @@ -25,7 +25,8 @@ public class IsGreaterThanOrEqualToWhenPresent<T> extends AbstractSingleValueCondition<T> implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { - private static final IsGreaterThanOrEqualToWhenPresent<?> EMPTY = new IsGreaterThanOrEqualToWhenPresent<Object>(-1) { + private static final IsGreaterThanOrEqualToWhenPresent<?> EMPTY = + new IsGreaterThanOrEqualToWhenPresent<Object>(-1) { @Override public Object value() { throw new NoSuchElementException("No value present"); //$NON-NLS-1$ diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java index 886980610..67072dc8a 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsIn.java @@ -27,7 +27,7 @@ import org.mybatis.dynamic.sql.util.Validator; public class IsIn<T> extends AbstractListValueCondition<T> - implements AbstractListValueCondition.Filterable<T>, AbstractListValueCondition.Mappable<T>{ + implements AbstractListValueCondition.Filterable<T>, AbstractListValueCondition.Mappable<T> { private static final IsIn<?> EMPTY = new IsIn<>(Collections.emptyList()); public static <T> IsIn<T> empty() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java index 934df359b..6b4c1e1cd 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInCaseInsensitiveWhenPresent.java @@ -18,8 +18,8 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.function.Function; import java.util.Objects; +import java.util.function.Function; import java.util.function.Predicate; import org.jspecify.annotations.NonNull; diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java index 2dec62d72..abacd2690 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsInWhenPresent.java @@ -27,7 +27,7 @@ import org.mybatis.dynamic.sql.AbstractListValueCondition; public class IsInWhenPresent<T> extends AbstractListValueCondition<T> - implements AbstractListValueCondition.Filterable<T>, AbstractListValueCondition.Mappable<T>{ + implements AbstractListValueCondition.Filterable<T>, AbstractListValueCondition.Mappable<T> { private static final IsInWhenPresent<?> EMPTY = new IsInWhenPresent<>(Collections.emptyList()); public static <T> IsInWhenPresent<T> empty() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitiveWhenPresent.java index bebbff30d..60307625f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsLikeCaseInsensitiveWhenPresent.java @@ -27,7 +27,8 @@ public class IsLikeCaseInsensitiveWhenPresent<T> extends AbstractSingleValueCondition<T> implements CaseInsensitiveRenderableCondition<T>, AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { - private static final IsLikeCaseInsensitiveWhenPresent<?> EMPTY = new IsLikeCaseInsensitiveWhenPresent<>("") { //$NON-NLS-1$ + private static final IsLikeCaseInsensitiveWhenPresent<?> EMPTY = + new IsLikeCaseInsensitiveWhenPresent<>("") { //$NON-NLS-1$ @Override public String value() { throw new NoSuchElementException("No value present"); //$NON-NLS-1$ diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java index f6c70d180..af6c248f4 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotIn.java @@ -27,7 +27,7 @@ import org.mybatis.dynamic.sql.util.Validator; public class IsNotIn<T> extends AbstractListValueCondition<T> - implements AbstractListValueCondition.Filterable<T>, AbstractListValueCondition.Mappable<T>{ + implements AbstractListValueCondition.Filterable<T>, AbstractListValueCondition.Mappable<T> { private static final IsNotIn<?> EMPTY = new IsNotIn<>(Collections.emptyList()); public static <T> IsNotIn<T> empty() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java index 5646168c1..6852c67fd 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInCaseInsensitiveWhenPresent.java @@ -18,8 +18,8 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.function.Function; import java.util.Objects; +import java.util.function.Function; import java.util.function.Predicate; import org.jspecify.annotations.NonNull; diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java index 375f7d69b..33efb1782 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotInWhenPresent.java @@ -27,7 +27,7 @@ import org.mybatis.dynamic.sql.AbstractListValueCondition; public class IsNotInWhenPresent<T> extends AbstractListValueCondition<T> - implements AbstractListValueCondition.Filterable<T>, AbstractListValueCondition.Mappable<T>{ + implements AbstractListValueCondition.Filterable<T>, AbstractListValueCondition.Mappable<T> { private static final IsNotInWhenPresent<?> EMPTY = new IsNotInWhenPresent<>(Collections.emptyList()); public static <T> IsNotInWhenPresent<T> empty() { diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitiveWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitiveWhenPresent.java index e1e17f9da..cc0b04549 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitiveWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotLikeCaseInsensitiveWhenPresent.java @@ -27,7 +27,8 @@ public class IsNotLikeCaseInsensitiveWhenPresent<T> extends AbstractSingleValueCondition<T> implements CaseInsensitiveRenderableCondition<T>, AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { - private static final IsNotLikeCaseInsensitiveWhenPresent<?> EMPTY = new IsNotLikeCaseInsensitiveWhenPresent<>("") { //$NON-NLS-1$ + private static final IsNotLikeCaseInsensitiveWhenPresent<?> EMPTY = + new IsNotLikeCaseInsensitiveWhenPresent<>("") { //$NON-NLS-1$ @Override public String value() { throw new NoSuchElementException("No value present"); //$NON-NLS-1$ From 42a905c88d19f83859c94e663351be1ad0fc11d8 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 7 Apr 2025 15:27:34 -0400 Subject: [PATCH 240/260] Checkstyle, Sonar, Coverage, etc. --- .../where/condition/IsBetweenWhenPresent.java | 2 +- .../condition/IsNotBetweenWhenPresent.java | 2 +- .../examples/animal/data/AnimalDataTest.java | 12 +- src/test/java/issues/gh105/Issue105Test.java | 176 ------------------ .../dynamic/sql/util/PredicatesTest.java | 42 +++++ .../sql/where/condition/FilterAndMapTest.java | 62 ++++++ .../sql/where/condition/NullContractTest.java | 2 +- .../render/OptionalCriterionRenderTest.java | 48 +---- 8 files changed, 122 insertions(+), 224 deletions(-) create mode 100644 src/test/java/org/mybatis/dynamic/sql/util/PredicatesTest.java diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetweenWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetweenWhenPresent.java index a3eb2a91e..bc9c12d37 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetweenWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsBetweenWhenPresent.java @@ -103,7 +103,7 @@ private Builder(@Nullable T value1) { @Override protected IsBetweenWhenPresent<T> build(@Nullable T value2) { - return IsBetweenWhenPresent.of(value1, value2); + return of(value1, value2); } } } diff --git a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetweenWhenPresent.java b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetweenWhenPresent.java index cb9860384..3c9c8fc9f 100644 --- a/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetweenWhenPresent.java +++ b/src/main/java/org/mybatis/dynamic/sql/where/condition/IsNotBetweenWhenPresent.java @@ -104,7 +104,7 @@ private Builder(@Nullable T value1) { @Override protected IsNotBetweenWhenPresent<T> build(@Nullable T value2) { - return IsNotBetweenWhenPresent.of(value1, value2); + return of(value1, value2); } } } diff --git a/src/test/java/examples/animal/data/AnimalDataTest.java b/src/test/java/examples/animal/data/AnimalDataTest.java index a883b4bd2..1ea44184c 100644 --- a/src/test/java/examples/animal/data/AnimalDataTest.java +++ b/src/test/java/examples/animal/data/AnimalDataTest.java @@ -33,7 +33,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Optional; import org.apache.ibatis.datasource.unpooled.UnpooledDataSource; @@ -717,7 +716,7 @@ void testInConditionWithEventuallyEmptyListForceRendering() { SelectModel selectModel = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isInWhenPresent(inValues).filter(Objects::nonNull).filter(i -> i != 22)) + .where(id, isInWhenPresent(inValues).filter(i -> i != 22)) .build(); assertThatExceptionOfType(NonRenderingWhereClauseException.class).isThrownBy(() -> @@ -744,7 +743,7 @@ void testInCaseSensitiveCondition() { SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isInCaseInsensitive("yellow-bellied marmot", "verbet", null)) + .where(animalName, isInCaseInsensitiveWhenPresent("yellow-bellied marmot", "verbet", null)) .build() .render(RenderingStrategies.MYBATIS3); @@ -792,12 +791,13 @@ void testNotInCaseSensitiveConditionWithNull() { SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isNotInCaseInsensitive((String)null)) + .where(animalName, isNotInCaseInsensitiveWhenPresent((String) null)) + .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); List<AnimalData> animals = mapper.selectMany(selectStatement); - assertThat(animals).isEmpty(); + assertThat(animals).hasSize(65); } } @@ -825,7 +825,7 @@ void testNotInConditionWithEventuallyEmptyListForceRendering() { SelectModel selectModel = select(id, animalName, bodyWeight, brainWeight) .from(animalData) .where(id, isNotInWhenPresent(null, 22, null) - .filter(Objects::nonNull).filter(i -> i != 22)) + .filter(i -> i != 22)) .build(); assertThatExceptionOfType(NonRenderingWhereClauseException.class).isThrownBy(() -> diff --git a/src/test/java/issues/gh105/Issue105Test.java b/src/test/java/issues/gh105/Issue105Test.java index 81ecb79c2..c12f4fde9 100644 --- a/src/test/java/issues/gh105/Issue105Test.java +++ b/src/test/java/issues/gh105/Issue105Test.java @@ -519,22 +519,6 @@ void testNotLikeWhenPresentTransform() { assertThat(selectStatement.getParameters()).containsEntry("p1", "%fred%"); } - @Test - void testBetweenTransformWithNull() { - - SelectStatementProvider selectStatement = select(id, firstName, lastName) - .from(person) - .where(age, isBetweenWhenPresent(1).and((Integer) null).map(i1 -> i1 + 1, i2 -> i2 + 2)) - .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expected = "select person_id, first_name, last_name" - + " from Person"; - - assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); - } - @Test void testBetweenWhenPresentTransformWithNull() { @@ -551,22 +535,6 @@ void testBetweenWhenPresentTransformWithNull() { assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); } - @Test - void testEqualTransformWithNull() { - - SelectStatementProvider selectStatement = select(id, firstName, lastName) - .from(person) - .where(age, isEqualToWhenPresent((Integer) null).map(i -> i + 1)) - .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expected = "select person_id, first_name, last_name" - + " from Person"; - - assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); - } - @Test void testEqualWhenPresentTransformWithNull() { @@ -583,38 +551,6 @@ void testEqualWhenPresentTransformWithNull() { assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); } - @Test - void testGreaterThanTransformWithNull() { - - SelectStatementProvider selectStatement = select(id, firstName, lastName) - .from(person) - .where(age, isGreaterThanWhenPresent((Integer) null).map(i -> i + 1)) - .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expected = "select person_id, first_name, last_name" - + " from Person"; - - assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); - } - - @Test - void testGreaterThanOrEqualTransformWithNull() { - - SelectStatementProvider selectStatement = select(id, firstName, lastName) - .from(person) - .where(age, isGreaterThanOrEqualToWhenPresent((Integer) null).map(i -> i + 1)) - .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expected = "select person_id, first_name, last_name" - + " from Person"; - - assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); - } - @Test void testGreaterThanOrEqualWhenPresentTransformWithNull() { @@ -647,38 +583,6 @@ void testGreaterThanWhenPresentTransformWithNull() { assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); } - @Test - void testLessThanTransformWithNull() { - - SelectStatementProvider selectStatement = select(id, firstName, lastName) - .from(person) - .where(age, isLessThanWhenPresent((Integer) null).map(i -> i + 1)) - .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expected = "select person_id, first_name, last_name" - + " from Person"; - - assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); - } - - @Test - void testLessThanOrEqualTransformWithNull() { - - SelectStatementProvider selectStatement = select(id, firstName, lastName) - .from(person) - .where(age, isLessThanOrEqualToWhenPresent((Integer) null).map(i -> i + 1)) - .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expected = "select person_id, first_name, last_name" - + " from Person"; - - assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); - } - @Test void testLessThanOrEqualWhenPresentTransformWithNull() { @@ -711,38 +615,6 @@ void testLessThanWhenPresentTransformWithNull() { assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); } - @Test - void testLikeTransformWithNull() { - - SelectStatementProvider selectStatement = select(id, firstName, lastName) - .from(person) - .where(firstName, isLikeWhenPresent((String) null).map(SearchUtils::addWildcards)) - .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expected = "select person_id, first_name, last_name" - + " from Person"; - - assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); - } - - @Test - void testLikeCaseInsensitiveTransformWithNull() { - - SelectStatementProvider selectStatement = select(id, firstName, lastName) - .from(person) - .where(firstName, isLikeCaseInsensitiveWhenPresent((String) null).map(SearchUtils::addWildcards)) - .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expected = "select person_id, first_name, last_name" - + " from Person"; - - assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); - } - @Test void testLikeCaseInsensitiveWhenPresentTransformWithNull() { @@ -807,22 +679,6 @@ void testNotBetweenWhenPresentTransformWithNull() { assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); } - @Test - void testNotEqualTransformWithNull() { - - SelectStatementProvider selectStatement = select(id, firstName, lastName) - .from(person) - .where(age, isNotEqualToWhenPresent((Integer) null).map(i -> i + 1)) - .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expected = "select person_id, first_name, last_name" - + " from Person"; - - assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); - } - @Test void testNotEqualWhenPresentTransformWithNull() { @@ -839,38 +695,6 @@ void testNotEqualWhenPresentTransformWithNull() { assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); } - @Test - void testNotLikeTransformWithNull() { - - SelectStatementProvider selectStatement = select(id, firstName, lastName) - .from(person) - .where(firstName, isNotLikeWhenPresent((String) null).map(SearchUtils::addWildcards)) - .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expected = "select person_id, first_name, last_name" - + " from Person"; - - assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); - } - - @Test - void testNotLikeCaseInsensitiveTransformWithNull() { - - SelectStatementProvider selectStatement = select(id, firstName, lastName) - .from(person) - .where(firstName, isNotLikeCaseInsensitiveWhenPresent((String) null).map(SearchUtils::addWildcards)) - .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) - .build() - .render(RenderingStrategies.MYBATIS3); - - String expected = "select person_id, first_name, last_name" - + " from Person"; - - assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); - } - @Test void testNotLikeCaseInsensitiveWhenPresentTransformWithNull() { diff --git a/src/test/java/org/mybatis/dynamic/sql/util/PredicatesTest.java b/src/test/java/org/mybatis/dynamic/sql/util/PredicatesTest.java new file mode 100644 index 000000000..950af088a --- /dev/null +++ b/src/test/java/org/mybatis/dynamic/sql/util/PredicatesTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2016-2025 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 + * + * https://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.util; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +class PredicatesTest { + @Test + void testFirstNull() { + assertThat(Predicates.bothPresent().test(null, 1)).isFalse(); + } + + @Test + void testSecondNull() { + assertThat(Predicates.bothPresent().test(1, null)).isFalse(); + } + + @Test + void testBothNull() { + assertThat(Predicates.bothPresent().test(null, null)).isFalse(); + } + + @Test + void testNeitherNull() { + assertThat(Predicates.bothPresent().test(1, 1)).isTrue(); + } +} diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java index a3bb3d620..7ea071e87 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/FilterAndMapTest.java @@ -20,8 +20,12 @@ import java.util.List; import java.util.NoSuchElementException; +import java.util.function.Predicate; +import java.util.stream.Stream; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import org.mybatis.dynamic.sql.SqlBuilder; class FilterAndMapTest { @@ -492,6 +496,46 @@ void testBetweenMapWithSingleMapper() { assertThat(cond.value2()).isEqualTo(4); } + @Test + void testBetweenWhenPresentFilterWithBiPredicate() { + IsBetweenWhenPresent<Integer> cond = SqlBuilder.isBetweenWhenPresent("3").and("4") + .map(Integer::parseInt) + .filter((v1, v2) -> true); + assertThat(cond.isEmpty()).isFalse(); + assertThat(cond.value1()).isEqualTo(3); + assertThat(cond.value2()).isEqualTo(4); + } + + @Test + void testNotBetweenWhenPresentFilterWithBiPredicate() { + IsNotBetweenWhenPresent<Integer> cond = SqlBuilder.isNotBetweenWhenPresent("3").and("4") + .map(Integer::parseInt) + .filter((v1, v2) -> true); + assertThat(cond.isEmpty()).isFalse(); + assertThat(cond.value1()).isEqualTo(3); + assertThat(cond.value2()).isEqualTo(4); + } + + @ParameterizedTest + @MethodSource("testBetweenFilterVariations") + void testBetweenFilterVariations(FilterVariation variation) { + IsBetween<Integer> cond = SqlBuilder.isBetween("4").and("6") + .map(Integer::parseInt) + .filter(variation.predicate); + assertThat(cond.isEmpty()).isEqualTo(variation.empty); + } + + private record FilterVariation(Predicate<Integer> predicate, boolean empty) {} + + private static Stream<FilterVariation> testBetweenFilterVariations() { + return Stream.of( + new FilterVariation(v -> v == 4, true), + new FilterVariation(v -> v == 6, true), + new FilterVariation(v -> v == 1, true), + new FilterVariation(v -> v % 2 == 0, false) + ); + } + @Test void testNotBetweenUnRenderableFilterShouldReturnSameObject() { IsNotBetween<Integer> cond = SqlBuilder.isNotBetween(3).and(4).filter((i1, i2) -> false); @@ -524,6 +568,24 @@ void testNotBetweenMapWithSingleMapper() { assertThat(cond.value2()).isEqualTo(4); } + @Test + void testBetweenFilterToEmpty() { + var cond = SqlBuilder.isBetween("3").and("4").map(Integer::parseInt) + .filter((i1, i2) -> false); + assertThat(cond.isEmpty()).isTrue(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value1); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value2); + } + + @Test + void testNotBetweenFilterToEmpty() { + var cond = SqlBuilder.isNotBetween("3").and("4").map(Integer::parseInt) + .filter((i1, i2) -> false); + assertThat(cond.isEmpty()).isTrue(); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value1); + assertThatExceptionOfType(NoSuchElementException.class).isThrownBy(cond::value2); + } + @Test void testMappingAnEmptyListCondition() { var cond = SqlBuilder.isNotIn("Fred", "Wilma"); diff --git a/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java b/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java index 17b96973e..cd55d9e52 100644 --- a/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/where/condition/NullContractTest.java @@ -37,7 +37,7 @@ * <p>This set of tests should be the only tests in the library that verify this behavior. All other tests * should use the library properly. */ -public class NullContractTest { +class NullContractTest { @SuppressWarnings("DataFlowIssue") // we are deliberately passing nulls into non-null methods for testing @Test void testIsBetween() { 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 25ea36a3e..48bd36755 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 @@ -34,21 +34,7 @@ class OptionalCriterionRenderTest { @Test void testNoRenderableCriteria() { - Integer nullId = null; - - Optional<WhereClauseProvider> whereClause = where(id, isEqualToWhenPresent(nullId)) - .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) - .build() - .render(RenderingStrategies.SPRING_NAMED_PARAMETER); - - assertThat(whereClause).isEmpty(); - } - - @Test - void testNoRenderableCriteriaWithIf() { - Integer nullId = null; - - Optional<WhereClauseProvider> whereClause = where(id, isEqualToWhenPresent(nullId)) + Optional<WhereClauseProvider> whereClause = where(id, isEqualToWhenPresent((Integer) null)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.SPRING_NAMED_PARAMETER); @@ -102,10 +88,8 @@ void testEnabledIsNotNull() { @Test void testOneRenderableCriteriaBeforeNull() { - String nullFirstName = null; - Optional<WhereClauseProvider> whereClause = where(id, isEqualToWhenPresent(22)) - .and(firstName, isEqualToWhenPresent(nullFirstName)) + .and(firstName, isEqualToWhenPresent((String) null)) .build() .render(RenderingStrategies.SPRING_NAMED_PARAMETER); @@ -117,9 +101,7 @@ void testOneRenderableCriteriaBeforeNull() { @Test void testOneRenderableCriteriaBeforeNull2() { - String nullFirstName = null; - - Optional<WhereClauseProvider> whereClause = where(id, isEqualToWhenPresent(22), and(firstName, isEqualToWhenPresent(nullFirstName))) + Optional<WhereClauseProvider> whereClause = where(id, isEqualToWhenPresent(22), and(firstName, isEqualToWhenPresent((String) null))) .build() .render(RenderingStrategies.SPRING_NAMED_PARAMETER); @@ -131,9 +113,7 @@ void testOneRenderableCriteriaBeforeNull2() { @Test void testOneRenderableCriteriaAfterNull() { - Integer nullId = null; - - Optional<WhereClauseProvider> whereClause = where(id, isEqualToWhenPresent(nullId)) + Optional<WhereClauseProvider> whereClause = where(id, isEqualToWhenPresent((Integer) null)) .and(firstName, isEqualToWhenPresent("fred")) .build() .render(RenderingStrategies.SPRING_NAMED_PARAMETER); @@ -146,9 +126,7 @@ void testOneRenderableCriteriaAfterNull() { @Test void testOneRenderableCriteriaAfterNull2() { - Integer nullId = null; - - Optional<WhereClauseProvider> whereClause = where(id, isEqualToWhenPresent(nullId), and(firstName, isEqualToWhenPresent("fred"))) + Optional<WhereClauseProvider> whereClause = where(id, isEqualToWhenPresent((Integer) null), and(firstName, isEqualToWhenPresent("fred"))) .build() .render(RenderingStrategies.SPRING_NAMED_PARAMETER); @@ -160,9 +138,7 @@ void testOneRenderableCriteriaAfterNull2() { @Test void testOverrideFirstConnector() { - Integer nullId = null; - - Optional<WhereClauseProvider> whereClause = where(id, isEqualToWhenPresent(nullId), and(firstName, isEqualToWhenPresent("fred")), or(lastName, isEqualTo("flintstone"))) + Optional<WhereClauseProvider> whereClause = where(id, isEqualToWhenPresent((Integer) null), and(firstName, isEqualToWhenPresent("fred")), or(lastName, isEqualTo("flintstone"))) .build() .render(RenderingStrategies.SPRING_NAMED_PARAMETER); @@ -305,10 +281,8 @@ void testWhereExistsAndAnd() { @Test void testCollapsingCriteriaGroup1() { - String name1 = null; - Optional<WhereClauseProvider> whereClause = where( - group(firstName, isEqualToWhenPresent(name1)), or(lastName, isEqualToWhenPresent(name1))) + group(firstName, isEqualToWhenPresent((String) null)), or(lastName, isEqualToWhenPresent((String) null))) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.SPRING_NAMED_PARAMETER); @@ -318,10 +292,8 @@ void testCollapsingCriteriaGroup1() { @Test void testCollapsingCriteriaGroup2() { - String name1 = null; - Optional<WhereClauseProvider> whereClause = where( - group(firstName, isEqualTo("Fred")), or(lastName, isEqualToWhenPresent(name1))) + group(firstName, isEqualTo("Fred")), or(lastName, isEqualToWhenPresent((String) null))) .build() .render(RenderingStrategies.SPRING_NAMED_PARAMETER); @@ -335,10 +307,8 @@ void testCollapsingCriteriaGroup2() { @Test void testCollapsingCriteriaGroup3() { - String name1 = null; - Optional<WhereClauseProvider> whereClause = where( - group(firstName, isEqualTo("Fred")), or(lastName, isEqualToWhenPresent(name1)), or(firstName, isEqualTo("Betty"))) + group(firstName, isEqualTo("Fred")), or(lastName, isEqualToWhenPresent((String) null)), or(firstName, isEqualTo("Betty"))) .build() .render(RenderingStrategies.SPRING_NAMED_PARAMETER); From b3b3b7d8f9cc26aa86f5b36bdef1dd28bf917dba Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 7 Apr 2025 15:38:09 -0400 Subject: [PATCH 241/260] Documentation --- CHANGELOG.md | 2 ++ src/site/markdown/docs/conditions.md | 16 +++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cec9f683f..c65f2c09c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -82,6 +82,8 @@ Runtime behavior changes: 2. We have updated the "ParameterTypeConverter" used in Spring applications to maintain compatibility with Spring's "Converter" interface. The primary change is that the framework will no longer call a type converter if the input value is null. This should simplify the coding of converters and foster reuse with existing Spring converters. +3. The "map" method on the "WhenPresent" conditions will accept a mapper function that may return a null value. The + conditions will now properly handle this outcome ### Other important changes: diff --git a/src/site/markdown/docs/conditions.md b/src/site/markdown/docs/conditions.md index 2e266e22b..438249400 100644 --- a/src/site/markdown/docs/conditions.md +++ b/src/site/markdown/docs/conditions.md @@ -166,8 +166,8 @@ table lists the optional conditions and shows how to use them: | Null | where(id, isNull().filter(BooleanSupplier) | The condition will render if BooleanSupplier.getAsBoolean() returns true | ### "When Present" Condition Builders -The library supplies several methods that supply conditions to be used in the common case of checking for null -values. The table below lists the rendering rules for each of these "when present" condition builder methods. +The library supplies conditions for use in the common case of checking for null +values. The table below lists the rendering rules for each of these "when present" conditions. | Condition | Example | Rendering Rules | |---------------------------|---------------------------------------------------|---------------------------------------------------------------| @@ -184,14 +184,20 @@ values. The table below lists the rendering rules for each of these "when presen | Not Like | where(id, isNotLikeWhenPresent(x)) | The condition will render if x is non-null | | Not Like Case Insensitive | where(id, isNotLikeCaseInsensitiveWhenPresent(x)) | The condition will render if x is non-null | -Note that these methods simply apply a "NotNull" filter to a condition. For example: +With our adoption of JSpecify, it is now considered a misuse of the library to pass a null value into a condition +unless the condition is one of the "when present" conditions. If you previously wrote code like this: ```java -// the following two lines are functionally equivalent -... where (id, isEqualToWhenPresent(x)) ... ... where (id, isEqualTo(x).filter(Objects::nonNull)) ... ``` +Starting in version 2.0.0 of the library, you will now see IDE warnings related to nullability. You should change it +to this: + +```java +... where (id, isEqualToWhenPresent(x)) ... +``` + ### Optionality with the "In" Conditions Optionality with the "in" and "not in" conditions is a bit more complex than the other types of conditions. The rules are different for the base conditions ("isIn", "isNotIn", etc.) and the "when present" conditions ("isInWhenPresent", From f06686dfe0eb344f0e9c505cf1f02e27e7985278 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 7 Apr 2025 17:31:56 -0400 Subject: [PATCH 242/260] Animal data nullability updates --- .../examples/animal/data/AnimalDataTest.java | 1 - .../examples/animal/data/MyInCondition.java | 6 ++-- .../OptionalConditionsAnimalDataTest.java | 3 +- ...onditionsWithPredicatesAnimalDataTest.java | 35 ++++--------------- .../data/VariousListConditionsTest.java | 12 ++----- 5 files changed, 14 insertions(+), 43 deletions(-) diff --git a/src/test/java/examples/animal/data/AnimalDataTest.java b/src/test/java/examples/animal/data/AnimalDataTest.java index b028868ad..efedc0aea 100644 --- a/src/test/java/examples/animal/data/AnimalDataTest.java +++ b/src/test/java/examples/animal/data/AnimalDataTest.java @@ -33,7 +33,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Optional; import org.apache.ibatis.datasource.unpooled.UnpooledDataSource; diff --git a/src/test/java/examples/animal/data/MyInCondition.java b/src/test/java/examples/animal/data/MyInCondition.java index 7203e4fb5..de62d55f6 100644 --- a/src/test/java/examples/animal/data/MyInCondition.java +++ b/src/test/java/examples/animal/data/MyInCondition.java @@ -22,11 +22,11 @@ import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlBuilder; import org.mybatis.dynamic.sql.where.condition.IsIn; +import org.mybatis.dynamic.sql.where.condition.IsInWhenPresent; public class MyInCondition { - public static IsIn<String> isIn(@Nullable String...values) { - return SqlBuilder.isIn(values) - .filter(Objects::nonNull) + public static IsInWhenPresent<String> isIn(@Nullable String...values) { + return SqlBuilder.isInWhenPresent(values) .map(String::trim) .filter(not(String::isEmpty)); } diff --git a/src/test/java/examples/animal/data/OptionalConditionsAnimalDataTest.java b/src/test/java/examples/animal/data/OptionalConditionsAnimalDataTest.java index 166c21a05..0917160a0 100644 --- a/src/test/java/examples/animal/data/OptionalConditionsAnimalDataTest.java +++ b/src/test/java/examples/animal/data/OptionalConditionsAnimalDataTest.java @@ -34,6 +34,7 @@ import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; +import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.render.RenderingStrategies; @@ -43,7 +44,7 @@ class OptionalConditionsAnimalDataTest { private static final String JDBC_URL = "jdbc:hsqldb:mem:aname"; private static final String JDBC_DRIVER = "org.hsqldb.jdbcDriver"; - private static final Integer NULL_INTEGER = null; + private static final @Nullable Integer NULL_INTEGER = null; private SqlSessionFactory sqlSessionFactory; diff --git a/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java b/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java index 671a171bc..4c65708cd 100644 --- a/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java +++ b/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java @@ -30,7 +30,6 @@ import java.sql.Connection; import java.sql.DriverManager; import java.util.List; -import java.util.Objects; import org.apache.ibatis.datasource.unpooled.UnpooledDataSource; import org.apache.ibatis.jdbc.ScriptRunner; @@ -94,26 +93,6 @@ void testAllIgnored() { } } - @Test - void testSelectByNull() { - // this method demonstrates that ignoring the null value warning will still work - try (SqlSession sqlSession = sqlSessionFactory.openSession()) { - AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); - SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) - .from(animalData) - .where(id, isGreaterThan(NULL_INTEGER)) // should be an IDE warning about passing null to a nonnull method - .orderBy(id) - .build() - .render(RenderingStrategies.MYBATIS3); - List<AnimalData> animals = mapper.selectMany(selectStatement); - assertAll( - () -> assertThat(selectStatement.getSelectStatement()).isEqualTo("select id, animal_name, body_weight, brain_weight from AnimalData where id > #{parameters.p1,jdbcType=INTEGER} order by id"), - () -> assertThat(selectStatement.getParameters()).containsEntry("p1", null), - () -> assertThat(animals).isEmpty() - ); - } - } - @Test void testIgnoredBetweenRendered() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { @@ -122,7 +101,7 @@ void testIgnoredBetweenRendered() { .from(animalData) .where(id, isEqualTo(3)) .and(id, isNotEqualToWhenPresent(NULL_INTEGER)) - .or(id, isEqualTo(4).filter(Objects::nonNull)) + .or(id, isEqualTo(4)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -143,8 +122,8 @@ void testIgnoredInWhere() { SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) .where(id, isLessThanWhenPresent(NULL_INTEGER)) - .and(id, isEqualTo(3).filter(Objects::nonNull)) - .or(id, isEqualTo(4).filter(Objects::nonNull)) + .and(id, isEqualTo(3)) + .or(id, isEqualTo(4)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -187,8 +166,8 @@ void testIgnoredInitialWhere() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(id, isLessThanWhenPresent(NULL_INTEGER), and(id, isEqualTo(3).filter(Objects::nonNull))) - .or(id, isEqualTo(4).filter(Objects::nonNull)) + .where(id, isLessThanWhenPresent(NULL_INTEGER), and(id, isEqualTo(3))) + .or(id, isEqualTo(4)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); @@ -802,7 +781,7 @@ void testIsLikeWhenWithValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isLike("%mole").filter(Objects::nonNull)) + .where(animalName, isLike("%mole")) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() @@ -882,7 +861,7 @@ void testIsNotLikeWhenWithValue() { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) - .where(animalName, isNotLike("%mole").filter(Objects::nonNull)) + .where(animalName, isNotLike("%mole")) .and(id, isLessThanOrEqualTo(10)) .orderBy(id) .build() diff --git a/src/test/java/examples/animal/data/VariousListConditionsTest.java b/src/test/java/examples/animal/data/VariousListConditionsTest.java index c3cc8777e..1fef3d88b 100644 --- a/src/test/java/examples/animal/data/VariousListConditionsTest.java +++ b/src/test/java/examples/animal/data/VariousListConditionsTest.java @@ -86,19 +86,18 @@ void testInWithNull() { SelectStatementProvider selectStatement = select(id, animalName) .from(animalData) - .where(id, isIn(2, 3, null)) + .where(id, isInWhenPresent(2, 3, null)) .orderBy(id) .build() .render(RenderingStrategies.MYBATIS3); assertThat(selectStatement.getSelectStatement()).isEqualTo( "select id, animal_name from AnimalData where id " + - "in (#{parameters.p1,jdbcType=INTEGER},#{parameters.p2,jdbcType=INTEGER},#{parameters.p3,jdbcType=INTEGER}) " + + "in (#{parameters.p1,jdbcType=INTEGER},#{parameters.p2,jdbcType=INTEGER}) " + "order by id" ); assertThat(selectStatement.getParameters()).containsEntry("p1", 2); assertThat(selectStatement.getParameters()).containsEntry("p2", 3); - assertThat(selectStatement.getParameters()).containsEntry("p3", null); List<Map<String, Object>> rows = mapper.selectManyMappedRows(selectStatement); assertThat(rows).hasSize(2); @@ -171,13 +170,6 @@ void testInWhenPresentWithEmptyList() { } } - @Test - void testInWithNullList() { - assertThatExceptionOfType(NullPointerException.class).isThrownBy(() -> - isIn((Collection<Integer>) null) - ); - } - @Test void testInWhenPresentWithNullList() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { From e827b579560c7136a512433c119e7b1e5e96c2a5 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 7 Apr 2025 17:33:04 -0400 Subject: [PATCH 243/260] Remove unused imports --- src/test/java/examples/animal/data/MyInCondition.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/test/java/examples/animal/data/MyInCondition.java b/src/test/java/examples/animal/data/MyInCondition.java index de62d55f6..13f076331 100644 --- a/src/test/java/examples/animal/data/MyInCondition.java +++ b/src/test/java/examples/animal/data/MyInCondition.java @@ -17,11 +17,8 @@ import static java.util.function.Predicate.not; -import java.util.Objects; - import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.SqlBuilder; -import org.mybatis.dynamic.sql.where.condition.IsIn; import org.mybatis.dynamic.sql.where.condition.IsInWhenPresent; public class MyInCondition { From 3f5b36357070e00dcc2c2c11631974aca48fae42 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 7 Apr 2025 17:39:48 -0400 Subject: [PATCH 244/260] Convert to record --- .../comparison/ColumnComparisonMapper.java | 6 ++--- .../comparison/ColumnComparisonRecord.java | 21 +-------------- .../comparison/ColumnComparisonTest.java | 26 +++++++++---------- 3 files changed, 17 insertions(+), 36 deletions(-) diff --git a/src/test/java/examples/column/comparison/ColumnComparisonMapper.java b/src/test/java/examples/column/comparison/ColumnComparisonMapper.java index a8acf0c88..dc27de8d0 100644 --- a/src/test/java/examples/column/comparison/ColumnComparisonMapper.java +++ b/src/test/java/examples/column/comparison/ColumnComparisonMapper.java @@ -17,7 +17,7 @@ import java.util.List; -import org.apache.ibatis.annotations.Result; +import org.apache.ibatis.annotations.Arg; import org.apache.ibatis.annotations.SelectProvider; import org.mybatis.dynamic.sql.select.SelectDSLCompleter; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; @@ -27,8 +27,8 @@ public interface ColumnComparisonMapper { @SelectProvider(type=SqlProviderAdapter.class, method="select") - @Result(column="number1", property="number1", id=true) - @Result(column="number2", property="number2", id=true) + @Arg(column="number1", javaType = int.class, id=true) + @Arg(column="number2", javaType = int.class, id=true) List<ColumnComparisonRecord> selectMany(SelectStatementProvider selectStatement); default List<ColumnComparisonRecord> select(SelectDSLCompleter completer) { diff --git a/src/test/java/examples/column/comparison/ColumnComparisonRecord.java b/src/test/java/examples/column/comparison/ColumnComparisonRecord.java index b783d61b4..8222ca042 100644 --- a/src/test/java/examples/column/comparison/ColumnComparisonRecord.java +++ b/src/test/java/examples/column/comparison/ColumnComparisonRecord.java @@ -15,23 +15,4 @@ */ package examples.column.comparison; -public class ColumnComparisonRecord { - private int number1; - private int number2; - - public int getNumber1() { - return number1; - } - - public void setNumber1(int number1) { - this.number1 = number1; - } - - public int getNumber2() { - return number2; - } - - public void setNumber2(int number2) { - this.number2 = number2; - } -} +public record ColumnComparisonRecord (int number1, int number2) {} diff --git a/src/test/java/examples/column/comparison/ColumnComparisonTest.java b/src/test/java/examples/column/comparison/ColumnComparisonTest.java index 91a6036c5..746db94cd 100644 --- a/src/test/java/examples/column/comparison/ColumnComparisonTest.java +++ b/src/test/java/examples/column/comparison/ColumnComparisonTest.java @@ -51,8 +51,8 @@ void testColumnComparisonLessThan() { assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); assertThat(records).hasSize(5); - assertThat(records.get(0).getNumber1()).isEqualTo(1); - assertThat(records.get(4).getNumber1()).isEqualTo(5); + assertThat(records.get(0).number1()).isEqualTo(1); + assertThat(records.get(4).number1()).isEqualTo(5); } @Test @@ -73,8 +73,8 @@ void testColumnComparisonLessThanOrEqual() { assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); assertThat(records).hasSize(6); - assertThat(records.get(0).getNumber1()).isEqualTo(1); - assertThat(records.get(5).getNumber1()).isEqualTo(6); + assertThat(records.get(0).number1()).isEqualTo(1); + assertThat(records.get(5).number2()).isEqualTo(6); } @Test @@ -95,8 +95,8 @@ void testColumnComparisonGreaterThan() { assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); assertThat(records).hasSize(5); - assertThat(records.get(0).getNumber1()).isEqualTo(7); - assertThat(records.get(4).getNumber1()).isEqualTo(11); + assertThat(records.get(0).number1()).isEqualTo(7); + assertThat(records.get(4).number1()).isEqualTo(11); } @Test @@ -117,8 +117,8 @@ void testColumnComparisonGreaterThanOrEqual() { assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); assertThat(records).hasSize(6); - assertThat(records.get(0).getNumber1()).isEqualTo(6); - assertThat(records.get(5).getNumber1()).isEqualTo(11); + assertThat(records.get(0).number1()).isEqualTo(6); + assertThat(records.get(5).number1()).isEqualTo(11); } @Test @@ -139,7 +139,7 @@ void testColumnComparisonEqual() { assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); assertThat(records).hasSize(1); - assertThat(records.get(0).getNumber1()).isEqualTo(6); + assertThat(records.get(0).number1()).isEqualTo(6); } @Test @@ -160,8 +160,8 @@ void testColumnComparisonNotEqual() { assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); assertThat(records).hasSize(10); - assertThat(records.get(0).getNumber1()).isEqualTo(1); - assertThat(records.get(9).getNumber1()).isEqualTo(11); + assertThat(records.get(0).number1()).isEqualTo(1); + assertThat(records.get(9).number1()).isEqualTo(11); } @Test @@ -172,7 +172,7 @@ void testHelperMethod() { ); assertThat(records).hasSize(10); - assertThat(records.get(0).getNumber1()).isEqualTo(1); - assertThat(records.get(9).getNumber1()).isEqualTo(11); + assertThat(records.get(0).number1()).isEqualTo(1); + assertThat(records.get(9).number1()).isEqualTo(11); } } From 9c82e61c903753c2a64e8e434b6d8056563799d0 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 7 Apr 2025 17:41:00 -0400 Subject: [PATCH 245/260] Use search utils --- src/test/java/examples/complexquery/ComplexQueryTest.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/test/java/examples/complexquery/ComplexQueryTest.java b/src/test/java/examples/complexquery/ComplexQueryTest.java index 3912040cb..e31ab536b 100644 --- a/src/test/java/examples/complexquery/ComplexQueryTest.java +++ b/src/test/java/examples/complexquery/ComplexQueryTest.java @@ -117,7 +117,7 @@ SelectStatementProvider search(@Nullable Integer targetId, @Nullable String fNam } else { builder .and(firstName, isLikeWhenPresent(fName).map(s -> "%" + s + "%")) - .and(lastName, isLikeWhenPresent(lName).map(this::addWildcards)); + .and(lastName, isLikeWhenPresent(lName).map(SearchUtils::addWildcards)); } builder @@ -126,8 +126,4 @@ SelectStatementProvider search(@Nullable Integer targetId, @Nullable String fNam return builder.build().render(RenderingStrategies.MYBATIS3); } - - String addWildcards(String s) { - return "%" + s + "%"; - } } From b390f1f1cb098223a680d5d6510848ad0fc329e8 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 7 Apr 2025 17:55:09 -0400 Subject: [PATCH 246/260] Use search utils --- .../custom_render/CustomRenderingTest.java | 86 +++++++------------ .../custom_render/JsonTestMapper.java | 16 ++-- .../custom_render/JsonTestRecord.java | 30 +------ .../examples/custom_render/package-info.java | 19 ++++ 4 files changed, 60 insertions(+), 91 deletions(-) create mode 100644 src/test/java/examples/custom_render/package-info.java diff --git a/src/test/java/examples/custom_render/CustomRenderingTest.java b/src/test/java/examples/custom_render/CustomRenderingTest.java index 11d7e331c..8b0541c1e 100644 --- a/src/test/java/examples/custom_render/CustomRenderingTest.java +++ b/src/test/java/examples/custom_render/CustomRenderingTest.java @@ -40,7 +40,7 @@ import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; -import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.SqlColumn; import org.mybatis.dynamic.sql.insert.render.GeneralInsertStatementProvider; @@ -63,10 +63,10 @@ class CustomRenderingTest { new PostgreSQLContainer<>(TestContainersConfiguration.POSTGRES_LATEST) .withInitScript("examples/custom_render/dbInit.sql"); - private static SqlSessionFactory sqlSessionFactory; + private SqlSessionFactory sqlSessionFactory; - @BeforeAll - static void setUp() { + @BeforeEach + void setUp() { UnpooledDataSource ds = new UnpooledDataSource(postgres.getDriverClassName(), postgres.getJdbcUrl(), postgres.getUsername(), postgres.getPassword()); Environment environment = new Environment("test", new JdbcTransactionFactory(), ds); @@ -81,10 +81,8 @@ void testInsertRecord() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { JsonTestMapper mapper = sqlSession.getMapper(JsonTestMapper.class); - JsonTestRecord row = new JsonTestRecord(); - row.setId(1); - row.setDescription("Fred"); - row.setInfo("{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); + JsonTestRecord row = new JsonTestRecord(1, "Fred", + "{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); InsertStatementProvider<JsonTestRecord> insertStatement = insert(row).into(jsonTest) .map(id).toProperty("id") @@ -102,10 +100,8 @@ void testInsertRecord() { int rows = mapper.insert(insertStatement); assertThat(rows).isEqualTo(1); - row = new JsonTestRecord(); - row.setId(2); - row.setDescription("Wilma"); - row.setInfo("{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 25}"); + row = new JsonTestRecord(2, "Wilma", + "{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 25}"); insertStatement = insert(row).into(jsonTest) .map(id).toProperty("id") @@ -125,8 +121,8 @@ void testInsertRecord() { List<JsonTestRecord> records = mapper.selectMany(selectStatement); assertThat(records).hasSize(2); - assertThat(records.get(0).getInfo()).isEqualTo("{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); - assertThat(records.get(1).getInfo()).isEqualTo("{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 25}"); + assertThat(records.get(0).info()).isEqualTo("{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); + assertThat(records.get(1).info()).isEqualTo("{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 25}"); } } @@ -169,8 +165,8 @@ void testGeneralInsert() { List<JsonTestRecord> records = mapper.selectMany(selectStatement); assertThat(records).hasSize(2); - assertThat(records.get(0).getInfo()).isEqualTo("{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); - assertThat(records.get(1).getInfo()).isEqualTo("{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 25}"); + assertThat(records.get(0).info()).isEqualTo("{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); + assertThat(records.get(1).info()).isEqualTo("{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 25}"); } } @@ -179,15 +175,11 @@ void testInsertMultiple() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { JsonTestMapper mapper = sqlSession.getMapper(JsonTestMapper.class); - JsonTestRecord record1 = new JsonTestRecord(); - record1.setId(1); - record1.setDescription("Fred"); - record1.setInfo("{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); + JsonTestRecord record1 = new JsonTestRecord(1, "Fred", + "{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); - JsonTestRecord record2 = new JsonTestRecord(); - record2.setId(2); - record2.setDescription("Wilma"); - record2.setInfo("{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 25}"); + JsonTestRecord record2 = new JsonTestRecord(2, "Wilma", + "{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 25}"); MultiRowInsertStatementProvider<JsonTestRecord> insertStatement = insertMultiple(record1, record2) .into(jsonTest) @@ -216,8 +208,8 @@ void testInsertMultiple() { List<JsonTestRecord> records = mapper.selectMany(selectStatement); assertThat(records).hasSize(2); - assertThat(records.get(0).getInfo()).isEqualTo("{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); - assertThat(records.get(1).getInfo()).isEqualTo("{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 25}"); + assertThat(records.get(0).info()).isEqualTo("{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); + assertThat(records.get(1).info()).isEqualTo("{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 25}"); } } @@ -226,15 +218,11 @@ void testUpdate() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { JsonTestMapper mapper = sqlSession.getMapper(JsonTestMapper.class); - JsonTestRecord record1 = new JsonTestRecord(); - record1.setId(1); - record1.setDescription("Fred"); - record1.setInfo("{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); + JsonTestRecord record1 = new JsonTestRecord(1, "Fred", + "{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); - JsonTestRecord record2 = new JsonTestRecord(); - record2.setId(2); - record2.setDescription("Wilma"); - record2.setInfo("{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 25}"); + JsonTestRecord record2 = new JsonTestRecord(2, "Wilma", + "{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 25}"); MultiRowInsertStatementProvider<JsonTestRecord> insertStatement = insertMultiple(record1, record2) .into(jsonTest) @@ -270,8 +258,8 @@ void testUpdate() { List<JsonTestRecord> records = mapper.selectMany(selectStatement); assertThat(records).hasSize(2); - assertThat(records.get(0).getInfo()).isEqualTo("{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); - assertThat(records.get(1).getInfo()).isEqualTo("{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 26}"); + assertThat(records.get(0).info()).isEqualTo("{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); + assertThat(records.get(1).info()).isEqualTo("{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 26}"); } } @@ -280,15 +268,11 @@ void testDeReference() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { JsonTestMapper mapper = sqlSession.getMapper(JsonTestMapper.class); - JsonTestRecord record1 = new JsonTestRecord(); - record1.setId(1); - record1.setDescription("Fred"); - record1.setInfo("{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); + JsonTestRecord record1 = new JsonTestRecord(1, "Fred", + "{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); - JsonTestRecord record2 = new JsonTestRecord(); - record2.setId(2); - record2.setDescription("Wilma"); - record2.setInfo("{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 25}"); + JsonTestRecord record2 = new JsonTestRecord(2, "Wilma", + "{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 25}"); MultiRowInsertStatementProvider<JsonTestRecord> insertStatement = insertMultiple(record1, record2) .into(jsonTest) @@ -316,7 +300,7 @@ void testDeReference() { Optional<JsonTestRecord> row = mapper.selectOne(selectStatement); assertThat(row).hasValueSatisfying( r -> - assertThat(r.getInfo()) + assertThat(r.info()) .isEqualTo("{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 25}") ); } @@ -327,15 +311,11 @@ void testDereference2() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { JsonTestMapper mapper = sqlSession.getMapper(JsonTestMapper.class); - JsonTestRecord record1 = new JsonTestRecord(); - record1.setId(1); - record1.setDescription("Fred"); - record1.setInfo("{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); + JsonTestRecord record1 = new JsonTestRecord(1, "Fred", + "{\"firstName\": \"Fred\", \"lastName\": \"Flintstone\", \"age\": 30}"); - JsonTestRecord record2 = new JsonTestRecord(); - record2.setId(2); - record2.setDescription("Wilma"); - record2.setInfo("{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 25}"); + JsonTestRecord record2 = new JsonTestRecord(2, "Wilma", + "{\"firstName\": \"Wilma\", \"lastName\": \"Flintstone\", \"age\": 25}"); MultiRowInsertStatementProvider<JsonTestRecord> insertStatement = insertMultiple(record1, record2) .into(jsonTest) diff --git a/src/test/java/examples/custom_render/JsonTestMapper.java b/src/test/java/examples/custom_render/JsonTestMapper.java index d928c8a11..4b919ea34 100644 --- a/src/test/java/examples/custom_render/JsonTestMapper.java +++ b/src/test/java/examples/custom_render/JsonTestMapper.java @@ -18,9 +18,7 @@ import java.util.List; import java.util.Optional; -import org.apache.ibatis.annotations.Result; -import org.apache.ibatis.annotations.ResultMap; -import org.apache.ibatis.annotations.Results; +import org.apache.ibatis.annotations.Arg; import org.apache.ibatis.annotations.SelectProvider; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; import org.mybatis.dynamic.sql.util.SqlProviderAdapter; @@ -32,14 +30,14 @@ public interface JsonTestMapper extends CommonDeleteMapper, CommonInsertMapper<JsonTestRecord>, CommonSelectMapper, CommonUpdateMapper { @SelectProvider(type = SqlProviderAdapter.class, method = "select") - @Results(id = "JsonTestResult", value = { - @Result(column = "id", property = "id", id = true), - @Result(column = "description", property = "description"), - @Result(column = "info", property = "info") - }) + @Arg(column = "id", javaType = int.class, id = true) + @Arg(column = "description", javaType = String.class) + @Arg(column = "info", javaType = String.class) List<JsonTestRecord> selectMany(SelectStatementProvider selectStatement); @SelectProvider(type = SqlProviderAdapter.class, method = "select") - @ResultMap("JsonTestResult") + @Arg(column = "id", javaType = int.class, id = true) + @Arg(column = "description", javaType = String.class) + @Arg(column = "info", javaType = String.class) Optional<JsonTestRecord> selectOne(SelectStatementProvider selectStatement); } diff --git a/src/test/java/examples/custom_render/JsonTestRecord.java b/src/test/java/examples/custom_render/JsonTestRecord.java index 2d0da5331..6b7090d58 100644 --- a/src/test/java/examples/custom_render/JsonTestRecord.java +++ b/src/test/java/examples/custom_render/JsonTestRecord.java @@ -15,32 +15,4 @@ */ package examples.custom_render; -public class JsonTestRecord { - private int id; - private String description; - private String info; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getInfo() { - return info; - } - - public void setInfo(String info) { - this.info = info; - } -} +public record JsonTestRecord (int id, String description, String info) {} diff --git a/src/test/java/examples/custom_render/package-info.java b/src/test/java/examples/custom_render/package-info.java new file mode 100644 index 000000000..a735b9733 --- /dev/null +++ b/src/test/java/examples/custom_render/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package examples.custom_render; + +import org.jspecify.annotations.NullMarked; From ebccaa5e5d7da109b7641a41004aebd78fe1c460 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 7 Apr 2025 17:56:05 -0400 Subject: [PATCH 247/260] Remove unused import --- src/test/java/examples/emptywhere/EmptyWhereTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/examples/emptywhere/EmptyWhereTest.java b/src/test/java/examples/emptywhere/EmptyWhereTest.java index 28a718d06..f20a81a9a 100644 --- a/src/test/java/examples/emptywhere/EmptyWhereTest.java +++ b/src/test/java/examples/emptywhere/EmptyWhereTest.java @@ -20,8 +20,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mybatis.dynamic.sql.SqlBuilder.*; -import java.util.Optional; -import java.util.List; import java.util.Optional; import java.util.stream.Stream; From 57ebe037c1adf68315a02ddf829fea99d792f3bb Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Mon, 7 Apr 2025 18:10:07 -0400 Subject: [PATCH 248/260] Convert to record --- .../java/examples/spring/CompoundKeyRow.java | 21 +------------------ .../examples/spring/SpringMapToRowTest.java | 7 +------ 2 files changed, 2 insertions(+), 26 deletions(-) diff --git a/src/test/java/examples/spring/CompoundKeyRow.java b/src/test/java/examples/spring/CompoundKeyRow.java index ea7162e04..d9422b447 100644 --- a/src/test/java/examples/spring/CompoundKeyRow.java +++ b/src/test/java/examples/spring/CompoundKeyRow.java @@ -15,23 +15,4 @@ */ package examples.spring; -public class CompoundKeyRow { - private Integer id1; - private Integer id2; - - public Integer getId1() { - return id1; - } - - public void setId1(Integer id1) { - this.id1 = id1; - } - - public Integer getId2() { - return id2; - } - - public void setId2(Integer id2) { - this.id2 = id2; - } -} +public record CompoundKeyRow (Integer id1, Integer id2) {} diff --git a/src/test/java/examples/spring/SpringMapToRowTest.java b/src/test/java/examples/spring/SpringMapToRowTest.java index cf9b52258..0a2d5fe61 100644 --- a/src/test/java/examples/spring/SpringMapToRowTest.java +++ b/src/test/java/examples/spring/SpringMapToRowTest.java @@ -123,10 +123,5 @@ void testInsertBatch() { } static final RowMapper<CompoundKeyRow> rowMapper = - (rs, i) -> { - CompoundKeyRow answer = new CompoundKeyRow(); - answer.setId1(rs.getInt("ID1")); - answer.setId2(rs.getInt("ID2")); - return answer; - }; + (rs, i) -> new CompoundKeyRow(rs.getInt("ID1"), rs.getInt("ID2")); } From 80e939a596a752168ef7f379b4fe0159c0d8a955 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 8 Apr 2025 10:05:58 -0400 Subject: [PATCH 249/260] Convert to record --- src/test/java/examples/joins/JoinMapper.java | 8 ++--- .../java/examples/joins/JoinMapperTest.java | 18 +++++------ src/test/java/examples/joins/User.java | 30 ++----------------- .../java/examples/joins/package-info.java | 19 ++++++++++++ .../type_conversion/package-info.java | 19 ++++++++++++ 5 files changed, 53 insertions(+), 41 deletions(-) create mode 100644 src/test/java/examples/joins/package-info.java create mode 100644 src/test/java/examples/type_conversion/package-info.java diff --git a/src/test/java/examples/joins/JoinMapper.java b/src/test/java/examples/joins/JoinMapper.java index 0ce4cc42c..66241b7e5 100644 --- a/src/test/java/examples/joins/JoinMapper.java +++ b/src/test/java/examples/joins/JoinMapper.java @@ -17,7 +17,7 @@ import java.util.List; -import org.apache.ibatis.annotations.Result; +import org.apache.ibatis.annotations.Arg; import org.apache.ibatis.annotations.ResultMap; import org.apache.ibatis.annotations.SelectProvider; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; @@ -29,8 +29,8 @@ public interface JoinMapper { List<OrderMaster> selectMany(SelectStatementProvider selectStatement); @SelectProvider(type=SqlProviderAdapter.class, method="select") - @Result(column="user_id", property="userId") - @Result(column="user_name", property="userName") - @Result(column="parent_id", property="parentId") + @Arg(column="user_id", javaType = Integer.class) + @Arg(column="user_name", javaType = String.class) + @Arg(column="parent_id", javaType = Integer.class) List<User> selectUsers(SelectStatementProvider selectStatement); } diff --git a/src/test/java/examples/joins/JoinMapperTest.java b/src/test/java/examples/joins/JoinMapperTest.java index ace7b2115..6d6647219 100644 --- a/src/test/java/examples/joins/JoinMapperTest.java +++ b/src/test/java/examples/joins/JoinMapperTest.java @@ -945,9 +945,9 @@ void testSelf() { assertThat(rows).hasSize(1); User row = rows.get(0); - assertThat(row.getUserId()).isEqualTo(2); - assertThat(row.getUserName()).isEqualTo("Barney"); - assertThat(row.getParentId()).isNull(); + assertThat(row.userId()).isEqualTo(2); + assertThat(row.userName()).isEqualTo("Barney"); + assertThat(row.parentId()).isNull(); } } @@ -985,9 +985,9 @@ void testSelfWithNewAlias() { assertThat(rows).hasSize(1); User row = rows.get(0); - assertThat(row.getUserId()).isEqualTo(2); - assertThat(row.getUserName()).isEqualTo("Barney"); - assertThat(row.getParentId()).isNull(); + assertThat(row.userId()).isEqualTo(2); + assertThat(row.userName()).isEqualTo("Barney"); + assertThat(row.parentId()).isNull(); } } @@ -1016,9 +1016,9 @@ void testSelfWithNewAliasAndOverride() { assertThat(rows).hasSize(1); User row = rows.get(0); - assertThat(row.getUserId()).isEqualTo(2); - assertThat(row.getUserName()).isEqualTo("Barney"); - assertThat(row.getParentId()).isNull(); + assertThat(row.userId()).isEqualTo(2); + assertThat(row.userName()).isEqualTo("Barney"); + assertThat(row.parentId()).isNull(); } } diff --git a/src/test/java/examples/joins/User.java b/src/test/java/examples/joins/User.java index e8c242a25..1d9e36795 100644 --- a/src/test/java/examples/joins/User.java +++ b/src/test/java/examples/joins/User.java @@ -15,32 +15,6 @@ */ package examples.joins; -public class User { - private Integer userId; - private String userName; - private Integer parentId; +import org.jspecify.annotations.Nullable; - public Integer getUserId() { - return userId; - } - - public void setUserId(Integer userId) { - this.userId = userId; - } - - public String getUserName() { - return userName; - } - - public void setUserName(String userName) { - this.userName = userName; - } - - public Integer getParentId() { - return parentId; - } - - public void setParentId(Integer parentId) { - this.parentId = parentId; - } -} +public record User (Integer userId, String userName, @Nullable Integer parentId) {} diff --git a/src/test/java/examples/joins/package-info.java b/src/test/java/examples/joins/package-info.java new file mode 100644 index 000000000..a994448fb --- /dev/null +++ b/src/test/java/examples/joins/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package examples.joins; + +import org.jspecify.annotations.NullMarked; diff --git a/src/test/java/examples/type_conversion/package-info.java b/src/test/java/examples/type_conversion/package-info.java new file mode 100644 index 000000000..4848de776 --- /dev/null +++ b/src/test/java/examples/type_conversion/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package examples.type_conversion; + +import org.jspecify.annotations.NullMarked; From 5013d44b742efdc4cef8d6ead81c9d514acc7081 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 8 Apr 2025 10:12:13 -0400 Subject: [PATCH 250/260] Convert to record --- .../java/examples/joins/JoinMapperTest.java | 32 +++++++-------- .../java/examples/joins/JoinSubQueryTest.java | 14 +++---- src/test/java/examples/joins/OrderDetail.java | 39 +------------------ .../resources/examples/joins/JoinMapper.xml | 10 +++-- 4 files changed, 30 insertions(+), 65 deletions(-) diff --git a/src/test/java/examples/joins/JoinMapperTest.java b/src/test/java/examples/joins/JoinMapperTest.java index 6d6647219..1f1c6a27c 100644 --- a/src/test/java/examples/joins/JoinMapperTest.java +++ b/src/test/java/examples/joins/JoinMapperTest.java @@ -98,15 +98,15 @@ void testSingleTableJoin1() { assertThat(orderMaster.getId()).isEqualTo(1); assertThat(orderMaster.getDetails()).hasSize(2); OrderDetail orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); + assertThat(orderDetail.lineNumber()).isEqualTo(1); orderDetail = orderMaster.getDetails().get(1); - assertThat(orderDetail.getLineNumber()).isEqualTo(2); + assertThat(orderDetail.lineNumber()).isEqualTo(2); orderMaster = rows.get(1); assertThat(orderMaster.getId()).isEqualTo(2); assertThat(orderMaster.getDetails()).hasSize(1); orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); + assertThat(orderDetail.lineNumber()).isEqualTo(1); } } @@ -132,15 +132,15 @@ void testSingleTableJoin2() { assertThat(orderMaster.getId()).isEqualTo(1); assertThat(orderMaster.getDetails()).hasSize(2); OrderDetail orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); + assertThat(orderDetail.lineNumber()).isEqualTo(1); orderDetail = orderMaster.getDetails().get(1); - assertThat(orderDetail.getLineNumber()).isEqualTo(2); + assertThat(orderDetail.lineNumber()).isEqualTo(2); orderMaster = rows.get(1); assertThat(orderMaster.getId()).isEqualTo(2); assertThat(orderMaster.getDetails()).hasSize(1); orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); + assertThat(orderDetail.lineNumber()).isEqualTo(1); } } @@ -255,9 +255,9 @@ void testMultipleTableJoinWithWhereClause() { assertThat(orderMaster.getId()).isEqualTo(2); assertThat(orderMaster.getDetails()).hasSize(2); OrderDetail orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); + assertThat(orderDetail.lineNumber()).isEqualTo(1); orderDetail = orderMaster.getDetails().get(1); - assertThat(orderDetail.getLineNumber()).isEqualTo(2); + assertThat(orderDetail.lineNumber()).isEqualTo(2); } } @@ -286,9 +286,9 @@ void testMultipleTableJoinWithApplyWhere() { assertThat(orderMaster.getId()).isEqualTo(2); assertThat(orderMaster.getDetails()).hasSize(2); OrderDetail orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); + assertThat(orderDetail.lineNumber()).isEqualTo(1); orderDetail = orderMaster.getDetails().get(1); - assertThat(orderDetail.getLineNumber()).isEqualTo(2); + assertThat(orderDetail.lineNumber()).isEqualTo(2); } } @@ -317,7 +317,7 @@ void testMultipleTableJoinWithComplexWhereClause() { assertThat(orderMaster.getId()).isEqualTo(2); assertThat(orderMaster.getDetails()).hasSize(1); OrderDetail orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(2); + assertThat(orderDetail.lineNumber()).isEqualTo(2); } } @@ -346,15 +346,15 @@ void testMultipleTableJoinWithOrderBy() { assertThat(orderMaster.getId()).isEqualTo(1); assertThat(orderMaster.getDetails()).hasSize(1); OrderDetail orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); + assertThat(orderDetail.lineNumber()).isEqualTo(1); orderMaster = rows.get(1); assertThat(orderMaster.getId()).isEqualTo(2); assertThat(orderMaster.getDetails()).hasSize(2); orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); + assertThat(orderDetail.lineNumber()).isEqualTo(1); orderDetail = orderMaster.getDetails().get(1); - assertThat(orderDetail.getLineNumber()).isEqualTo(2); + assertThat(orderDetail.lineNumber()).isEqualTo(2); } } @@ -385,9 +385,9 @@ void testMultipleTableJoinNoAliasWithOrderBy() { assertThat(orderMaster.getId()).isEqualTo(2); assertThat(orderMaster.getDetails()).hasSize(2); OrderDetail orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); + assertThat(orderDetail.lineNumber()).isEqualTo(1); orderDetail = orderMaster.getDetails().get(1); - assertThat(orderDetail.getLineNumber()).isEqualTo(2); + assertThat(orderDetail.lineNumber()).isEqualTo(2); } } diff --git a/src/test/java/examples/joins/JoinSubQueryTest.java b/src/test/java/examples/joins/JoinSubQueryTest.java index 11b4ce192..abf3eaf6f 100644 --- a/src/test/java/examples/joins/JoinSubQueryTest.java +++ b/src/test/java/examples/joins/JoinSubQueryTest.java @@ -97,15 +97,15 @@ void testSingleTableJoin1() { assertThat(orderMaster.getId()).isEqualTo(1); assertThat(orderMaster.getDetails()).hasSize(2); OrderDetail orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); + assertThat(orderDetail.lineNumber()).isEqualTo(1); orderDetail = orderMaster.getDetails().get(1); - assertThat(orderDetail.getLineNumber()).isEqualTo(2); + assertThat(orderDetail.lineNumber()).isEqualTo(2); orderMaster = rows.get(1); assertThat(orderMaster.getId()).isEqualTo(2); assertThat(orderMaster.getDetails()).hasSize(1); orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); + assertThat(orderDetail.lineNumber()).isEqualTo(1); } } @@ -143,9 +143,9 @@ void testMultipleTableJoinWithWhereClause() { assertThat(orderMaster.getId()).isEqualTo(2); assertThat(orderMaster.getDetails()).hasSize(2); OrderDetail orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); + assertThat(orderDetail.lineNumber()).isEqualTo(1); orderDetail = orderMaster.getDetails().get(1); - assertThat(orderDetail.getLineNumber()).isEqualTo(2); + assertThat(orderDetail.lineNumber()).isEqualTo(2); } } @@ -180,10 +180,10 @@ void testMultipleTableJoinWithSelectStar() { assertThat(orderMaster.getDetails()).hasSize(2); OrderDetail orderDetail = orderMaster.getDetails().get(0); - assertThat(orderDetail.getLineNumber()).isEqualTo(1); + assertThat(orderDetail.lineNumber()).isEqualTo(1); orderDetail = orderMaster.getDetails().get(1); - assertThat(orderDetail.getLineNumber()).isEqualTo(2); + assertThat(orderDetail.lineNumber()).isEqualTo(2); } } diff --git a/src/test/java/examples/joins/OrderDetail.java b/src/test/java/examples/joins/OrderDetail.java index 6c9cdd8c5..9f9abd4ce 100644 --- a/src/test/java/examples/joins/OrderDetail.java +++ b/src/test/java/examples/joins/OrderDetail.java @@ -15,41 +15,4 @@ */ package examples.joins; -public class OrderDetail { - private Integer orderId; - private Integer lineNumber; - private String description; - private Integer quantity; - - public Integer getOrderId() { - return orderId; - } - - public void setOrderId(Integer orderId) { - this.orderId = orderId; - } - - public Integer getLineNumber() { - return lineNumber; - } - - public void setLineNumber(Integer lineNumber) { - this.lineNumber = lineNumber; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public Integer getQuantity() { - return quantity; - } - - public void setQuantity(Integer quantity) { - this.quantity = quantity; - } -} +public record OrderDetail (Integer orderId, Integer lineNumber, String description, Integer quantity) {} diff --git a/src/test/resources/examples/joins/JoinMapper.xml b/src/test/resources/examples/joins/JoinMapper.xml index e70e6b242..22aa930e9 100644 --- a/src/test/resources/examples/joins/JoinMapper.xml +++ b/src/test/resources/examples/joins/JoinMapper.xml @@ -22,10 +22,12 @@ <id column="order_id" jdbcType="INTEGER" property="id" /> <result column="order_date" jdbcType="DATE" property="orderDate" /> <collection property="details" ofType="examples.joins.OrderDetail"> - <id column="order_id" jdbcType="INTEGER" property="orderId"/> - <id column="line_number" jdbcType="INTEGER" property="lineNumber"/> - <result column="description" jdbcType="VARCHAR" property="description"/> - <result column="quantity" jdbcType="INTEGER" property="quantity"/> + <constructor> + <idArg column="order_id" jdbcType="INTEGER" javaType="Integer" /> + <idArg column="line_number" jdbcType="INTEGER" javaType="Integer" /> + <arg column="description" jdbcType="VARCHAR" javaType="String" /> + <arg column="quantity" jdbcType="INTEGER" javaType="Integer" /> + </constructor> </collection> </resultMap> </mapper> From 3ffc250a84d70f35948aee47331138b903e83b11 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 8 Apr 2025 13:11:24 -0400 Subject: [PATCH 251/260] Null Marking --- .../java/examples/mysql/IsLikeEscape.java | 2 -- .../examples/mysql/MemberOfCondition.java | 2 -- .../java/examples/mysql/MemberOfFunction.java | 2 -- src/test/java/examples/mysql/MySQLTest.java | 7 ++++--- .../java/examples/mysql/package-info.java | 19 +++++++++++++++++++ 5 files changed, 23 insertions(+), 9 deletions(-) create mode 100644 src/test/java/examples/mysql/package-info.java diff --git a/src/test/java/examples/mysql/IsLikeEscape.java b/src/test/java/examples/mysql/IsLikeEscape.java index 6b8799abb..418ff7141 100644 --- a/src/test/java/examples/mysql/IsLikeEscape.java +++ b/src/test/java/examples/mysql/IsLikeEscape.java @@ -19,14 +19,12 @@ import java.util.function.Function; import java.util.function.Predicate; -import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -@NullMarked public class IsLikeEscape<T> extends AbstractSingleValueCondition<T> implements AbstractSingleValueCondition.Filterable<T>, AbstractSingleValueCondition.Mappable<T> { private static final IsLikeEscape<?> EMPTY = new IsLikeEscape<Object>(-1, null) { diff --git a/src/test/java/examples/mysql/MemberOfCondition.java b/src/test/java/examples/mysql/MemberOfCondition.java index 33b967556..962ad5c38 100644 --- a/src/test/java/examples/mysql/MemberOfCondition.java +++ b/src/test/java/examples/mysql/MemberOfCondition.java @@ -17,10 +17,8 @@ import java.util.Objects; -import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.AbstractNoValueCondition; -@NullMarked public class MemberOfCondition<T> extends AbstractNoValueCondition<T> { private final String jsonArray; diff --git a/src/test/java/examples/mysql/MemberOfFunction.java b/src/test/java/examples/mysql/MemberOfFunction.java index 1035bf3e0..d41f95f8c 100644 --- a/src/test/java/examples/mysql/MemberOfFunction.java +++ b/src/test/java/examples/mysql/MemberOfFunction.java @@ -17,14 +17,12 @@ import java.util.Objects; -import org.jspecify.annotations.NullMarked; import org.mybatis.dynamic.sql.BasicColumn; import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingContext; import org.mybatis.dynamic.sql.select.function.AbstractTypeConvertingFunction; import org.mybatis.dynamic.sql.util.FragmentAndParameters; -@NullMarked public class MemberOfFunction<T> extends AbstractTypeConvertingFunction<T, Long, MemberOfFunction<T>> { private final String jsonArray; diff --git a/src/test/java/examples/mysql/MySQLTest.java b/src/test/java/examples/mysql/MySQLTest.java index 45c403bd7..d37b7de13 100644 --- a/src/test/java/examples/mysql/MySQLTest.java +++ b/src/test/java/examples/mysql/MySQLTest.java @@ -34,6 +34,7 @@ import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.render.RenderingStrategies; import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; @@ -51,10 +52,10 @@ class MySQLTest { new MySQLContainer<>(TestContainersConfiguration.MYSQL_LATEST) .withInitScript("examples/mariadb/CreateDB.sql"); - private static SqlSessionFactory sqlSessionFactory; + private SqlSessionFactory sqlSessionFactory; - @BeforeAll - static void setup() { + @BeforeEach + void setup() { UnpooledDataSource ds = new UnpooledDataSource(mysql.getDriverClassName(), mysql.getJdbcUrl(), mysql.getUsername(), mysql.getPassword()); Environment environment = new Environment("test", new JdbcTransactionFactory(), ds); diff --git a/src/test/java/examples/mysql/package-info.java b/src/test/java/examples/mysql/package-info.java new file mode 100644 index 000000000..70357075d --- /dev/null +++ b/src/test/java/examples/mysql/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package examples.mysql; + +import org.jspecify.annotations.NullMarked; From eb1a7049ab50c0cda3f05828c5cc54975d27efa6 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Tue, 8 Apr 2025 13:13:03 -0400 Subject: [PATCH 252/260] Null Marking --- .../java/examples/sharding/package-info.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/test/java/examples/sharding/package-info.java diff --git a/src/test/java/examples/sharding/package-info.java b/src/test/java/examples/sharding/package-info.java new file mode 100644 index 000000000..8c1f71235 --- /dev/null +++ b/src/test/java/examples/sharding/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package examples.sharding; + +import org.jspecify.annotations.NullMarked; From 0c6ec65cbc7a84b8b4358471f703627f93bb584f Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 9 Apr 2025 10:15:30 -0400 Subject: [PATCH 253/260] LastName can be a record --- src/test/java/examples/simple/LastName.java | 40 +------------------ .../examples/simple/LastNameTypeHandler.java | 13 ++++-- .../examples/simple/PersonMapperTest.java | 40 +++++++++---------- .../java/examples/simple/package-info.java | 19 +++++++++ 4 files changed, 49 insertions(+), 63 deletions(-) create mode 100644 src/test/java/examples/simple/package-info.java diff --git a/src/test/java/examples/simple/LastName.java b/src/test/java/examples/simple/LastName.java index 1caaef4e2..2a2499e14 100644 --- a/src/test/java/examples/simple/LastName.java +++ b/src/test/java/examples/simple/LastName.java @@ -15,42 +15,4 @@ */ package examples.simple; -public class LastName { - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public static LastName of(String name) { - LastName lastName = new LastName(); - lastName.setName(name); - return lastName; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - LastName other = (LastName) obj; - if (name == null) { - return other.name == null; - } else return name.equals(other.name); - } -} +public record LastName (String name) {} diff --git a/src/test/java/examples/simple/LastNameTypeHandler.java b/src/test/java/examples/simple/LastNameTypeHandler.java index e8a26486e..de14fcc0d 100644 --- a/src/test/java/examples/simple/LastNameTypeHandler.java +++ b/src/test/java/examples/simple/LastNameTypeHandler.java @@ -22,12 +22,17 @@ import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.TypeHandler; +import org.jspecify.annotations.Nullable; public class LastNameTypeHandler implements TypeHandler<LastName> { @Override - public void setParameter(PreparedStatement ps, int i, LastName parameter, JdbcType jdbcType) throws SQLException { - ps.setString(i, parameter == null ? null : parameter.getName()); + public void setParameter(PreparedStatement ps, int i, @Nullable LastName parameter, JdbcType jdbcType) throws SQLException { + if (parameter == null) { + ps.setNull(i, jdbcType.TYPE_CODE); + } else { + ps.setString(i, parameter.name()); + } } @Override @@ -45,7 +50,7 @@ public LastName getResult(CallableStatement cs, int columnIndex) throws SQLExcep return toLastName(cs.getString(columnIndex)); } - private LastName toLastName(String s) { - return s == null ? null : LastName.of(s); + private @Nullable LastName toLastName(@Nullable String s) { + return s == null ? null : new LastName(s); } } diff --git a/src/test/java/examples/simple/PersonMapperTest.java b/src/test/java/examples/simple/PersonMapperTest.java index acbda68ad..1fd44f5a3 100644 --- a/src/test/java/examples/simple/PersonMapperTest.java +++ b/src/test/java/examples/simple/PersonMapperTest.java @@ -245,8 +245,8 @@ void testFirstNameIn() { c.where(firstName, isIn("Fred", "Barney"))); assertThat(rows).hasSize(2); - assertThat(rows.get(0).getLastName().getName()).isEqualTo("Flintstone"); - assertThat(rows.get(1).getLastName().getName()).isEqualTo("Rubble"); + assertThat(rows.get(0).getLastName().name()).isEqualTo("Flintstone"); + assertThat(rows.get(1).getLastName().name()).isEqualTo("Rubble"); } } @@ -263,8 +263,8 @@ void testOrderByCollection() { ); assertThat(rows).hasSize(2); - assertThat(rows.get(0).getLastName().getName()).isEqualTo("Rubble"); - assertThat(rows.get(1).getLastName().getName()).isEqualTo("Flintstone"); + assertThat(rows.get(0).getLastName().name()).isEqualTo("Rubble"); + assertThat(rows.get(1).getLastName().name()).isEqualTo("Flintstone"); } } @@ -321,7 +321,7 @@ void testInsert() { PersonRecord row = new PersonRecord(); row.setId(100); row.setFirstName("Joe"); - row.setLastName(LastName.of("Jones")); + row.setLastName(new LastName("Jones")); row.setBirthDate(new Date()); row.setEmployed(true); row.setOccupation("Developer"); @@ -339,7 +339,7 @@ void testGeneralInsert() { int rows = mapper.generalInsert(c -> c.set(id).toValue(100) .set(firstName).toValue("Joe") - .set(lastName).toValue(LastName.of("Jones")) + .set(lastName).toValue(new LastName("Jones")) .set(birthDate).toValue(new Date()) .set(employed).toValue(true) .set(occupation).toValue("Developer") @@ -360,7 +360,7 @@ void testInsertMultiple() { PersonRecord row = new PersonRecord(); row.setId(100); row.setFirstName("Joe"); - row.setLastName(LastName.of("Jones")); + row.setLastName(new LastName("Jones")); row.setBirthDate(new Date()); row.setEmployed(true); row.setOccupation("Developer"); @@ -370,7 +370,7 @@ void testInsertMultiple() { row = new PersonRecord(); row.setId(101); row.setFirstName("Sarah"); - row.setLastName(LastName.of("Smith")); + row.setLastName(new LastName("Smith")); row.setBirthDate(new Date()); row.setEmployed(true); row.setOccupation("Architect"); @@ -389,7 +389,7 @@ void testInsertSelective() { PersonRecord row = new PersonRecord(); row.setId(100); row.setFirstName("Joe"); - row.setLastName(LastName.of("Jones")); + row.setLastName(new LastName("Jones")); row.setBirthDate(new Date()); row.setEmployed(false); row.setAddressId(1); @@ -406,7 +406,7 @@ void testUpdateByPrimaryKey() { PersonRecord row = new PersonRecord(); row.setId(100); row.setFirstName("Joe"); - row.setLastName(LastName.of("Jones")); + row.setLastName(new LastName("Jones")); row.setBirthDate(new Date()); row.setEmployed(true); row.setOccupation("Developer"); @@ -432,7 +432,7 @@ void testUpdateByPrimaryKeySelective() { PersonRecord row = new PersonRecord(); row.setId(100); row.setFirstName("Joe"); - row.setLastName(LastName.of("Jones")); + row.setLastName(new LastName("Jones")); row.setBirthDate(new Date()); row.setEmployed(true); row.setOccupation("Developer"); @@ -462,7 +462,7 @@ void testUpdate() { PersonRecord row = new PersonRecord(); row.setId(100); row.setFirstName("Joe"); - row.setLastName(LastName.of("Jones")); + row.setLastName(new LastName("Jones")); row.setBirthDate(new Date()); row.setEmployed(true); row.setOccupation("Developer"); @@ -493,7 +493,7 @@ void testUpdateOneField() { PersonRecord row = new PersonRecord(); row.setId(100); row.setFirstName("Joe"); - row.setLastName(LastName.of("Jones")); + row.setLastName(new LastName("Jones")); row.setBirthDate(new Date()); row.setEmployed(true); row.setOccupation("Developer"); @@ -521,7 +521,7 @@ void testUpdateAll() { PersonRecord row = new PersonRecord(); row.setId(100); row.setFirstName("Joe"); - row.setLastName(LastName.of("Jones")); + row.setLastName(new LastName("Jones")); row.setBirthDate(new Date()); row.setEmployed(true); row.setOccupation("Developer"); @@ -550,7 +550,7 @@ void testUpdateSelective() { PersonRecord row = new PersonRecord(); row.setId(100); row.setFirstName("Joe"); - row.setLastName(LastName.of("Jones")); + row.setLastName(new LastName("Jones")); row.setBirthDate(new Date()); row.setEmployed(true); row.setOccupation("Developer"); @@ -620,7 +620,7 @@ void testTypeHandledLike() { PersonMapper mapper = session.getMapper(PersonMapper.class); List<PersonRecord> rows = mapper.select(c -> - c.where(lastName, isLike(LastName.of("Fl%"))) + c.where(lastName, isLike(new LastName("Fl%"))) .orderBy(id)); assertThat(rows).hasSize(3); @@ -634,7 +634,7 @@ void testTypeHandledNotLike() { PersonMapper mapper = session.getMapper(PersonMapper.class); List<PersonRecord> rows = mapper.select(c -> - c.where(lastName, isNotLike(LastName.of("Fl%"))) + c.where(lastName, isNotLike(new LastName("Fl%"))) .orderBy(id)); assertThat(rows).hasSize(3); @@ -654,7 +654,7 @@ void testJoinAllRows() { assertThat(records.get(0).getId()).isEqualTo(1); assertThat(records.get(0).getEmployed()).isTrue(); assertThat(records.get(0).getFirstName()).isEqualTo("Fred"); - assertThat(records.get(0).getLastName()).isEqualTo(LastName.of("Flintstone")); + assertThat(records.get(0).getLastName()).isEqualTo(new LastName("Flintstone")); assertThat(records.get(0).getOccupation()).isEqualTo("Brontosaurus Operator"); assertThat(records.get(0).getBirthDate()).isNotNull(); assertThat(records.get(0).getAddress().getId()).isEqualTo(1); @@ -677,7 +677,7 @@ void testJoinOneRow() { assertThat(records.get(0).getId()).isEqualTo(1); assertThat(records.get(0).getEmployed()).isTrue(); assertThat(records.get(0).getFirstName()).isEqualTo("Fred"); - assertThat(records.get(0).getLastName()).isEqualTo(LastName.of("Flintstone")); + assertThat(records.get(0).getLastName()).isEqualTo(new LastName("Flintstone")); assertThat(records.get(0).getOccupation()).isEqualTo("Brontosaurus Operator"); assertThat(records.get(0).getBirthDate()).isNotNull(); assertThat(records.get(0).getAddress().getId()).isEqualTo(1); @@ -697,7 +697,7 @@ void testJoinPrimaryKey() { assertThat(r.getId()).isEqualTo(1); assertThat(r.getEmployed()).isTrue(); assertThat(r.getFirstName()).isEqualTo("Fred"); - assertThat(r.getLastName()).isEqualTo(LastName.of("Flintstone")); + assertThat(r.getLastName()).isEqualTo(new LastName("Flintstone")); assertThat(r.getOccupation()).isEqualTo("Brontosaurus Operator"); assertThat(r.getBirthDate()).isNotNull(); assertThat(r.getAddress().getId()).isEqualTo(1); diff --git a/src/test/java/examples/simple/package-info.java b/src/test/java/examples/simple/package-info.java new file mode 100644 index 000000000..79a124103 --- /dev/null +++ b/src/test/java/examples/simple/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package examples.simple; + +import org.jspecify.annotations.NullMarked; From 25f1fcbcb2ad38c96bcf15ce1ff5e6f206958dc9 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 9 Apr 2025 17:51:24 -0400 Subject: [PATCH 254/260] Use records where possible --- .../java/examples/simple/CompoundKeyRow.java | 21 +- .../examples/simple/MyBatisMapToRowTest.java | 15 +- .../java/examples/simple/PersonMapper.java | 100 +++++----- .../examples/simple/PersonMapperTest.java | 187 +++++++----------- .../java/examples/simple/PersonRecord.java | 70 +------ 5 files changed, 133 insertions(+), 260 deletions(-) diff --git a/src/test/java/examples/simple/CompoundKeyRow.java b/src/test/java/examples/simple/CompoundKeyRow.java index c710d4b26..dc65b005a 100644 --- a/src/test/java/examples/simple/CompoundKeyRow.java +++ b/src/test/java/examples/simple/CompoundKeyRow.java @@ -15,23 +15,4 @@ */ package examples.simple; -public class CompoundKeyRow { - private Integer id1; - private Integer id2; - - public Integer getId1() { - return id1; - } - - public void setId1(Integer id1) { - this.id1 = id1; - } - - public Integer getId2() { - return id2; - } - - public void setId2(Integer id2) { - this.id2 = id2; - } -} +public record CompoundKeyRow (Integer id1, Integer id2) {} diff --git a/src/test/java/examples/simple/MyBatisMapToRowTest.java b/src/test/java/examples/simple/MyBatisMapToRowTest.java index 473a4cd47..7750195e9 100644 --- a/src/test/java/examples/simple/MyBatisMapToRowTest.java +++ b/src/test/java/examples/simple/MyBatisMapToRowTest.java @@ -30,6 +30,7 @@ import java.sql.DriverManager; import java.util.List; import java.util.Map; +import java.util.function.Function; import java.util.stream.IntStream; import org.apache.ibatis.datasource.unpooled.UnpooledDataSource; @@ -98,7 +99,7 @@ void testInsertOne() { .orderBy(id1, id2) .build().render(RenderingStrategies.MYBATIS3); - List<CompoundKeyRow> records = mapper.selectMany(selectStatement, this::mapRow); + List<CompoundKeyRow> records = mapper.selectMany(selectStatement, rowMapper); assertThat(records).hasSize(1); } } @@ -128,7 +129,7 @@ void testInsertMultiple() { .orderBy(id1, id2) .build().render(RenderingStrategies.MYBATIS3); - List<CompoundKeyRow> records = mapper.selectMany(selectStatement, this::mapRow); + List<CompoundKeyRow> records = mapper.selectMany(selectStatement, rowMapper); assertThat(records).hasSize(3); } } @@ -165,15 +166,11 @@ void testInsertBatch() { .orderBy(id1, id2) .build().render(RenderingStrategies.MYBATIS3); - List<CompoundKeyRow> records = mapper.selectMany(selectStatement, this::mapRow); + List<CompoundKeyRow> records = mapper.selectMany(selectStatement, rowMapper); assertThat(records).hasSize(3); } } - private CompoundKeyRow mapRow(Map<String, Object> map) { - CompoundKeyRow answer = new CompoundKeyRow(); - answer.setId1((Integer) map.get("ID1")); - answer.setId2((Integer) map.get("ID2")); - return answer; - } + private final Function<Map<String, Object>, CompoundKeyRow> rowMapper = + m -> new CompoundKeyRow((Integer) m.get("ID1"), (Integer) m.get("ID2")); } diff --git a/src/test/java/examples/simple/PersonMapper.java b/src/test/java/examples/simple/PersonMapper.java index dffc66ee4..819b72c3b 100644 --- a/src/test/java/examples/simple/PersonMapper.java +++ b/src/test/java/examples/simple/PersonMapper.java @@ -17,17 +17,17 @@ import static examples.simple.PersonDynamicSqlSupport.*; import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo; +import static org.mybatis.dynamic.sql.SqlBuilder.isEqualToWhenPresent; import java.util.Arrays; import java.util.Collection; +import java.util.Date; import java.util.List; import java.util.Optional; import java.util.function.UnaryOperator; +import org.apache.ibatis.annotations.Arg; import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Result; -import org.apache.ibatis.annotations.ResultMap; -import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.SelectProvider; import org.apache.ibatis.type.JdbcType; import org.mybatis.dynamic.sql.BasicColumn; @@ -56,19 +56,23 @@ public interface PersonMapper extends CommonCountMapper, CommonDeleteMapper, CommonInsertMapper<PersonRecord>, CommonUpdateMapper { @SelectProvider(type=SqlProviderAdapter.class, method="select") - @Results(id="PersonResult", value= { - @Result(column="A_ID", property="id", jdbcType=JdbcType.INTEGER, id=true), - @Result(column="first_name", property="firstName", jdbcType=JdbcType.VARCHAR), - @Result(column="last_name", property="lastName", jdbcType=JdbcType.VARCHAR, typeHandler=LastNameTypeHandler.class), - @Result(column="birth_date", property="birthDate", jdbcType=JdbcType.DATE), - @Result(column="employed", property="employed", jdbcType=JdbcType.VARCHAR, typeHandler=YesNoTypeHandler.class), - @Result(column="occupation", property="occupation", jdbcType=JdbcType.VARCHAR), - @Result(column="address_id", property="addressId", jdbcType=JdbcType.INTEGER) - }) + @Arg(column="A_ID", jdbcType=JdbcType.INTEGER, id=true, javaType = Integer.class) + @Arg(column="first_name", jdbcType=JdbcType.VARCHAR, javaType = String.class) + @Arg(column="last_name", jdbcType=JdbcType.VARCHAR, typeHandler=LastNameTypeHandler.class, javaType = LastName.class) + @Arg(column="birth_date", jdbcType=JdbcType.DATE, javaType = Date.class) + @Arg(column="employed", jdbcType=JdbcType.VARCHAR, typeHandler=YesNoTypeHandler.class, javaType = Boolean.class) + @Arg(column="occupation", jdbcType=JdbcType.VARCHAR, javaType = String.class) + @Arg(column="address_id", jdbcType=JdbcType.INTEGER, javaType = Integer.class) List<PersonRecord> selectMany(SelectStatementProvider selectStatement); @SelectProvider(type=SqlProviderAdapter.class, method="select") - @ResultMap("PersonResult") + @Arg(column="A_ID", jdbcType=JdbcType.INTEGER, id=true, javaType = Integer.class) + @Arg(column="first_name", jdbcType=JdbcType.VARCHAR, javaType = String.class) + @Arg(column="last_name", jdbcType=JdbcType.VARCHAR, typeHandler=LastNameTypeHandler.class, javaType = LastName.class) + @Arg(column="birth_date", jdbcType=JdbcType.DATE, javaType = Date.class) + @Arg(column="employed", jdbcType=JdbcType.VARCHAR, typeHandler=YesNoTypeHandler.class, javaType = Boolean.class) + @Arg(column="occupation", jdbcType=JdbcType.VARCHAR, javaType = String.class) + @Arg(column="address_id", jdbcType=JdbcType.INTEGER, javaType = Integer.class) Optional<PersonRecord> selectOne(SelectStatementProvider selectStatement); BasicColumn[] selectList = @@ -130,13 +134,13 @@ default int insertMultiple(Collection<PersonRecord> records) { default int insertSelective(PersonRecord row) { return MyBatis3Utils.insert(this::insert, row, person, c -> - c.map(id).toPropertyWhenPresent("id", row::getId) - .map(firstName).toPropertyWhenPresent("firstName", row::getFirstName) - .map(lastName).toPropertyWhenPresent("lastName", row::getLastName) - .map(birthDate).toPropertyWhenPresent("birthDate", row::getBirthDate) - .map(employed).toPropertyWhenPresent("employed", row::getEmployed) - .map(occupation).toPropertyWhenPresent("occupation", row::getOccupation) - .map(addressId).toPropertyWhenPresent("addressId", row::getAddressId) + c.map(id).toPropertyWhenPresent("id", row::id) + .map(firstName).toPropertyWhenPresent("firstName", row::firstName) + .map(lastName).toPropertyWhenPresent("lastName", row::lastName) + .map(birthDate).toPropertyWhenPresent("birthDate", row::birthDate) + .map(employed).toPropertyWhenPresent("employed", row::employed) + .map(occupation).toPropertyWhenPresent("occupation", row::occupation) + .map(addressId).toPropertyWhenPresent("addressId", row::addressId) ); } @@ -164,47 +168,47 @@ default int update(UpdateDSLCompleter completer) { static UpdateDSL<UpdateModel> updateAllColumns(PersonRecord row, UpdateDSL<UpdateModel> dsl) { - return dsl.set(id).equalTo(row::getId) - .set(firstName).equalTo(row::getFirstName) - .set(lastName).equalTo(row::getLastName) - .set(birthDate).equalTo(row::getBirthDate) - .set(employed).equalTo(row::getEmployed) - .set(occupation).equalTo(row::getOccupation) - .set(addressId).equalTo(row::getAddressId); + return dsl.set(id).equalToOrNull(row::id) + .set(firstName).equalToOrNull(row::firstName) + .set(lastName).equalToOrNull(row::lastName) + .set(birthDate).equalToOrNull(row::birthDate) + .set(employed).equalToOrNull(row::employed) + .set(occupation).equalToOrNull(row::occupation) + .set(addressId).equalToOrNull(row::addressId); } static UpdateDSL<UpdateModel> updateSelectiveColumns(PersonRecord row, UpdateDSL<UpdateModel> dsl) { - return dsl.set(id).equalToWhenPresent(row::getId) - .set(firstName).equalToWhenPresent(row::getFirstName) - .set(lastName).equalToWhenPresent(row::getLastName) - .set(birthDate).equalToWhenPresent(row::getBirthDate) - .set(employed).equalToWhenPresent(row::getEmployed) - .set(occupation).equalToWhenPresent(row::getOccupation) - .set(addressId).equalToWhenPresent(row::getAddressId); + return dsl.set(id).equalToWhenPresent(row::id) + .set(firstName).equalToWhenPresent(row::firstName) + .set(lastName).equalToWhenPresent(row::lastName) + .set(birthDate).equalToWhenPresent(row::birthDate) + .set(employed).equalToWhenPresent(row::employed) + .set(occupation).equalToWhenPresent(row::occupation) + .set(addressId).equalToWhenPresent(row::addressId); } default int updateByPrimaryKey(PersonRecord row) { return update(c -> - c.set(firstName).equalTo(row::getFirstName) - .set(lastName).equalTo(row::getLastName) - .set(birthDate).equalTo(row::getBirthDate) - .set(employed).equalTo(row::getEmployed) - .set(occupation).equalTo(row::getOccupation) - .set(addressId).equalTo(row::getAddressId) - .where(id, isEqualTo(row::getId)) + c.set(firstName).equalToOrNull(row::firstName) + .set(lastName).equalToOrNull(row::lastName) + .set(birthDate).equalToOrNull(row::birthDate) + .set(employed).equalToOrNull(row::employed) + .set(occupation).equalToOrNull(row::occupation) + .set(addressId).equalToOrNull(row::addressId) + .where(id, isEqualToWhenPresent(row::id)) ); } default int updateByPrimaryKeySelective(PersonRecord row) { return update(c -> - c.set(firstName).equalToWhenPresent(row::getFirstName) - .set(lastName).equalToWhenPresent(row::getLastName) - .set(birthDate).equalToWhenPresent(row::getBirthDate) - .set(employed).equalToWhenPresent(row::getEmployed) - .set(occupation).equalToWhenPresent(row::getOccupation) - .set(addressId).equalToWhenPresent(row::getAddressId) - .where(id, isEqualTo(row::getId)) + c.set(firstName).equalToWhenPresent(row::firstName) + .set(lastName).equalToWhenPresent(row::lastName) + .set(birthDate).equalToWhenPresent(row::birthDate) + .set(employed).equalToWhenPresent(row::employed) + .set(occupation).equalToWhenPresent(row::occupation) + .set(addressId).equalToWhenPresent(row::addressId) + .where(id, isEqualToWhenPresent(row::id)) ); } } diff --git a/src/test/java/examples/simple/PersonMapperTest.java b/src/test/java/examples/simple/PersonMapperTest.java index 1fd44f5a3..b02d52c4c 100644 --- a/src/test/java/examples/simple/PersonMapperTest.java +++ b/src/test/java/examples/simple/PersonMapperTest.java @@ -25,6 +25,7 @@ import static examples.simple.PersonDynamicSqlSupport.occupation; import static examples.simple.PersonDynamicSqlSupport.person; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.assertj.core.api.Assertions.entry; import static org.mybatis.dynamic.sql.SqlBuilder.*; @@ -32,7 +33,6 @@ import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DriverManager; -import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; @@ -51,6 +51,7 @@ import org.mybatis.dynamic.sql.SortSpecification; import org.mybatis.dynamic.sql.delete.DeleteDSLCompleter; import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider; +import org.mybatis.dynamic.sql.exception.NonRenderingWhereClauseException; import org.mybatis.dynamic.sql.insert.render.GeneralInsertStatementProvider; import org.mybatis.dynamic.sql.render.RenderingStrategies; import org.mybatis.dynamic.sql.select.CountDSLCompleter; @@ -108,7 +109,7 @@ void testSelectEmployed() { .orderBy(id)); assertThat(rows).hasSize(4); - assertThat(rows.get(0).getId()).isEqualTo(1); + assertThat(rows.get(0).id()).isEqualTo(1); } } @@ -122,7 +123,7 @@ void testSelectUnemployed() { .orderBy(id)); assertThat(rows).hasSize(2); - assertThat(rows.get(0).getId()).isEqualTo(3); + assertThat(rows.get(0).id()).isEqualTo(3); } } @@ -179,8 +180,8 @@ void testSelectAll() { List<PersonRecord> rows = mapper.select(SelectDSLCompleter.allRows()); assertThat(rows).hasSize(6); - assertThat(rows.get(0).getId()).isEqualTo(1); - assertThat(rows.get(5).getId()).isEqualTo(6); + assertThat(rows.get(0).id()).isEqualTo(1); + assertThat(rows.get(5).id()).isEqualTo(6); } } @@ -193,8 +194,8 @@ void testSelectAllOrdered() { .select(SelectDSLCompleter.allRowsOrderedBy(lastName.descending(), firstName.descending())); assertThat(rows).hasSize(6); - assertThat(rows.get(0).getId()).isEqualTo(5); - assertThat(rows.get(5).getId()).isEqualTo(1); + assertThat(rows.get(0).id()).isEqualTo(5); + assertThat(rows.get(5).id()).isEqualTo(1); } } @@ -221,8 +222,8 @@ void testSelectWithTypeHandler() { .orderBy(id)); assertThat(rows).hasSize(2); - assertThat(rows.get(0).getId()).isEqualTo(3); - assertThat(rows.get(1).getId()).isEqualTo(6); + assertThat(rows.get(0).id()).isEqualTo(3); + assertThat(rows.get(1).id()).isEqualTo(6); } } @@ -245,8 +246,14 @@ void testFirstNameIn() { c.where(firstName, isIn("Fred", "Barney"))); assertThat(rows).hasSize(2); - assertThat(rows.get(0).getLastName().name()).isEqualTo("Flintstone"); - assertThat(rows.get(1).getLastName().name()).isEqualTo("Rubble"); + assertThat(rows.get(0)) + .isNotNull() + .extracting("lastName").isNotNull() + .extracting("name").isEqualTo("Flintstone"); + assertThat(rows.get(1)) + .isNotNull() + .extracting("lastName").isNotNull() + .extracting("name").isEqualTo("Rubble"); } } @@ -263,8 +270,14 @@ void testOrderByCollection() { ); assertThat(rows).hasSize(2); - assertThat(rows.get(0).getLastName().name()).isEqualTo("Rubble"); - assertThat(rows.get(1).getLastName().name()).isEqualTo("Flintstone"); + assertThat(rows.get(0)) + .isNotNull() + .extracting("lastName").isNotNull() + .extracting("name").isEqualTo("Rubble"); + assertThat(rows.get(1)) + .isNotNull() + .extracting("lastName").isNotNull() + .extracting("name").isEqualTo("Flintstone"); } } @@ -318,14 +331,7 @@ void testDeleteByPrimaryKey() { void testInsert() { try (SqlSession session = sqlSessionFactory.openSession()) { PersonMapper mapper = session.getMapper(PersonMapper.class); - PersonRecord row = new PersonRecord(); - row.setId(100); - row.setFirstName("Joe"); - row.setLastName(new LastName("Jones")); - row.setBirthDate(new Date()); - row.setEmployed(true); - row.setOccupation("Developer"); - row.setAddressId(1); + PersonRecord row = new PersonRecord(100, "Joe", new LastName("Jones"), new Date(), true, "Developer", 1); int rows = mapper.insert(row); assertThat(rows).isEqualTo(1); @@ -355,27 +361,10 @@ void testInsertMultiple() { try (SqlSession session = sqlSessionFactory.openSession()) { PersonMapper mapper = session.getMapper(PersonMapper.class); - List<PersonRecord> records = new ArrayList<>(); - - PersonRecord row = new PersonRecord(); - row.setId(100); - row.setFirstName("Joe"); - row.setLastName(new LastName("Jones")); - row.setBirthDate(new Date()); - row.setEmployed(true); - row.setOccupation("Developer"); - row.setAddressId(1); - records.add(row); - - row = new PersonRecord(); - row.setId(101); - row.setFirstName("Sarah"); - row.setLastName(new LastName("Smith")); - row.setBirthDate(new Date()); - row.setEmployed(true); - row.setOccupation("Architect"); - row.setAddressId(2); - records.add(row); + List<PersonRecord> records = List.of( + new PersonRecord(100, "Joe", new LastName("Jones"), new Date(), true, "Developer", 1), + new PersonRecord(101, "Sarah", new LastName("Smith"), new Date(), true, "Architect", 2) + ); int rows = mapper.insertMultiple(records); assertThat(rows).isEqualTo(2); @@ -386,42 +375,39 @@ void testInsertMultiple() { void testInsertSelective() { try (SqlSession session = sqlSessionFactory.openSession()) { PersonMapper mapper = session.getMapper(PersonMapper.class); - PersonRecord row = new PersonRecord(); - row.setId(100); - row.setFirstName("Joe"); - row.setLastName(new LastName("Jones")); - row.setBirthDate(new Date()); - row.setEmployed(false); - row.setAddressId(1); + PersonRecord row = new PersonRecord(100, "Joe", new LastName("Jones"), new Date(), false, null, 1); int rows = mapper.insertSelective(row); assertThat(rows).isEqualTo(1); } } + @Test + void testUpdateByPrimaryKeyNullKeyShouldThrowException() { + try (SqlSession session = sqlSessionFactory.openSession()) { + PersonMapper mapper = session.getMapper(PersonMapper.class); + PersonRecord row = new PersonRecord(null, "Joe", new LastName("Jones"), new Date(), true, "Developer", 1); + + assertThatExceptionOfType(NonRenderingWhereClauseException.class).isThrownBy(() -> mapper.updateByPrimaryKey(row)); + } + } + @Test void testUpdateByPrimaryKey() { try (SqlSession session = sqlSessionFactory.openSession()) { PersonMapper mapper = session.getMapper(PersonMapper.class); - PersonRecord row = new PersonRecord(); - row.setId(100); - row.setFirstName("Joe"); - row.setLastName(new LastName("Jones")); - row.setBirthDate(new Date()); - row.setEmployed(true); - row.setOccupation("Developer"); - row.setAddressId(1); + PersonRecord row = new PersonRecord(100, "Joe", new LastName("Jones"), new Date(), true, "Developer", 1); int rows = mapper.insert(row); assertThat(rows).isEqualTo(1); - row.setOccupation("Programmer"); + row = row.withOccupation("Programmer"); rows = mapper.updateByPrimaryKey(row); assertThat(rows).isEqualTo(1); Optional<PersonRecord> newRecord = mapper.selectByPrimaryKey(100); assertThat(newRecord).hasValueSatisfying(r -> - assertThat(r.getOccupation()).isEqualTo("Programmer")); + assertThat(r.occupation()).isEqualTo("Programmer")); } } @@ -429,28 +415,19 @@ void testUpdateByPrimaryKey() { void testUpdateByPrimaryKeySelective() { try (SqlSession session = sqlSessionFactory.openSession()) { PersonMapper mapper = session.getMapper(PersonMapper.class); - PersonRecord row = new PersonRecord(); - row.setId(100); - row.setFirstName("Joe"); - row.setLastName(new LastName("Jones")); - row.setBirthDate(new Date()); - row.setEmployed(true); - row.setOccupation("Developer"); - row.setAddressId(1); + PersonRecord row = new PersonRecord(100, "Joe", new LastName("Jones"), new Date(), true, "Developer", 1); int rows = mapper.insert(row); assertThat(rows).isEqualTo(1); - PersonRecord updateRecord = new PersonRecord(); - updateRecord.setId(100); - updateRecord.setOccupation("Programmer"); + PersonRecord updateRecord = new PersonRecord(100, null, null, null, null, "Programmer", null); rows = mapper.updateByPrimaryKeySelective(updateRecord); assertThat(rows).isEqualTo(1); Optional<PersonRecord> newRecord = mapper.selectByPrimaryKey(100); assertThat(newRecord).hasValueSatisfying(r -> { - assertThat(r.getOccupation()).isEqualTo("Programmer"); - assertThat(r.getFirstName()).isEqualTo("Joe"); + assertThat(r.occupation()).isEqualTo("Programmer"); + assertThat(r.firstName()).isEqualTo("Joe"); }); } } @@ -459,22 +436,15 @@ void testUpdateByPrimaryKeySelective() { void testUpdate() { try (SqlSession session = sqlSessionFactory.openSession()) { PersonMapper mapper = session.getMapper(PersonMapper.class); - PersonRecord row = new PersonRecord(); - row.setId(100); - row.setFirstName("Joe"); - row.setLastName(new LastName("Jones")); - row.setBirthDate(new Date()); - row.setEmployed(true); - row.setOccupation("Developer"); - row.setAddressId(1); + PersonRecord row = new PersonRecord(100, "Joe", new LastName("Jones"), new Date(), true, "Developer", 1); int rows = mapper.insert(row); assertThat(rows).isEqualTo(1); - row.setOccupation("Programmer"); + PersonRecord updateRow = row.withOccupation("Programmer"); rows = mapper.update(c -> - PersonMapper.updateAllColumns(row, c) + PersonMapper.updateAllColumns(updateRow, c) .where(id, isEqualTo(100)) .and(firstName, isEqualTo("Joe"))); @@ -482,7 +452,7 @@ void testUpdate() { Optional<PersonRecord> newRecord = mapper.selectByPrimaryKey(100); assertThat(newRecord).hasValueSatisfying(r -> - assertThat(r.getOccupation()).isEqualTo("Programmer")); + assertThat(r.occupation()).isEqualTo("Programmer")); } } @@ -490,14 +460,7 @@ void testUpdate() { void testUpdateOneField() { try (SqlSession session = sqlSessionFactory.openSession()) { PersonMapper mapper = session.getMapper(PersonMapper.class); - PersonRecord row = new PersonRecord(); - row.setId(100); - row.setFirstName("Joe"); - row.setLastName(new LastName("Jones")); - row.setBirthDate(new Date()); - row.setEmployed(true); - row.setOccupation("Developer"); - row.setAddressId(1); + PersonRecord row = new PersonRecord(100, "Joe", new LastName("Jones"), new Date(), true, "Developer", 1); int rows = mapper.insert(row); assertThat(rows).isEqualTo(1); @@ -510,7 +473,7 @@ void testUpdateOneField() { Optional<PersonRecord> newRecord = mapper.selectByPrimaryKey(100); assertThat(newRecord).hasValueSatisfying(r -> - assertThat(r.getOccupation()).isEqualTo("Programmer")); + assertThat(r.occupation()).isEqualTo("Programmer")); } } @@ -518,20 +481,12 @@ void testUpdateOneField() { void testUpdateAll() { try (SqlSession session = sqlSessionFactory.openSession()) { PersonMapper mapper = session.getMapper(PersonMapper.class); - PersonRecord row = new PersonRecord(); - row.setId(100); - row.setFirstName("Joe"); - row.setLastName(new LastName("Jones")); - row.setBirthDate(new Date()); - row.setEmployed(true); - row.setOccupation("Developer"); - row.setAddressId(1); + PersonRecord row = new PersonRecord(100, "Joe", new LastName("Jones"), new Date(), true, "Developer", 1); int rows = mapper.insert(row); assertThat(rows).isEqualTo(1); - PersonRecord updateRecord = new PersonRecord(); - updateRecord.setOccupation("Programmer"); + PersonRecord updateRecord = new PersonRecord(null, null, null, null, null, "Programmer", null); rows = mapper.update(c -> PersonMapper.updateSelectiveColumns(updateRecord, c)); @@ -539,7 +494,7 @@ void testUpdateAll() { Optional<PersonRecord> newRecord = mapper.selectByPrimaryKey(100); assertThat(newRecord).hasValueSatisfying(r -> - assertThat(r.getOccupation()).isEqualTo("Programmer")); + assertThat(r.occupation()).isEqualTo("Programmer")); } } @@ -547,20 +502,12 @@ void testUpdateAll() { void testUpdateSelective() { try (SqlSession session = sqlSessionFactory.openSession()) { PersonMapper mapper = session.getMapper(PersonMapper.class); - PersonRecord row = new PersonRecord(); - row.setId(100); - row.setFirstName("Joe"); - row.setLastName(new LastName("Jones")); - row.setBirthDate(new Date()); - row.setEmployed(true); - row.setOccupation("Developer"); - row.setAddressId(1); + PersonRecord row = new PersonRecord(100, "Joe", new LastName("Jones"), new Date(), true, "Developer", 1); int rows = mapper.insert(row); assertThat(rows).isEqualTo(1); - PersonRecord updateRecord = new PersonRecord(); - updateRecord.setOccupation("Programmer"); + PersonRecord updateRecord = new PersonRecord(null, null, null, null, null, "Programmer", null); rows = mapper.update(c -> PersonMapper.updateSelectiveColumns(updateRecord, c) .where(id, isEqualTo(100))); @@ -569,7 +516,7 @@ void testUpdateSelective() { Optional<PersonRecord> newRecord = mapper.selectByPrimaryKey(100); assertThat(newRecord).hasValueSatisfying(r -> - assertThat(r.getOccupation()).isEqualTo("Programmer")); + assertThat(r.occupation()).isEqualTo("Programmer")); } } @@ -624,7 +571,7 @@ void testTypeHandledLike() { .orderBy(id)); assertThat(rows).hasSize(3); - assertThat(rows.get(0).getFirstName()).isEqualTo("Fred"); + assertThat(rows.get(0).firstName()).isEqualTo("Fred"); } } @@ -638,7 +585,7 @@ void testTypeHandledNotLike() { .orderBy(id)); assertThat(rows).hasSize(3); - assertThat(rows.get(0).getFirstName()).isEqualTo("Barney"); + assertThat(rows.get(0).firstName()).isEqualTo("Barney"); } } @@ -807,8 +754,8 @@ void testMultiSelectWithUnion() { List<PersonRecord> records = mapper.selectMany(selectStatement); assertThat(records).hasSize(2); - assertThat(records.get(0).getId()).isEqualTo(1); - assertThat(records.get(1).getId()).isEqualTo(6); + assertThat(records.get(0).id()).isEqualTo(1); + assertThat(records.get(1).id()).isEqualTo(6); } } @@ -852,8 +799,8 @@ void testMultiSelectWithUnionAll() { List<PersonRecord> records = mapper.selectMany(selectStatement); assertThat(records).hasSize(2); - assertThat(records.get(0).getId()).isEqualTo(1); - assertThat(records.get(1).getId()).isEqualTo(6); + assertThat(records.get(0).id()).isEqualTo(1); + assertThat(records.get(1).id()).isEqualTo(6); } } diff --git a/src/test/java/examples/simple/PersonRecord.java b/src/test/java/examples/simple/PersonRecord.java index bb7702cc1..10a9d9edf 100644 --- a/src/test/java/examples/simple/PersonRecord.java +++ b/src/test/java/examples/simple/PersonRecord.java @@ -15,70 +15,14 @@ */ package examples.simple; -import java.util.Date; - -public class PersonRecord { - private Integer id; - private String firstName; - private LastName lastName; - private Date birthDate; - private Boolean employed; - private String occupation; - private Integer addressId; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public LastName getLastName() { - return lastName; - } - - public void setLastName(LastName lastName) { - this.lastName = lastName; - } +import org.jspecify.annotations.Nullable; - public Date getBirthDate() { - return birthDate; - } - - public void setBirthDate(Date birthDate) { - this.birthDate = birthDate; - } - - public String getOccupation() { - return occupation; - } - - public void setOccupation(String occupation) { - this.occupation = occupation; - } - - public Boolean getEmployed() { - return employed; - } - - public void setEmployed(Boolean employed) { - this.employed = employed; - } - - public Integer getAddressId() { - return addressId; - } +import java.util.Date; - public void setAddressId(Integer addressId) { - this.addressId = addressId; +public record PersonRecord (@Nullable Integer id, @Nullable String firstName, @Nullable LastName lastName, + @Nullable Date birthDate, @Nullable Boolean employed, @Nullable String occupation, + @Nullable Integer addressId) { + public PersonRecord withOccupation(String occupation) { + return new PersonRecord(id, firstName, lastName, birthDate, employed, occupation, addressId); } } From baf165dbfec85bf8ce37fc413acfa601bcc009c3 Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Wed, 9 Apr 2025 17:52:12 -0400 Subject: [PATCH 255/260] Unused import --- src/test/java/examples/mysql/MySQLTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/examples/mysql/MySQLTest.java b/src/test/java/examples/mysql/MySQLTest.java index d37b7de13..f9c047f77 100644 --- a/src/test/java/examples/mysql/MySQLTest.java +++ b/src/test/java/examples/mysql/MySQLTest.java @@ -33,7 +33,6 @@ import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mybatis.dynamic.sql.render.RenderingStrategies; From e1ea69d04e33a433f5ad8d987b662fef116169ee Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 10 Apr 2025 13:19:24 -0400 Subject: [PATCH 256/260] Use record --- .../dynamic/sql/util/spring/BatchInsertUtility.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/main/java/org/mybatis/dynamic/sql/util/spring/BatchInsertUtility.java b/src/main/java/org/mybatis/dynamic/sql/util/spring/BatchInsertUtility.java index 81f5a5ed6..8672e98ea 100644 --- a/src/main/java/org/mybatis/dynamic/sql/util/spring/BatchInsertUtility.java +++ b/src/main/java/org/mybatis/dynamic/sql/util/spring/BatchInsertUtility.java @@ -39,15 +39,5 @@ public static <T> SqlParameterSource[] createBatch(List<T> rows) { return SqlParameterSourceUtils.createBatch(tt); } - public static class RowHolder<T> { - private final T row; - - public RowHolder(T row) { - this.row = row; - } - - public T getRow() { - return row; - } - } + public record RowHolder<T> (T row) {} } From 0848d7c6fbe3815bc1f36754fdd40da7baf07eac Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Thu, 10 Apr 2025 13:20:25 -0400 Subject: [PATCH 257/260] Random cleanup --- src/test/java/issues/gh105/Issue105Test.java | 13 ++++--------- .../sql/insert/GeneralInsertStatementTest.java | 6 ++---- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/test/java/issues/gh105/Issue105Test.java b/src/test/java/issues/gh105/Issue105Test.java index c12f4fde9..63d2b2f16 100644 --- a/src/test/java/issues/gh105/Issue105Test.java +++ b/src/test/java/issues/gh105/Issue105Test.java @@ -49,12 +49,11 @@ void testFuzzyLikeBothPresent() { @Test void testFuzzyLikeFirstNameNull() { - String fName = null; String lName = "Flintstone"; SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(firstName, isLikeWhenPresent(fName).map(SearchUtils::addWildcards)) + .where(firstName, isLikeWhenPresent((String) null).map(SearchUtils::addWildcards)) .and(lastName, isLike(lName).map(SearchUtils::addWildcards)) .build() .render(RenderingStrategies.MYBATIS3); @@ -70,12 +69,11 @@ void testFuzzyLikeFirstNameNull() { @Test void testFuzzyLikeLastNameNull() { String fName = "Fred"; - String lName = null; SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) .where(firstName, isLike(fName).map(SearchUtils::addWildcards)) - .and(lastName, isLikeWhenPresent(lName).map(SearchUtils::addWildcards)) + .and(lastName, isLikeWhenPresent((String) null).map(SearchUtils::addWildcards)) .build() .render(RenderingStrategies.MYBATIS3); @@ -89,13 +87,10 @@ void testFuzzyLikeLastNameNull() { @Test void testFuzzyLikeBothNull() { - String fName = null; - String lName = null; - SelectStatementProvider selectStatement = select(id, firstName, lastName) .from(person) - .where(firstName, isLikeWhenPresent(fName).map(SearchUtils::addWildcards)) - .and(lastName, isLikeWhenPresent(lName).map(SearchUtils::addWildcards)) + .where(firstName, isLikeWhenPresent((String) null).map(SearchUtils::addWildcards)) + .and(lastName, isLikeWhenPresent((String) null).map(SearchUtils::addWildcards)) .configureStatement(c -> c.setNonRenderingWhereClauseAllowed(true)) .build() .render(RenderingStrategies.MYBATIS3); diff --git a/src/test/java/org/mybatis/dynamic/sql/insert/GeneralInsertStatementTest.java b/src/test/java/org/mybatis/dynamic/sql/insert/GeneralInsertStatementTest.java index 5c470cdcc..22813df69 100644 --- a/src/test/java/org/mybatis/dynamic/sql/insert/GeneralInsertStatementTest.java +++ b/src/test/java/org/mybatis/dynamic/sql/insert/GeneralInsertStatementTest.java @@ -85,14 +85,12 @@ void testInsertStatementBuilderWithConstants() { @Test void testSelectiveInsertStatementBuilder() { - Integer myId = null; - String myFirstName = null; String myLastName = "jones"; String myOccupation = "dino driver"; GeneralInsertStatementProvider insertStatement = insertInto(foo) - .set(id).toValueWhenPresent(() -> myId) - .set(firstName).toValueWhenPresent(myFirstName) + .set(id).toValueWhenPresent(() -> null) + .set(firstName).toValueWhenPresent((String) null) .set(lastName).toValueWhenPresent(() -> myLastName) .set(occupation).toValueWhenPresent(myOccupation) .build() From b0e8124270105bc55d4ae18850db241a9a97807e Mon Sep 17 00:00:00 2001 From: Jeff Butler <jeffgbutler@gmail.com> Date: Fri, 11 Apr 2025 09:36:27 -0400 Subject: [PATCH 258/260] Null mark by package --- .../examples/emptywhere/EmptyWhereTest.java | 2 -- .../examples/emptywhere/package-info.java | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 src/test/java/examples/emptywhere/package-info.java diff --git a/src/test/java/examples/emptywhere/EmptyWhereTest.java b/src/test/java/examples/emptywhere/EmptyWhereTest.java index f20a81a9a..6d6ea5ba7 100644 --- a/src/test/java/examples/emptywhere/EmptyWhereTest.java +++ b/src/test/java/examples/emptywhere/EmptyWhereTest.java @@ -23,7 +23,6 @@ import java.util.Optional; import java.util.stream.Stream; -import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -41,7 +40,6 @@ import org.mybatis.dynamic.sql.where.WhereDSL; import org.mybatis.dynamic.sql.where.render.WhereClauseProvider; -@NullMarked class EmptyWhereTest { private static final String FIRST_NAME = "Fred"; private static final String LAST_NAME = "Flintstone"; diff --git a/src/test/java/examples/emptywhere/package-info.java b/src/test/java/examples/emptywhere/package-info.java new file mode 100644 index 000000000..89f32f987 --- /dev/null +++ b/src/test/java/examples/emptywhere/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2016-2025 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 + * + * https://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. + */ +@NullMarked +package examples.emptywhere; + +import org.jspecify.annotations.NullMarked; From e52797c8274ac6734669cb6064848b455a2f716e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 11 Apr 2025 18:53:53 +0000 Subject: [PATCH 259/260] Update junit5 monorepo to v5.12.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 665634e5d..677844711 100644 --- a/pom.xml +++ b/pom.xml @@ -60,7 +60,7 @@ <java.release.version>17</java.release.version> <java.test.version>17</java.test.version> <java.test.release.version>17</java.test.release.version> - <junit.jupiter.version>5.12.1</junit.jupiter.version> + <junit.jupiter.version>5.12.2</junit.jupiter.version> <spring.batch.version>5.2.2</spring.batch.version> <checkstyle.config>checkstyle-override.xml</checkstyle.config> From ae4bc67ba96fc73eca3f02caeef406d50dc9500c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 17 Apr 2025 12:03:21 +0000 Subject: [PATCH 260/260] Update dependency org.springframework:spring-jdbc to v6.2.6 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 677844711..e1e1f613d 100644 --- a/pom.xml +++ b/pom.xml @@ -103,7 +103,7 @@ <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> - <version>6.2.5</version> + <version>6.2.6</version> <scope>provided</scope> <optional>true</optional> </dependency>