diff --git a/CHANGELOG.md b/CHANGELOG.md index 3783d2b89..813c7be34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,12 @@ GitHub milestone: [https://github.com/mybatis/mybatis-dynamic-sql/issues?q=miles ### Added -- Changed the public SQLBuilder API to accept Collection instead of List for in conditions and batch record inserts. This should have no impact on existing code, but allow for some future flexibility -- Added the ability have have table catalog and/or schema calculated at query runtime. This is useful for situations where there are different database schemas for different environments, or in some sharding situations -- Added the ability to call a builder method on any intermediate object in a select statement and receive a fully rendered statement. This makes it easier to build very dynamic queries +- Changed the public SQLBuilder API to accept Collection instead of List for in conditions and batch record inserts. This should have no impact on existing code, but allow for some future flexibility [#88](https://github.com/mybatis/mybatis-dynamic-sql/pull/88) +- Added the ability have have table catalog and/or schema calculated at query runtime. This is useful for situations where there are different database schemas for different environments, or in some sharding situations [#92](https://github.com/mybatis/mybatis-dynamic-sql/pull/92) +- Add support for paging queries with "offset" and "fetch first" - this seems to be standard on most databases [#96](https://github.com/mybatis/mybatis-dynamic-sql/pull/96) +- Added the ability to call a builder method on any intermediate object in a select statement and receive a fully rendered statement. This makes it easier to build very dynamic queries [#106](https://github.com/mybatis/mybatis-dynamic-sql/pull/106) +- Add the ability to modify values on any condition before they are placed in the parameter map [#105](https://github.com/mybatis/mybatis-dynamic-sql/issues/105) +- Add the ability to call `where()` with no parameters. This aids in constructing very dynamic queries [#107](https://github.com/mybatis/mybatis-dynamic-sql/issues/107) ## Release 1.1.1 - April 7, 2019 diff --git a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java index 18daee42a..e7544e9f9 100644 --- a/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java +++ b/src/main/java/org/mybatis/dynamic/sql/AbstractListValueCondition.java @@ -24,19 +24,19 @@ public abstract class AbstractListValueCondition implements VisitableCondition { protected Collection values; - protected UnaryOperator> valueStreamOperations; + protected UnaryOperator> valueStreamTransformer; protected AbstractListValueCondition(Collection values) { this(values, UnaryOperator.identity()); } - protected AbstractListValueCondition(Collection values, UnaryOperator> valueStreamOperations) { + protected AbstractListValueCondition(Collection values, UnaryOperator> valueStreamTransformer) { this.values = new ArrayList<>(Objects.requireNonNull(values)); - this.valueStreamOperations = Objects.requireNonNull(valueStreamOperations); + this.valueStreamTransformer = Objects.requireNonNull(valueStreamTransformer); } public final Stream mapValues(Function mapper) { - return valueStreamOperations.apply(values.stream()).map(mapper); + return valueStreamTransformer.apply(values.stream()).map(mapper); } @Override 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 80cb9bc5c..a404df544 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-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.function.BiPredicate; import java.util.function.Supplier; +import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractTwoValueCondition; @@ -53,4 +54,9 @@ public static Builder isBetween(Supplier valueSupplier1) { public IsBetween when(BiPredicate predicate) { return new IsBetween<>(valueSupplier1, valueSupplier2, predicate); } + + public IsBetween then(UnaryOperator transformer1, UnaryOperator transformer2) { + return shouldRender() ? new IsBetween<>(() -> transformer1.apply(value1()), + () -> transformer2.apply(value2())) : this; + } } 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 23e08de6b..117ca74a7 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 @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.mybatis.dynamic.sql.where.condition; import java.util.function.Supplier; +import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.util.Predicates; @@ -39,4 +40,10 @@ protected IsBetweenWhenPresent build() { public static Builder isBetweenWhenPresent(Supplier valueSupplier) { return new Builder<>(valueSupplier); } + + @Override + public IsBetweenWhenPresent then(UnaryOperator transformer1, UnaryOperator transformer2) { + return shouldRender() ? new IsBetweenWhenPresent<>(() -> transformer1.apply(value1()), + () -> transformer2.apply(value2())) : this; + } } 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 27a4614f9..4235b1a86 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-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; @@ -42,4 +43,8 @@ public static IsEqualTo of(Supplier valueSupplier) { public IsEqualTo when(Predicate predicate) { return new IsEqualTo<>(valueSupplier, predicate); } + + public IsEqualTo then(UnaryOperator transformer) { + return shouldRender() ? new IsEqualTo<>(() -> transformer.apply(value())) : this; + } } 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 0a67f2b51..12af85b9b 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 @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.Objects; import java.util.function.Supplier; +import java.util.function.UnaryOperator; public class IsEqualToWhenPresent extends IsEqualTo { @@ -27,4 +28,9 @@ protected IsEqualToWhenPresent(Supplier valueSupplier) { public static IsEqualToWhenPresent of(Supplier valueSupplier) { return new IsEqualToWhenPresent<>(valueSupplier); } + + @Override + public IsEqualToWhenPresent then(UnaryOperator transformer) { + return shouldRender() ? new IsEqualToWhenPresent<>(() -> transformer.apply(value())) : this; + } } 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 3ecac6cff..2909e6e39 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-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; @@ -42,4 +43,8 @@ public static IsGreaterThan of(Supplier valueSupplier) { public IsGreaterThan when(Predicate predicate) { return new IsGreaterThan<>(valueSupplier, predicate); } + + public IsGreaterThan then(UnaryOperator transformer) { + return shouldRender() ? new IsGreaterThan<>(() -> transformer.apply(value())) : this; + } } 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 fb8745b02..569a68db8 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-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; @@ -42,4 +43,8 @@ public static IsGreaterThanOrEqualTo of(Supplier valueSupplier) { public IsGreaterThanOrEqualTo when(Predicate predicate) { return new IsGreaterThanOrEqualTo<>(valueSupplier, predicate); } + + public IsGreaterThanOrEqualTo then(UnaryOperator transformer) { + return shouldRender() ? new IsGreaterThanOrEqualTo<>(() -> transformer.apply(value())) : this; + } } 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 b575e9d3a..495da0ae2 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 @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.Objects; import java.util.function.Supplier; +import java.util.function.UnaryOperator; public class IsGreaterThanOrEqualToWhenPresent extends IsGreaterThanOrEqualTo { @@ -27,4 +28,9 @@ protected IsGreaterThanOrEqualToWhenPresent(Supplier valueSupplier) { public static IsGreaterThanOrEqualToWhenPresent of(Supplier valueSupplier) { return new IsGreaterThanOrEqualToWhenPresent<>(valueSupplier); } + + @Override + public IsGreaterThanOrEqualToWhenPresent then(UnaryOperator transformer) { + return shouldRender() ? new IsGreaterThanOrEqualToWhenPresent<>(() -> transformer.apply(value())) : this; + } } 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 8bcb0ef4d..f06fd3901 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 @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.Objects; import java.util.function.Supplier; +import java.util.function.UnaryOperator; public class IsGreaterThanWhenPresent extends IsGreaterThan { @@ -27,4 +28,9 @@ protected IsGreaterThanWhenPresent(Supplier valueSupplier) { public static IsGreaterThanWhenPresent of(Supplier valueSupplier) { return new IsGreaterThanWhenPresent<>(valueSupplier); } + + @Override + public IsGreaterThanWhenPresent then(UnaryOperator transformer) { + return shouldRender() ? new IsGreaterThanWhenPresent<>(() -> transformer.apply(value())) : this; + } } 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 2b27cbbb5..bcc9ef032 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 @@ -26,8 +26,8 @@ public class IsIn extends AbstractListValueCondition { - protected IsIn(Collection values, UnaryOperator> valueStreamOperations) { - super(values, valueStreamOperations); + protected IsIn(Collection values, UnaryOperator> valueStreamTransformer) { + super(values, valueStreamTransformer); } protected IsIn(Collection values) { @@ -40,8 +40,35 @@ public String renderCondition(String columnName, Stream placeholders) { + placeholders.collect(Collectors.joining(",", "in (", ")")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } - public IsIn withValueStreamOperations(UnaryOperator> valueStreamOperations) { - return new IsIn<>(values, valueStreamOperations); + /** + * This method allows you to modify the condition's values before they are placed into the parameter map. + * For example, you could filter nulls, or trim strings, etc. This process will run before final rendering of SQL. + * If you filter values out of the stream, then final condition will not reference those values. If you filter all + * values out of the stream, then the condition will not render. + * + * @param valueStreamTransformer a UnaryOperator that will transform the value stream before + * the values are placed in the parameter map + * @return new condition with the specified transformer + */ + public IsIn then(UnaryOperator> valueStreamTransformer) { + return new IsIn<>(values, valueStreamTransformer); + } + + /** + * This method allows you to modify the condition's values before they are placed into the parameter map. + * For example, you could filter nulls, or trim strings, etc. This process will run before final rendering of SQL. + * If you filter values out of the stream, then final condition will not reference those values. If you filter all + * values out of the stream, then the condition will not render. + * + * @param valueStreamTransformer a UnaryOperator that will transform the value stream before + * the values are placed in the parameter map + * @return new condition with the specified transformer + * + * @deprecated See {@link IsIn#then(UnaryOperator)} + */ + @Deprecated + public IsIn withValueStreamOperations(UnaryOperator> valueStreamTransformer) { + return then(valueStreamTransformer); } public static IsIn of(Collection 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 8283a88f7..2ef6ae5a5 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 @@ -29,8 +29,8 @@ protected IsInCaseInsensitive(Collection values) { super(values, s -> s.map(StringUtilities::safelyUpperCase)); } - protected IsInCaseInsensitive(Collection values, UnaryOperator> valueStreamOperations) { - super(values, StringUtilities.upperCaseAfter(valueStreamOperations)); + protected IsInCaseInsensitive(Collection values, UnaryOperator> valueStreamTransformer) { + super(values, StringUtilities.upperCaseAfter(valueStreamTransformer)); } @Override @@ -39,8 +39,35 @@ public String renderCondition(String columnName, Stream placeholders) { placeholders.collect(Collectors.joining(",", "in (", ")")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } - public IsInCaseInsensitive withValueStreamOperations(UnaryOperator> valueStreamOperations) { - return new IsInCaseInsensitive(values, valueStreamOperations); + /** + * This method allows you to modify the condition's values before they are placed into the parameter map. + * For example, you could filter nulls, or trim strings, etc. This process will run before final rendering of SQL. + * If you filter values out of the stream, then final condition will not reference those values. If you filter all + * values out of the stream, then the condition will not render. + * + * @param valueStreamTransformer a UnaryOperator that will transform the value stream before + * the values are placed in the parameter map + * @return new condition with the specified transformer + */ + public IsInCaseInsensitive then(UnaryOperator> valueStreamTransformer) { + return new IsInCaseInsensitive(values, valueStreamTransformer); + } + + /** + * This method allows you to modify the condition's values before they are placed into the parameter map. + * For example, you could filter nulls, or trim strings, etc. This process will run before final rendering of SQL. + * If you filter values out of the stream, then final condition will not reference those values. If you filter all + * values out of the stream, then the condition will not render. + * + * @param valueStreamTransformer a UnaryOperator that will transform the value stream before + * the values are placed in the parameter map + * @return new condition with the specified transformer + * + * @deprecated See {@link IsInCaseInsensitive#then(UnaryOperator)} + */ + @Deprecated + public IsInCaseInsensitive withValueStreamOperations(UnaryOperator> valueStreamTransformer) { + return then(valueStreamTransformer); } public static IsInCaseInsensitive of(Collection 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 01500a0d3..0f0c243c5 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-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; @@ -42,4 +43,8 @@ public static IsLessThan of(Supplier valueSupplier) { public IsLessThan when(Predicate predicate) { return new IsLessThan<>(valueSupplier, predicate); } + + public IsLessThan then(UnaryOperator transformer) { + return shouldRender() ? new IsLessThan<>(() -> transformer.apply(value())) : this; + } } 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 e6d3e5393..ccb5e4815 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-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; @@ -42,4 +43,8 @@ public static IsLessThanOrEqualTo of(Supplier valueSupplier) { public IsLessThanOrEqualTo when(Predicate predicate) { return new IsLessThanOrEqualTo<>(valueSupplier, predicate); } + + public IsLessThanOrEqualTo then(UnaryOperator transformer) { + return shouldRender() ? new IsLessThanOrEqualTo<>(() -> transformer.apply(value())) : this; + } } 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 39b7560a2..eeb344d6f 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 @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.Objects; import java.util.function.Supplier; +import java.util.function.UnaryOperator; public class IsLessThanOrEqualToWhenPresent extends IsLessThanOrEqualTo { @@ -27,4 +28,9 @@ protected IsLessThanOrEqualToWhenPresent(Supplier valueSupplier) { public static IsLessThanOrEqualToWhenPresent of(Supplier valueSupplier) { return new IsLessThanOrEqualToWhenPresent<>(valueSupplier); } + + @Override + public IsLessThanOrEqualToWhenPresent then(UnaryOperator transformer) { + return shouldRender() ? new IsLessThanOrEqualToWhenPresent<>(() -> transformer.apply(value())) : this; + } } 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 27957f714..6ae4f4988 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 @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.Objects; import java.util.function.Supplier; +import java.util.function.UnaryOperator; public class IsLessThanWhenPresent extends IsLessThan { @@ -27,4 +28,9 @@ protected IsLessThanWhenPresent(Supplier valueSupplier) { public static IsLessThanWhenPresent of(Supplier valueSupplier) { return new IsLessThanWhenPresent<>(valueSupplier); } + + @Override + public IsLessThanWhenPresent then(UnaryOperator transformer) { + return shouldRender() ? new IsLessThanWhenPresent<>(() -> transformer.apply(value())) : this; + } } 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 0d8ab5633..4d9a55bd6 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-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; @@ -42,4 +43,8 @@ public static IsLike of(Supplier valueSupplier) { public IsLike when(Predicate predicate) { return new IsLike<>(valueSupplier, predicate); } + + public IsLike then(UnaryOperator transformer) { + return shouldRender() ? new IsLike<>(() -> transformer.apply(value())) : this; + } } 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 39e8fe9f9..d2b67204a 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-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; @@ -47,4 +48,8 @@ public static IsLikeCaseInsensitive of(Supplier valueSupplier) { public IsLikeCaseInsensitive when(Predicate predicate) { return new IsLikeCaseInsensitive(valueSupplier, predicate); } + + public IsLikeCaseInsensitive then(UnaryOperator transformer) { + return shouldRender() ? new IsLikeCaseInsensitive(() -> transformer.apply(value())) : this; + } } \ No newline at end of file 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 c6348b41e..1609efa0f 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 @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.Objects; import java.util.function.Supplier; +import java.util.function.UnaryOperator; public class IsLikeCaseInsensitiveWhenPresent extends IsLikeCaseInsensitive { @@ -27,4 +28,9 @@ protected IsLikeCaseInsensitiveWhenPresent(Supplier valueSupplier) { public static IsLikeCaseInsensitiveWhenPresent of(Supplier valueSupplier) { return new IsLikeCaseInsensitiveWhenPresent(valueSupplier); } + + @Override + public IsLikeCaseInsensitiveWhenPresent then(UnaryOperator transformer) { + return shouldRender() ? new IsLikeCaseInsensitiveWhenPresent(() -> transformer.apply(value())) : this; + } } \ No newline at end of file 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 fcae15a75..e4beea97a 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 @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.Objects; import java.util.function.Supplier; +import java.util.function.UnaryOperator; public class IsLikeWhenPresent extends IsLike { @@ -27,4 +28,9 @@ protected IsLikeWhenPresent(Supplier valueSupplier) { public static IsLikeWhenPresent of(Supplier valueSupplier) { return new IsLikeWhenPresent<>(valueSupplier); } + + @Override + public IsLikeWhenPresent then(UnaryOperator transformer) { + return shouldRender() ? new IsLikeWhenPresent<>(() -> transformer.apply(value())) : this; + } } 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 2e1a81d05..0a3b1b2f0 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-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.function.BiPredicate; import java.util.function.Supplier; +import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractTwoValueCondition; @@ -54,4 +55,9 @@ public static Builder isNotBetween(Supplier valueSupplier1) { public IsNotBetween when(BiPredicate predicate) { return new IsNotBetween<>(valueSupplier1, valueSupplier2, predicate); } + + public IsNotBetween then(UnaryOperator transformer1, UnaryOperator transformer2) { + return shouldRender() ? new IsNotBetween<>(() -> transformer1.apply(value1()), + () -> transformer2.apply(value2())) : this; + } } 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 66340c1f4..fd0ba0f48 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 @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.mybatis.dynamic.sql.where.condition; import java.util.function.Supplier; +import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.util.Predicates; @@ -39,4 +40,10 @@ protected IsNotBetweenWhenPresent build() { public static Builder isNotBetweenWhenPresent(Supplier valueSupplier) { return new Builder<>(valueSupplier); } + + @Override + public IsNotBetweenWhenPresent then(UnaryOperator transformer1, UnaryOperator transformer2) { + return shouldRender() ? new IsNotBetweenWhenPresent<>(() -> transformer1.apply(value1()), + () -> transformer2.apply(value2())) : this; + } } 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 3bf820581..77d06c9e8 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-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; @@ -42,4 +43,8 @@ public static IsNotEqualTo of(Supplier valueSupplier) { public IsNotEqualTo when(Predicate predicate) { return new IsNotEqualTo<>(valueSupplier, predicate); } + + public IsNotEqualTo then(UnaryOperator transformer) { + return shouldRender() ? new IsNotEqualTo<>(() -> transformer.apply(value())) : this; + } } 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 d810dfb5e..86bca9be4 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 @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.Objects; import java.util.function.Supplier; +import java.util.function.UnaryOperator; public class IsNotEqualToWhenPresent extends IsNotEqualTo { @@ -27,4 +28,9 @@ protected IsNotEqualToWhenPresent(Supplier valueSupplier) { public static IsNotEqualToWhenPresent of(Supplier valueSupplier) { return new IsNotEqualToWhenPresent<>(valueSupplier); } + + @Override + public IsNotEqualToWhenPresent then(UnaryOperator transformer) { + return shouldRender() ? new IsNotEqualToWhenPresent<>(() -> transformer.apply(value())) : this; + } } 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 4dcdc1d54..7992be263 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 @@ -26,8 +26,8 @@ public class IsNotIn extends AbstractListValueCondition { - protected IsNotIn(Collection values, UnaryOperator> valueStreamOperations) { - super(values, valueStreamOperations); + protected IsNotIn(Collection values, UnaryOperator> valueStreamTransformer) { + super(values, valueStreamTransformer); } protected IsNotIn(Collection values) { @@ -41,8 +41,35 @@ public String renderCondition(String columnName, Stream placeholders) { Collectors.joining(",", "not in (", ")")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } - public IsNotIn withValueStreamOperations(UnaryOperator> valueStreamOperations) { - return new IsNotIn<>(values, valueStreamOperations); + /** + * This method allows you to modify the condition's values before they are placed into the parameter map. + * For example, you could filter nulls, or trim strings, etc. This process will run before final rendering of SQL. + * If you filter values out of the stream, then final condition will not reference those values. If you filter all + * values out of the stream, then the condition will not render. + * + * @param valueStreamTransformer a UnaryOperator that will transform the value stream before + * the values are placed in the parameter map + * @return new condition with the specified transformer + */ + public IsNotIn then(UnaryOperator> valueStreamTransformer) { + return new IsNotIn<>(values, valueStreamTransformer); + } + + /** + * This method allows you to modify the condition's values before they are placed into the parameter map. + * For example, you could filter nulls, or trim strings, etc. This process will run before final rendering of SQL. + * If you filter values out of the stream, then final condition will not reference those values. If you filter all + * values out of the stream, then the condition will not render. + * + * @param valueStreamTransformer a UnaryOperator that will transform the value stream before + * the values are placed in the parameter map + * @return new condition with the specified transformer + * + * @deprecated See {@link IsNotIn#then(UnaryOperator)} + */ + @Deprecated + public IsNotIn withValueStreamOperations(UnaryOperator> valueStreamTransformer) { + return then(valueStreamTransformer); } public static IsNotIn of(Collection values) { 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 579fed6df..38fa8bf61 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 @@ -29,8 +29,8 @@ protected IsNotInCaseInsensitive(Collection values) { super(values, s -> s.map(StringUtilities::safelyUpperCase)); } - protected IsNotInCaseInsensitive(Collection values, UnaryOperator> valueStreamOperations) { - super(values, StringUtilities.upperCaseAfter(valueStreamOperations)); + protected IsNotInCaseInsensitive(Collection values, UnaryOperator> valueStreamTransformer) { + super(values, StringUtilities.upperCaseAfter(valueStreamTransformer)); } @Override @@ -40,8 +40,35 @@ public String renderCondition(String columnName, Stream placeholders) { Collectors.joining(",", "not in (", ")")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } - public IsNotInCaseInsensitive withValueStreamOperations(UnaryOperator> valueStreamOperations) { - return new IsNotInCaseInsensitive(values, valueStreamOperations); + /** + * This method allows you to modify the condition's values before they are placed into the parameter map. + * For example, you could filter nulls, or trim strings, etc. This process will run before final rendering of SQL. + * If you filter values out of the stream, then final condition will not reference those values. If you filter all + * values out of the stream, then the condition will not render. + * + * @param valueStreamTransformer a UnaryOperator that will transform the value stream before + * the values are placed in the parameter map + * @return new condition with the specified transformer + */ + public IsNotInCaseInsensitive then(UnaryOperator> valueStreamTransformer) { + return new IsNotInCaseInsensitive(values, valueStreamTransformer); + } + + /** + * This method allows you to modify the condition's values before they are placed into the parameter map. + * For example, you could filter nulls, or trim strings, etc. This process will run before final rendering of SQL. + * If you filter values out of the stream, then final condition will not reference those values. If you filter all + * values out of the stream, then the condition will not render. + * + * @param valueStreamTransformer a UnaryOperator that will transform the value stream before + * the values are placed in the parameter map + * @return new condition with the specified transformer + * + * @deprecated See {@link IsNotInCaseInsensitive#then(UnaryOperator)} + */ + @Deprecated + public IsNotInCaseInsensitive withValueStreamOperations(UnaryOperator> valueStreamTransformer) { + return then(valueStreamTransformer); } public static IsNotInCaseInsensitive of(Collection 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 57d49d2cc..586b26f4f 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-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; @@ -42,4 +43,8 @@ public static IsNotLike of(Supplier valueSupplier) { public IsNotLike when(Predicate predicate) { return new IsNotLike<>(valueSupplier, predicate); } + + public IsNotLike then(UnaryOperator transformer) { + return shouldRender() ? new IsNotLike<>(() -> transformer.apply(value())) : this; + } } 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 c3b532671..71e0dc6b4 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-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.function.UnaryOperator; import org.mybatis.dynamic.sql.AbstractSingleValueCondition; import org.mybatis.dynamic.sql.util.StringUtilities; @@ -47,4 +48,8 @@ public static IsNotLikeCaseInsensitive of(Supplier valueSupplier) { public IsNotLikeCaseInsensitive when(Predicate predicate) { return new IsNotLikeCaseInsensitive(valueSupplier, predicate); } + + public IsNotLikeCaseInsensitive then(UnaryOperator transformer) { + return shouldRender() ? new IsNotLikeCaseInsensitive(() -> transformer.apply(value())) : this; + } } \ No newline at end of file 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 7cdfefed5..07f086908 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 @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.Objects; import java.util.function.Supplier; +import java.util.function.UnaryOperator; public class IsNotLikeCaseInsensitiveWhenPresent extends IsNotLikeCaseInsensitive { @@ -27,4 +28,9 @@ protected IsNotLikeCaseInsensitiveWhenPresent(Supplier valueSupplier) { public static IsNotLikeCaseInsensitiveWhenPresent of(Supplier valueSupplier) { return new IsNotLikeCaseInsensitiveWhenPresent(valueSupplier); } + + @Override + public IsNotLikeCaseInsensitiveWhenPresent then(UnaryOperator transformer) { + return shouldRender() ? new IsNotLikeCaseInsensitiveWhenPresent(() -> transformer.apply(value())) : this; + } } \ No newline at end of file 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 dcbfae553..da169dc8f 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 @@ -1,5 +1,5 @@ /** - * Copyright 2016-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ import java.util.Objects; import java.util.function.Supplier; +import java.util.function.UnaryOperator; public class IsNotLikeWhenPresent extends IsNotLike { @@ -27,4 +28,9 @@ protected IsNotLikeWhenPresent(Supplier valueSupplier) { public static IsNotLikeWhenPresent of(Supplier valueSupplier) { return new IsNotLikeWhenPresent<>(valueSupplier); } + + @Override + public IsNotLikeWhenPresent then(UnaryOperator transformer) { + return shouldRender() ? new IsNotLikeWhenPresent<>(() -> transformer.apply(value())) : this; + } } diff --git a/src/site/markdown/docs/conditions.md b/src/site/markdown/docs/conditions.md index a368a34c4..5821a168b 100644 --- a/src/site/markdown/docs/conditions.md +++ b/src/site/markdown/docs/conditions.md @@ -143,13 +143,13 @@ The following table shows the different supplied In conditions and how they will If none of these options meet your needs, there is an extension point where you can add your own filter and/or map conditions to the value stream. This gives you great flexibility to alter or filter the value list before the condition is rendered. -The extension point for modifying the value list is the method `withValueStreamOperations(UnaryOperator>)`. This method accepts a `UnaryOperator>` in which you can specify map and/or filter operations for the value stream. For example, suppose you wanted to code an "in" condition that accepted a list of strings, but you want to filter out any null or blank string, and you want to trim all strings. This can be accomplished with code like this: +The extension point for modifying the value list is the method `then(UnaryOperator>)`. This method accepts a `UnaryOperator>` in which you can specify map and/or filter operations for the value stream. For example, suppose you wanted to code an "in" condition that accepted a list of strings, but you want to filter out any null or blank string, and you want to trim all strings. This can be accomplished with code like this: ```java SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) .where(animalName, isIn(" Mouse", " ", null, "", "Musk shrew ") - .withValueStreamOperations(s -> s.filter(Objects::nonNull) + .then(s -> s.filter(Objects::nonNull) .map(String::trim) .filter(st -> !st.isEmpty()))) .orderBy(id) diff --git a/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java b/src/test/java/examples/animal/data/OptionalConditionsWithPredicatesAnimalDataTest.java index 703adea11..3d9e21fd1 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-2018 the original author or authors. + * Copyright 2016-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -436,6 +436,30 @@ public void testIsInWhenWithValue() { @Test public void testIsInWhenWithSomeValues() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); + SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) + .from(animalData) + .where(id, isIn(3, NULL_INTEGER, 5).then(s -> s.filter(Objects::nonNull).map(i -> i + 3))) + .orderBy(id) + .build() + .render(RenderingStrategy.MYBATIS3); + List animals = mapper.selectMany(selectStatement); + 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.size()).isEqualTo(2), + () -> assertThat(animals.get(0).getId()).isEqualTo(6), + () -> assertThat(animals.get(1).getId()).isEqualTo(8) + ); + } + } + + /** + * Delete this test when the deprecated method is deleted + */ + @Test + @Deprecated + public void testIsInWhenWithSomeValuesDeprecated() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) @@ -474,13 +498,13 @@ public void testIsInCaseInsensitiveWhenWithValue() { } @Test - public void testValueStreamOperations() { + public void testValueStreamTransformer() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) .from(animalData) .where(animalName, isIn(" Mouse", " ", null, "", "Musk shrew ") - .withValueStreamOperations(s -> s.filter(Objects::nonNull) + .then(s -> s.filter(Objects::nonNull) .map(String::trim) .filter(st -> !st.isEmpty()))) .orderBy(id) @@ -496,7 +520,7 @@ public void testValueStreamOperations() { } @Test - public void testValueStreamOperationsWithCustomCondition() { + public void testValueStreamTransformerWithCustomCondition() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) @@ -516,6 +540,29 @@ public void testValueStreamOperationsWithCustomCondition() { @Test public void testIsInCaseInsensitiveWhenWithSomeValues() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); + SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) + .from(animalData) + .where(animalName, isInCaseInsensitive("mouse", null, "musk shrew").then(s -> s.filter(Objects::nonNull))) + .orderBy(id) + .build() + .render(RenderingStrategy.MYBATIS3); + List animals = mapper.selectMany(selectStatement); + 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.size()).isEqualTo(2), + () -> assertThat(animals.get(0).getId()).isEqualTo(4) + ); + } + } + + /** + * Delete this test when the deprecated method is deleted + */ + @Test + @Deprecated + public void testIsInCaseInsensitiveWhenWithSomeValuesDeprecated() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) @@ -575,6 +622,30 @@ public void testIsNotInWhenWithValue() { @Test public void testIsNotInWhenWithSomeValues() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); + SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) + .from(animalData) + .where(id, isNotIn(3, NULL_INTEGER, 5).then(s -> s.filter(Objects::nonNull))) + .and(id, isLessThanOrEqualTo(10)) + .orderBy(id) + .build() + .render(RenderingStrategy.MYBATIS3); + List animals = mapper.selectMany(selectStatement); + 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.size()).isEqualTo(8), + () -> assertThat(animals.get(0).getId()).isEqualTo(1) + ); + } + } + + /** + * Delete this test when the deprecated method is deleted + */ + @Test + @Deprecated + public void testIsNotInWhenWithSomeValuesDeprecated() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) @@ -615,6 +686,30 @@ public void testIsNotInCaseInsensitiveWhenWithValue() { @Test public void testIsNotInCaseInsensitiveWhenWithSomeValues() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); + SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) + .from(animalData) + .where(animalName, isNotInCaseInsensitive("mouse", null, "musk shrew").then(s -> s.filter(Objects::nonNull))) + .and(id, isLessThanOrEqualTo(10)) + .orderBy(id) + .build() + .render(RenderingStrategy.MYBATIS3); + List animals = mapper.selectMany(selectStatement); + 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.size()).isEqualTo(8), + () -> assertThat(animals.get(0).getId()).isEqualTo(1) + ); + } + } + + /** + * Delete this test when the deprecated method is deleted + */ + @Test + @Deprecated + public void testIsNotInCaseInsensitiveWhenWithSomeValuesDeprecated() { try (SqlSession sqlSession = sqlSessionFactory.openSession()) { AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class); SelectStatementProvider selectStatement = select(id, animalName, bodyWeight, brainWeight) diff --git a/src/test/java/issues/gh105/Issue105Test.java b/src/test/java/issues/gh105/Issue105Test.java new file mode 100644 index 000000000..a79e410e2 --- /dev/null +++ b/src/test/java/issues/gh105/Issue105Test.java @@ -0,0 +1,883 @@ +/** + * Copyright 2016-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package issues.gh105; + +import static issues.gh105.PersonDynamicSqlSupport.*; +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.RenderingStrategy; +import org.mybatis.dynamic.sql.select.render.SelectStatementProvider; +import org.mybatis.dynamic.sql.util.Predicates; + +public class Issue105Test { + + @Test + public void testFuzzyLikeBothPresent() { + String fName = "Fred"; + String lName = "Flintstone"; + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isLike(fName).when(Objects::nonNull).then(s -> "%" + s + "%")) + .and(lastName, isLike(lName).when(Objects::nonNull).then(s -> "%" + s + "%")) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where first_name like #{parameters.p1}" + + " and last_name like #{parameters.p2}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo("%Fred%"); + assertThat(selectStatement.getParameters().get("p2")).isEqualTo("%Flintstone%"); + } + + @Test + public void testFuzzyLikeFirstNameNull() { + String fName = null; + String lName = "Flintstone"; + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isLike(fName).when(Objects::nonNull).then(SearchUtils::addWildcards)) + .and(lastName, isLike(lName).when(Objects::nonNull).then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where last_name like #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo("%Flintstone%"); + } + + @Test + public void testFuzzyLikeLastNameNull() { + String fName = "Fred"; + String lName = null; + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isLike(fName).when(Objects::nonNull).then(SearchUtils::addWildcards)) + .and(lastName, isLike(lName).when(Objects::nonNull).then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where first_name like #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo("%Fred%"); + } + + @Test + public void testFuzzyLikeBothNull() { + String fName = null; + String lName = null; + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isLike(fName).when(Objects::nonNull).then(SearchUtils::addWildcards)) + .and(lastName, isLike(lName).when(Objects::nonNull).then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().size()).isEqualTo(0); + } + + @Test + public void testBetweenTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isBetween(1).and(10).then(i1 -> i1 + 1, i2 -> i2 + 2)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where age between #{parameters.p1} and #{parameters.p2}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo(2); + assertThat(selectStatement.getParameters().get("p2")).isEqualTo(12); + } + + @Test + public void testBetweenWhenPresentTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isBetweenWhenPresent(1).and(10).then(i1 -> i1 + 1, i2 -> i2 + 2)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where age between #{parameters.p1} and #{parameters.p2}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo(2); + assertThat(selectStatement.getParameters().get("p2")).isEqualTo(12); + } + + @Test + public void testEqualTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isEqualTo(1).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where age = #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo(2); + } + + @Test + public void testEqualWhenPresentTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isEqualToWhenPresent(1).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where age = #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo(2); + } + + @Test + public void testGreaterThanTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isGreaterThan(1).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where age > #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo(2); + } + + @Test + public void testGreaterThanOrEqualTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isGreaterThanOrEqualTo(1).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where age >= #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo(2); + } + + @Test + public void testGreaterThanOrEqualWhenPresentTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isGreaterThanOrEqualToWhenPresent(1).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where age >= #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo(2); + } + + @Test + public void testGreaterThanWhenPresentTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isGreaterThanWhenPresent(1).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where age > #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo(2); + } + + @Test + public void testLessThanTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isLessThan(1).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where age < #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo(2); + } + + @Test + public void testLessThanOrEqualTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isLessThanOrEqualTo(1).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where age <= #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo(2); + } + + @Test + public void testLessThanOrEqualWhenPresentTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isLessThanOrEqualToWhenPresent(1).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where age <= #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo(2); + } + + @Test + public void testLessThanWhenPresentTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isLessThanWhenPresent(1).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where age < #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo(2); + } + + @Test + public void testLikeTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isLike("fred").then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where first_name like #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo("%fred%"); + } + + @Test + public void testLikeCaseInsensitiveTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isLikeCaseInsensitive("fred").then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where upper(first_name) like #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo("%FRED%"); + } + + @Test + public void testLikeCaseInsensitiveWhenPresentTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isLikeCaseInsensitiveWhenPresent("fred").then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where upper(first_name) like #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo("%FRED%"); + } + + @Test + public void testLikeWhenPresentTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isLikeWhenPresent("fred").then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where first_name like #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo("%fred%"); + } + + @Test + public void testNotBetweenTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isNotBetween(1).and(10).then(i1 -> i1 + 1, i2 -> i2 + 2)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where age not between #{parameters.p1} and #{parameters.p2}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo(2); + assertThat(selectStatement.getParameters().get("p2")).isEqualTo(12); + } + + @Test + public void testNotBetweenWhenPresentTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isNotBetweenWhenPresent(1).and(10).then(i1 -> i1 + 1, i2 -> i2 + 2)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where age not between #{parameters.p1} and #{parameters.p2}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo(2); + assertThat(selectStatement.getParameters().get("p2")).isEqualTo(12); + } + + @Test + public void testNotEqualTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isNotEqualTo(1).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where age <> #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo(2); + } + + @Test + public void testNotEqualWhenPresentTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isNotEqualToWhenPresent(1).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where age <> #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo(2); + } + + @Test + public void testNotLikeTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isNotLike("fred").then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where first_name not like #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo("%fred%"); + } + + @Test + public void testNotLikeCaseInsensitiveTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isNotLikeCaseInsensitive("fred").then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where upper(first_name) not like #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo("%FRED%"); + } + + @Test + public void testNotLikeCaseInsensitiveWhenPresentTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isNotLikeCaseInsensitiveWhenPresent("fred").then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where upper(first_name) not like #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo("%FRED%"); + } + + @Test + public void testNotLikeWhenPresentTransform() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isNotLikeWhenPresent("fred").then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person" + + " where first_name not like #{parameters.p1}"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + assertThat(selectStatement.getParameters().get("p1")).isEqualTo("%fred%"); + } + + @Test + public void testBetweenTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isBetween(1).and((Integer) null).when(Predicates.bothPresent()).then(i1 -> i1 + 1, i2 -> i2 + 2)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testBetweenWhenPresentTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isBetweenWhenPresent(1).and((Integer) null).then(i1 -> i1 + 1, i2 -> i2 + 2)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testEqualTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isEqualTo((Integer) null).when(Objects::nonNull).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testEqualWhenPresentTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isEqualToWhenPresent((Integer) null).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testGreaterThanTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isGreaterThan((Integer) null).when(Objects::nonNull).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testGreaterThanOrEqualTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isGreaterThanOrEqualTo((Integer) null).when(Objects::nonNull).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testGreaterThanOrEqualWhenPresentTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isGreaterThanOrEqualToWhenPresent((Integer) null).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testGreaterThanWhenPresentTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isGreaterThanWhenPresent((Integer) null).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testLessThanTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isLessThan((Integer) null).when(Objects::nonNull).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testLessThanOrEqualTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isLessThanOrEqualTo((Integer) null).when(Objects::nonNull).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testLessThanOrEqualWhenPresentTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isLessThanOrEqualToWhenPresent((Integer) null).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testLessThanWhenPresentTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isLessThanWhenPresent((Integer) null).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testLikeTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isLike((String) null).when(Objects::nonNull).then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testLikeCaseInsensitiveTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isLikeCaseInsensitive((String) null).when(Objects::nonNull).then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testLikeCaseInsensitiveWhenPresentTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isLikeCaseInsensitiveWhenPresent((String) null).then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testLikeWhenPresentTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isLikeWhenPresent((String) null).then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testNotBetweenTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isNotBetween((Integer) null).and(10).when(Predicates.bothPresent()).then(i1 -> i1 + 1, i2 -> i2 + 2)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testNotBetweenWhenPresentTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isNotBetweenWhenPresent(1).and((Integer) null).then(i1 -> i1 + 1, i2 -> i2 + 2)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testNotEqualTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isNotEqualTo((Integer) null).when(Objects::nonNull).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testNotEqualWhenPresentTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(age, isNotEqualToWhenPresent((Integer) null).then(i -> i + 1)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testNotLikeTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isNotLike((String) null).when(Objects::nonNull).then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testNotLikeCaseInsensitiveTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isNotLikeCaseInsensitive((String) null).when(Objects::nonNull).then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testNotLikeCaseInsensitiveWhenPresentTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isNotLikeCaseInsensitiveWhenPresent((String) null).then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } + + @Test + public void testNotLikeWhenPresentTransformWithNull() { + + SelectStatementProvider selectStatement = select(id, firstName, lastName) + .from(person) + .where(firstName, isNotLikeWhenPresent((String) null).then(SearchUtils::addWildcards)) + .build() + .render(RenderingStrategy.MYBATIS3); + + String expected = "select person_id, first_name, last_name" + + " from Person"; + + assertThat(selectStatement.getSelectStatement()).isEqualTo(expected); + } +} diff --git a/src/test/java/issues/gh105/PersonDynamicSqlSupport.java b/src/test/java/issues/gh105/PersonDynamicSqlSupport.java new file mode 100644 index 000000000..fa9634b5b --- /dev/null +++ b/src/test/java/issues/gh105/PersonDynamicSqlSupport.java @@ -0,0 +1,38 @@ +/** + * Copyright 2016-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package issues.gh105; + +import org.mybatis.dynamic.sql.SqlColumn; +import org.mybatis.dynamic.sql.SqlTable; + +public final class PersonDynamicSqlSupport { + public static final Person person = new Person(); + public static final SqlColumn id = person.id; + public static final SqlColumn firstName = person.firstName; + public static final SqlColumn lastName = person.lastName; + public static final SqlColumn age = person.age; + + public static final class Person extends SqlTable { + public final SqlColumn id = column("person_id"); + public final SqlColumn firstName = column("first_name"); + public final SqlColumn lastName = column("last_name"); + public final SqlColumn age = column("age"); + + public Person() { + super("Person"); + } + } +} diff --git a/src/test/java/issues/gh105/SearchUtils.java b/src/test/java/issues/gh105/SearchUtils.java new file mode 100644 index 000000000..a10ec97c1 --- /dev/null +++ b/src/test/java/issues/gh105/SearchUtils.java @@ -0,0 +1,22 @@ +/** + * Copyright 2016-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package issues.gh105; + +public class SearchUtils { + public static String addWildcards(String s) { + return "%" + s + "%"; + } +}