Skip to content

Commit 1f8c78c

Browse files
committed
Enable a standalone where clause
1 parent 77d8487 commit 1f8c78c

File tree

8 files changed

+153
-22
lines changed

8 files changed

+153
-22
lines changed

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

+10
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.mybatis.dynamic.sql.update.UpdateDSL;
4444
import org.mybatis.dynamic.sql.update.UpdateModel;
4545
import org.mybatis.dynamic.sql.util.Buildable;
46+
import org.mybatis.dynamic.sql.where.WhereDSL;
4647
import org.mybatis.dynamic.sql.where.condition.IsBetween;
4748
import org.mybatis.dynamic.sql.where.condition.IsEqualTo;
4849
import org.mybatis.dynamic.sql.where.condition.IsEqualToWithSubselect;
@@ -106,6 +107,15 @@ static UpdateDSL<UpdateModel> update(SqlTable table) {
106107
return UpdateDSL.update(table);
107108
}
108109

110+
static <T> WhereDSL where(BindableColumn<T> column, VisitableCondition<T> condition) {
111+
return WhereDSL.where(column, condition);
112+
}
113+
114+
static <T> WhereDSL where(BindableColumn<T> column, VisitableCondition<T> condition,
115+
SqlCriterion<?>... subCriteria) {
116+
return WhereDSL.where(column, condition, subCriteria);
117+
}
118+
109119
// where condition connectors
110120
static <T> SqlCriterion<T> or(BindableColumn<T> column, VisitableCondition<T> condition) {
111121
return new SqlCriterion.Builder<T>()

src/main/java/org/mybatis/dynamic/sql/delete/render/DeleteRenderer.java

+1-10
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,11 @@
1616
package org.mybatis.dynamic.sql.delete.render;
1717

1818
import java.util.Objects;
19-
import java.util.concurrent.atomic.AtomicInteger;
2019

2120
import org.mybatis.dynamic.sql.delete.DeleteModel;
2221
import org.mybatis.dynamic.sql.render.RenderingStrategy;
23-
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
2422
import org.mybatis.dynamic.sql.where.WhereModel;
2523
import org.mybatis.dynamic.sql.where.render.WhereClauseAndParameters;
26-
import org.mybatis.dynamic.sql.where.render.WhereRenderer;
2724

2825
public class DeleteRenderer {
2926
private DeleteModel deleteModel;
@@ -42,13 +39,7 @@ public DeleteStatement render() {
4239
}
4340

4441
private WhereClauseAndParameters renderWhereModel(WhereModel whereModel) {
45-
return new WhereRenderer.Builder()
46-
.withWhereModel(whereModel)
47-
.withRenderingStrategy(renderingStrategy)
48-
.withSequence(new AtomicInteger(1))
49-
.withTableAliasCalculator(TableAliasCalculator.empty())
50-
.build()
51-
.render();
42+
return whereModel.render(renderingStrategy);
5243
}
5344

5445
public static class Builder {

src/main/java/org/mybatis/dynamic/sql/render/TableAliasCalculator.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.mybatis.dynamic.sql.render;
1717

1818
import java.util.Collections;
19+
import java.util.HashMap;
1920
import java.util.Map;
2021
import java.util.Objects;
2122
import java.util.Optional;
@@ -38,11 +39,17 @@ public Optional<String> aliasForTable(SqlTable table) {
3839
return Optional.ofNullable(aliases.get(table));
3940
}
4041

42+
public static TableAliasCalculator of(SqlTable table, String alias) {
43+
Map<SqlTable, String> tableAliases = new HashMap<>();
44+
tableAliases.put(table, alias);
45+
return of(tableAliases);
46+
}
47+
4148
public static TableAliasCalculator of(Map<SqlTable, String> aliases) {
4249
return new TableAliasCalculator(aliases);
4350
}
4451

4552
public static TableAliasCalculator empty() {
46-
return new TableAliasCalculator(Collections.emptyMap());
53+
return of(Collections.emptyMap());
4754
}
4855
}

src/main/java/org/mybatis/dynamic/sql/update/render/UpdateRenderer.java

+1-10
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,16 @@
1616
package org.mybatis.dynamic.sql.update.render;
1717

1818
import java.util.Objects;
19-
import java.util.concurrent.atomic.AtomicInteger;
2019
import java.util.function.Function;
2120
import java.util.stream.Collectors;
2221

2322
import org.mybatis.dynamic.sql.render.RenderingStrategy;
24-
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
2523
import org.mybatis.dynamic.sql.update.UpdateModel;
2624
import org.mybatis.dynamic.sql.util.FragmentAndParameters;
2725
import org.mybatis.dynamic.sql.util.FragmentCollector;
2826
import org.mybatis.dynamic.sql.util.UpdateMapping;
2927
import org.mybatis.dynamic.sql.where.WhereModel;
3028
import org.mybatis.dynamic.sql.where.render.WhereClauseAndParameters;
31-
import org.mybatis.dynamic.sql.where.render.WhereRenderer;
3229

3330
public class UpdateRenderer {
3431
private UpdateModel updateModel;
@@ -59,13 +56,7 @@ private String calculateSetPhrase(FragmentCollector collector) {
5956
}
6057

6158
private WhereClauseAndParameters renderWhereModel(WhereModel whereModel) {
62-
return new WhereRenderer.Builder()
63-
.withWhereModel(whereModel)
64-
.withRenderingStrategy(renderingStrategy)
65-
.withSequence(new AtomicInteger(1))
66-
.withTableAliasCalculator(TableAliasCalculator.empty())
67-
.build()
68-
.render();
59+
return whereModel.render(renderingStrategy);
6960
}
7061

7162
private Function<UpdateMapping, FragmentAndParameters> toFragmentAndParameters(SetPhraseVisitor visitor) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Copyright 2016-2017 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+
* http://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.where;
17+
18+
import org.mybatis.dynamic.sql.BindableColumn;
19+
import org.mybatis.dynamic.sql.SqlCriterion;
20+
import org.mybatis.dynamic.sql.VisitableCondition;
21+
22+
public class WhereDSL extends AbstractWhereDSL<WhereDSL> {
23+
24+
private <T> WhereDSL(BindableColumn<T> column, VisitableCondition<T> condition) {
25+
super(column, condition);
26+
}
27+
28+
private <T> WhereDSL(BindableColumn<T> column, VisitableCondition<T> condition, SqlCriterion<?>... subCriteria) {
29+
super(column, condition, subCriteria);
30+
}
31+
32+
@Override
33+
protected WhereDSL getThis() {
34+
return this;
35+
}
36+
37+
public static <T> WhereDSL where(BindableColumn<T> column, VisitableCondition<T> condition) {
38+
return new WhereDSL(column, condition);
39+
}
40+
41+
public static <T> WhereDSL where(BindableColumn<T> column, VisitableCondition<T> condition,
42+
SqlCriterion<?>... subCriteria) {
43+
return new WhereDSL(column, condition, subCriteria);
44+
}
45+
46+
public WhereModel build() {
47+
return super.buildWhereModel();
48+
}
49+
}

src/main/java/org/mybatis/dynamic/sql/where/WhereModel.java

+26
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,15 @@
1717

1818
import java.util.ArrayList;
1919
import java.util.List;
20+
import java.util.concurrent.atomic.AtomicInteger;
2021
import java.util.function.Function;
2122
import java.util.stream.Stream;
2223

2324
import org.mybatis.dynamic.sql.SqlCriterion;
25+
import org.mybatis.dynamic.sql.render.RenderingStrategy;
26+
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
27+
import org.mybatis.dynamic.sql.where.render.WhereClauseAndParameters;
28+
import org.mybatis.dynamic.sql.where.render.WhereRenderer;
2429

2530
public class WhereModel {
2631
private List<SqlCriterion<?>> criteria = new ArrayList<>();
@@ -33,6 +38,27 @@ public <R> Stream<R> mapCriteria(Function<SqlCriterion<?>, R> mapper) {
3338
return criteria.stream().map(mapper);
3439
}
3540

41+
/**
42+
* Renders a where clause without table aliases.
43+
*
44+
* @param renderingStrategy rendering strategy
45+
* @return rendered where clause
46+
*/
47+
public WhereClauseAndParameters render(RenderingStrategy renderingStrategy) {
48+
return render(renderingStrategy, TableAliasCalculator.empty());
49+
}
50+
51+
public WhereClauseAndParameters render(RenderingStrategy renderingStrategy,
52+
TableAliasCalculator tableAliasCalculator) {
53+
return new WhereRenderer.Builder()
54+
.withWhereModel(this)
55+
.withRenderingStrategy(renderingStrategy)
56+
.withSequence(new AtomicInteger(1))
57+
.withTableAliasCalculator(tableAliasCalculator)
58+
.build()
59+
.render();
60+
}
61+
3662
public static WhereModel of(List<SqlCriterion<?>> criteria) {
3763
return new WhereModel(criteria);
3864
}

src/test/java/examples/animal/data/AnimalDataMapper.java

+20-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
import org.apache.ibatis.annotations.DeleteProvider;
2222
import org.apache.ibatis.annotations.InsertProvider;
2323
import org.apache.ibatis.annotations.Result;
24+
import org.apache.ibatis.annotations.ResultMap;
2425
import org.apache.ibatis.annotations.Results;
26+
import org.apache.ibatis.annotations.Select;
2527
import org.apache.ibatis.annotations.SelectProvider;
2628
import org.apache.ibatis.annotations.UpdateProvider;
2729
import org.mybatis.dynamic.sql.delete.render.DeleteStatement;
@@ -30,11 +32,12 @@
3032
import org.mybatis.dynamic.sql.select.render.SelectStatement;
3133
import org.mybatis.dynamic.sql.update.render.UpdateStatement;
3234
import org.mybatis.dynamic.sql.util.SqlProviderAdapter;
35+
import org.mybatis.dynamic.sql.where.render.WhereClauseAndParameters;
3336

3437
public interface AnimalDataMapper {
3538

3639
@SelectProvider(type=SqlProviderAdapter.class, method="select")
37-
@Results({
40+
@Results(id="AnimalDataResult", value={
3841
@Result(column="id", property="id", id=true),
3942
@Result(column="animal_name", property="animalName"),
4043
@Result(column="brain_weight", property="brainWeight"),
@@ -62,4 +65,20 @@ public interface AnimalDataMapper {
6265

6366
@InsertProvider(type=SqlProviderAdapter.class, method="insertSelect")
6467
int insertSelect(InsertSelectStatement insertSelectStatement);
68+
69+
@Select({
70+
"select id, animal_name, brain_weight, body_weight",
71+
"from AnimalData",
72+
"${whereClause}"
73+
})
74+
@ResultMap("AnimalDataResult")
75+
List<AnimalData> selectByExample(WhereClauseAndParameters whereClause);
76+
77+
@Select({
78+
"select a.id, a.animal_name, a.brain_weight, a.body_weight",
79+
"from AnimalData a",
80+
"${whereClause}"
81+
})
82+
@ResultMap("AnimalDataResult")
83+
List<AnimalData> selectByExampleWithAlias(WhereClauseAndParameters whereClause);
6584
}

src/test/java/examples/animal/data/AnimalDataTest.java

+38
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,10 @@
4848
import org.mybatis.dynamic.sql.insert.render.InsertSelectStatement;
4949
import org.mybatis.dynamic.sql.insert.render.InsertStatement;
5050
import org.mybatis.dynamic.sql.render.RenderingStrategy;
51+
import org.mybatis.dynamic.sql.render.TableAliasCalculator;
5152
import org.mybatis.dynamic.sql.select.render.SelectStatement;
5253
import org.mybatis.dynamic.sql.update.render.UpdateStatement;
54+
import org.mybatis.dynamic.sql.where.render.WhereClauseAndParameters;
5355

5456
@RunWith(JUnitPlatform.class)
5557
public class AnimalDataTest {
@@ -172,6 +174,23 @@ public void testSelectRowsNotBetween() {
172174
}
173175
}
174176

177+
@Test
178+
public void testSelectRowsNotBetweenWithStandaloneWhereClause() {
179+
SqlSession sqlSession = sqlSessionFactory.openSession();
180+
try {
181+
AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
182+
183+
WhereClauseAndParameters whereClause = where(id, isNotBetween(10).and(60))
184+
.build()
185+
.render(RenderingStrategy.MYBATIS3);
186+
187+
List<AnimalData> animals = mapper.selectByExample(whereClause);
188+
assertThat(animals.size()).isEqualTo(14);
189+
} finally {
190+
sqlSession.close();
191+
}
192+
}
193+
175194
@Test
176195
public void testUnionSelectWithWhere() {
177196
SqlSession sqlSession = sqlSessionFactory.openSession();
@@ -725,6 +744,25 @@ public void testComplexCondition() {
725744
}
726745
}
727746

747+
@Test
748+
public void testComplexConditionWithStandaloneWhereAndTableAlias() {
749+
SqlSession sqlSession = sqlSessionFactory.openSession();
750+
try {
751+
AnimalDataMapper mapper = sqlSession.getMapper(AnimalDataMapper.class);
752+
753+
WhereClauseAndParameters whereClause = where(id, isEqualTo(1), or(bodyWeight, isGreaterThan(1.0)))
754+
.build()
755+
.render(RenderingStrategy.MYBATIS3, TableAliasCalculator.of(animalData, "a"));
756+
757+
assertThat(whereClause.whereClause()).isEqualTo("where (a.id = #{parameters.p1,jdbcType=INTEGER} or a.body_weight > #{parameters.p2,jdbcType=DOUBLE})");
758+
759+
List<AnimalData> animals = mapper.selectByExampleWithAlias(whereClause);
760+
assertThat(animals.size()).isEqualTo(59);
761+
} finally {
762+
sqlSession.close();
763+
}
764+
}
765+
728766
@Test
729767
public void testUpdateByExample() {
730768
SqlSession sqlSession = sqlSessionFactory.openSession();

0 commit comments

Comments
 (0)