Skip to content

Commit 11acc1a

Browse files
committed
Case expressions for Java DSL
1 parent 9812701 commit 11acc1a

File tree

11 files changed

+978
-1
lines changed

11 files changed

+978
-1
lines changed

src/main/java/org/mybatis/dynamic/sql/SqlBuilder.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@
3333
import org.mybatis.dynamic.sql.select.HavingDSL;
3434
import org.mybatis.dynamic.sql.select.MultiSelectDSL;
3535
import org.mybatis.dynamic.sql.select.QueryExpressionDSL.FromGatherer;
36+
import org.mybatis.dynamic.sql.select.SearchedCaseDSL;
3637
import org.mybatis.dynamic.sql.select.SelectDSL;
3738
import org.mybatis.dynamic.sql.select.SelectModel;
39+
import org.mybatis.dynamic.sql.select.SimpleCaseDSL;
3840
import org.mybatis.dynamic.sql.select.SimpleSortSpecification;
3941
import org.mybatis.dynamic.sql.select.aggregate.Avg;
4042
import org.mybatis.dynamic.sql.select.aggregate.Count;
@@ -425,6 +427,15 @@ static AndOrCriteriaGroup and(List<AndOrCriteriaGroup> subCriteria) {
425427
.build();
426428
}
427429

430+
// case expressions
431+
static <T> SimpleCaseDSL<T> simpleCase(BindableColumn<T> column) {
432+
return SimpleCaseDSL.simpleCase(column);
433+
}
434+
435+
static SearchedCaseDSL searchedCase() {
436+
return SearchedCaseDSL.searchedCase();
437+
}
438+
428439
// join support
429440
static <T> JoinCriterion<T> and(BindableColumn<T> joinColumn, JoinCondition<T> joinCondition) {
430441
return new JoinCriterion.Builder<T>()

src/main/java/org/mybatis/dynamic/sql/common/AbstractBooleanExpressionDSL.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,13 @@ private void addSubCriteria(String connector, List<AndOrCriteriaGroup> criteria)
144144
.build());
145145
}
146146

147+
protected void setInitialCriterion(SqlCriterion initialCriterion) {
148+
this.initialCriterion = initialCriterion;
149+
}
150+
147151
protected void setInitialCriterion(SqlCriterion initialCriterion, StatementType statementType) {
148152
Validator.assertTrue(this.initialCriterion == null, statementType.messageNumber());
149-
this.initialCriterion = initialCriterion;
153+
setInitialCriterion(initialCriterion);
150154
}
151155

152156
// may be null!
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright 2016-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.mybatis.dynamic.sql.select;
17+
18+
import java.util.ArrayList;
19+
import java.util.Arrays;
20+
import java.util.List;
21+
22+
import org.mybatis.dynamic.sql.AndOrCriteriaGroup;
23+
import org.mybatis.dynamic.sql.BindableColumn;
24+
import org.mybatis.dynamic.sql.ColumnAndConditionCriterion;
25+
import org.mybatis.dynamic.sql.CriteriaGroup;
26+
import org.mybatis.dynamic.sql.SqlCriterion;
27+
import org.mybatis.dynamic.sql.VisitableCondition;
28+
import org.mybatis.dynamic.sql.common.AbstractBooleanExpressionDSL;
29+
30+
public class SearchedCaseDSL {
31+
private final List<SearchedCaseModel.SearchedWhenCondition> whenConditions = new ArrayList<>();
32+
private String elseValue;
33+
34+
public <T> WhenDSL when(BindableColumn<T> column, VisitableCondition<T> condition,
35+
AndOrCriteriaGroup... subCriteria) {
36+
return when(column, condition, Arrays.asList(subCriteria));
37+
}
38+
39+
public <T> WhenDSL when(BindableColumn<T> column, VisitableCondition<T> condition,
40+
List<AndOrCriteriaGroup> subCriteria) {
41+
SqlCriterion sqlCriterion = ColumnAndConditionCriterion.withColumn(column)
42+
.withCondition(condition)
43+
.withSubCriteria(subCriteria)
44+
.build();
45+
46+
return initialize(sqlCriterion);
47+
}
48+
49+
public WhenDSL when(SqlCriterion initialCriterion, AndOrCriteriaGroup... subCriteria) {
50+
return when(initialCriterion, Arrays.asList(subCriteria));
51+
}
52+
53+
public WhenDSL when(SqlCriterion initialCriterion, List<AndOrCriteriaGroup> subCriteria) {
54+
SqlCriterion sqlCriterion = new CriteriaGroup.Builder()
55+
.withInitialCriterion(initialCriterion)
56+
.withSubCriteria(subCriteria)
57+
.build();
58+
59+
return initialize(sqlCriterion);
60+
}
61+
62+
private WhenDSL initialize(SqlCriterion sqlCriterion) {
63+
return new WhenDSL(sqlCriterion);
64+
}
65+
66+
public SearchedCaseDSL elseConstant(String elseValue) {
67+
this.elseValue = elseValue;
68+
return this;
69+
}
70+
71+
public SearchedCaseModel end() {
72+
return new SearchedCaseModel.Builder()
73+
.withElseValue(elseValue)
74+
.withWhenConditions(whenConditions)
75+
.build();
76+
}
77+
78+
public class WhenDSL extends AbstractBooleanExpressionDSL<WhenDSL> {
79+
private WhenDSL(SqlCriterion sqlCriterion) {
80+
setInitialCriterion(sqlCriterion);
81+
}
82+
83+
public SearchedCaseDSL thenConstant(String value) {
84+
whenConditions.add(new SearchedCaseModel.SearchedWhenCondition(getInitialCriterion(), subCriteria, value));
85+
return SearchedCaseDSL.this;
86+
}
87+
88+
@Override
89+
protected WhenDSL getThis() {
90+
return this;
91+
}
92+
}
93+
94+
public static SearchedCaseDSL searchedCase() {
95+
return new SearchedCaseDSL();
96+
}
97+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/*
2+
* Copyright 2016-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.mybatis.dynamic.sql.select;
17+
18+
import java.util.ArrayList;
19+
import java.util.List;
20+
import java.util.Objects;
21+
import java.util.Optional;
22+
import java.util.stream.Stream;
23+
24+
import org.mybatis.dynamic.sql.AndOrCriteriaGroup;
25+
import org.mybatis.dynamic.sql.BasicColumn;
26+
import org.mybatis.dynamic.sql.SqlCriterion;
27+
import org.mybatis.dynamic.sql.common.AbstractBooleanExpressionModel;
28+
import org.mybatis.dynamic.sql.render.RenderingContext;
29+
import org.mybatis.dynamic.sql.select.render.SearchedCaseRenderer;
30+
import org.mybatis.dynamic.sql.util.FragmentAndParameters;
31+
32+
public class SearchedCaseModel implements BasicColumn {
33+
private final List<SearchedWhenCondition> whenConditions;
34+
private final String elseValue;
35+
private final String alias;
36+
37+
private SearchedCaseModel(Builder builder) {
38+
whenConditions = builder.whenConditions;
39+
alias = builder.alias;
40+
elseValue = builder.elseValue;
41+
}
42+
43+
public Stream<SearchedWhenCondition> whenConditions() {
44+
return whenConditions.stream();
45+
}
46+
47+
public Optional<String> elseValue() {
48+
return Optional.ofNullable(elseValue);
49+
}
50+
51+
@Override
52+
public Optional<String> alias() {
53+
return Optional.ofNullable(alias);
54+
}
55+
56+
@Override
57+
public SearchedCaseModel as(String alias) {
58+
return new Builder().withWhenConditions(whenConditions)
59+
.withElseValue(elseValue)
60+
.withAlias(alias)
61+
.build();
62+
}
63+
64+
@Override
65+
public FragmentAndParameters render(RenderingContext renderingContext) {
66+
return new SearchedCaseRenderer(this, renderingContext).render();
67+
}
68+
69+
public static class SearchedWhenCondition extends AbstractBooleanExpressionModel {
70+
71+
private final String thenValue;
72+
73+
public String thenValue() {
74+
return thenValue;
75+
}
76+
77+
protected SearchedWhenCondition(SqlCriterion initialCriterion, List<AndOrCriteriaGroup> subCriteria,
78+
String thenValue) {
79+
super(initialCriterion, subCriteria);
80+
this.thenValue = Objects.requireNonNull(thenValue);
81+
}
82+
}
83+
84+
public static class Builder {
85+
private final List<SearchedWhenCondition> whenConditions = new ArrayList<>();
86+
private String elseValue;
87+
private String alias;
88+
89+
public Builder withWhenConditions(List<SearchedWhenCondition> whenConditions) {
90+
this.whenConditions.addAll(whenConditions);
91+
return this;
92+
}
93+
94+
public Builder withElseValue(String elseValue) {
95+
this.elseValue = elseValue;
96+
return this;
97+
}
98+
99+
public Builder withAlias(String alias) {
100+
this.alias = alias;
101+
return this;
102+
}
103+
104+
public SearchedCaseModel build() {
105+
return new SearchedCaseModel(this);
106+
}
107+
}
108+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* Copyright 2016-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.mybatis.dynamic.sql.select;
17+
18+
import java.util.ArrayList;
19+
import java.util.Arrays;
20+
import java.util.List;
21+
import java.util.Objects;
22+
23+
import org.mybatis.dynamic.sql.BindableColumn;
24+
import org.mybatis.dynamic.sql.VisitableCondition;
25+
26+
public class SimpleCaseDSL<T> {
27+
private final BindableColumn<T> column;
28+
private final List<SimpleCaseModel.SimpleWhenCondition<T>> whenConditions = new ArrayList<>();
29+
private String elseValue;
30+
31+
private SimpleCaseDSL(BindableColumn<T> column) {
32+
this.column = Objects.requireNonNull(column);
33+
}
34+
35+
@SafeVarargs
36+
public final WhenFinisher when(VisitableCondition<T> condition,
37+
VisitableCondition<T>... subsequentConditions) {
38+
return when(condition, Arrays.asList(subsequentConditions));
39+
}
40+
41+
public WhenFinisher when(VisitableCondition<T> condition,
42+
List<VisitableCondition<T>> subsequentConditions) {
43+
return new WhenFinisher(condition, subsequentConditions);
44+
}
45+
46+
public SimpleCaseDSL<T> elseConstant(String value) {
47+
elseValue = value;
48+
return this;
49+
}
50+
51+
public SimpleCaseModel<T> end() {
52+
return new SimpleCaseModel.Builder<T>()
53+
.withColumn(column)
54+
.withWhenConditions(whenConditions)
55+
.withElseValue(elseValue)
56+
.build();
57+
}
58+
59+
public class WhenFinisher {
60+
private final List<VisitableCondition<T>> conditions = new ArrayList<>();
61+
62+
private WhenFinisher(VisitableCondition<T> condition, List<VisitableCondition<T>> subsequentConditions) {
63+
conditions.add(condition);
64+
conditions.addAll(subsequentConditions);
65+
}
66+
67+
public SimpleCaseDSL<T> thenConstant(String value) {
68+
whenConditions.add(new SimpleCaseModel.SimpleWhenCondition<>(conditions, value));
69+
return SimpleCaseDSL.this;
70+
}
71+
}
72+
73+
public static <T> SimpleCaseDSL<T> simpleCase(BindableColumn<T> column) {
74+
return new SimpleCaseDSL<>(column);
75+
}
76+
}

0 commit comments

Comments
 (0)