Skip to content

Commit 257c1b7

Browse files
authored
Merge pull request #454 from domaframework/semantics-of-condition-operators
Change the semantics of condition operators.
2 parents f33df36 + fd38fa8 commit 257c1b7

File tree

8 files changed

+512
-127
lines changed

8 files changed

+512
-127
lines changed

docs/criteria-api.rst

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,16 @@ We support the following operators and predicates:
494494

495495
.. note::
496496

497-
The ``eq`` operator generates the ``is null`` predicate if the second operand is ``null``.
498-
Also, the ``ne`` operator generates the ``is not null`` predicate if the second operand is ``null``.
497+
If the right hand operand is ``null``, the WHERE or the HAVING clause doesn't include the operator.
498+
See WhereDeclaration_ and HavingDeclaration_ javadoc for more details.
499499

500+
.. _WhereDeclaration: https://www.javadoc.io/doc/org.seasar.doma/doma-core/latest/org/seasar/doma/jdbc/criteria/declaration/WhereDeclaration.html
501+
.. _HavingDeclaration: https://www.javadoc.io/doc/org.seasar.doma/doma-core/latest/org/seasar/doma/jdbc/criteria/declaration/HavingDeclaration.html
502+
503+
We also support the following utility operators:
504+
505+
* eqOrIsNull - ("=" or "is null")
506+
* neOrIsNotNull - ("<>" or "is not null")
500507

501508
We also support the following logical operators:
502509

@@ -579,13 +586,13 @@ For example, suppose that a where expression contains a conditional expression a
579586
.where(
580587
c -> {
581588
c.eq(e.departmentId, 1);
582-
if (name != null) {
589+
if (enableNameCondition) {
583590
c.like(e.employeeName, name);
584591
}
585592
})
586593
.fetch();
587594
588-
In the case that the ``name`` variable is ``null``, the ``like`` expression is ignored.
595+
In the case that the ``enableNameCondition`` variable is ``false``, the ``like`` expression is ignored.
589596
The above query issues the following SQL statement:
590597

591598
.. code-block:: sql

doma-core/src/main/java/org/seasar/doma/jdbc/criteria/context/Criterion.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class Like implements Criterion {
132132

133133
public Like(Operand.Prop left, CharSequence right, LikeOption option) {
134134
this.left = Objects.requireNonNull(left);
135-
this.right = right;
135+
this.right = Objects.requireNonNull(right);
136136
this.option = Objects.requireNonNull(option);
137137
}
138138

@@ -149,7 +149,7 @@ class NotLike implements Criterion {
149149

150150
public NotLike(Operand.Prop left, CharSequence right, LikeOption option) {
151151
this.left = Objects.requireNonNull(left);
152-
this.right = right;
152+
this.right = Objects.requireNonNull(right);
153153
this.option = Objects.requireNonNull(option);
154154
}
155155

doma-core/src/main/java/org/seasar/doma/jdbc/criteria/declaration/ComparisonDeclaration.java

Lines changed: 198 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,82 +21,274 @@ protected ComparisonDeclaration(
2121
this.setter = Objects.requireNonNull(setter);
2222
}
2323

24+
/**
25+
* Adds a {@code =} operator.
26+
*
27+
* @param left the left hand operand
28+
* @param right the right hand operand. If this value is null, the query condition does'nt include
29+
* the operand.
30+
* @param <PROPERTY> the property type
31+
* @throws NullPointerException if {@code left} is null
32+
*/
2433
public <PROPERTY> void eq(PropertyMetamodel<PROPERTY> left, PROPERTY right) {
2534
Objects.requireNonNull(left);
26-
add(new Criterion.Eq(new Operand.Prop(left), new Operand.Param(left, right)));
35+
if (right != null) {
36+
add(new Criterion.Eq(new Operand.Prop(left), new Operand.Param(left, right)));
37+
}
2738
}
2839

40+
/**
41+
* Adds a {@code =} operator.
42+
*
43+
* @param left the left hand operand
44+
* @param right the right hand operand
45+
* @param <PROPERTY> the property type
46+
* @throws NullPointerException if {@code left} or {@code right} is null
47+
*/
2948
public <PROPERTY> void eq(PropertyMetamodel<PROPERTY> left, PropertyMetamodel<PROPERTY> right) {
3049
Objects.requireNonNull(left);
3150
Objects.requireNonNull(right);
3251
add(new Criterion.Eq(new Operand.Prop(left), new Operand.Prop(right)));
3352
}
3453

54+
/**
55+
* Adds a {@code <>} operator.
56+
*
57+
* @param left the left hand operand
58+
* @param right the right hand operand. If this value is null, the query condition does'nt include
59+
* the operand.
60+
* @param <PROPERTY> the property type
61+
* @throws NullPointerException if {@code left} is null
62+
*/
3563
public <PROPERTY> void ne(PropertyMetamodel<PROPERTY> left, PROPERTY right) {
3664
Objects.requireNonNull(left);
37-
add(new Criterion.Ne(new Operand.Prop(left), new Operand.Param(left, right)));
65+
if (right != null) {
66+
add(new Criterion.Ne(new Operand.Prop(left), new Operand.Param(left, right)));
67+
}
3868
}
3969

70+
/**
71+
* Adds a {@code <>} operator.
72+
*
73+
* @param left the left hand operand
74+
* @param right the right hand operand
75+
* @param <PROPERTY> the property type
76+
* @throws NullPointerException if {@code left} or {@code right} is null
77+
*/
4078
public <PROPERTY> void ne(PropertyMetamodel<PROPERTY> left, PropertyMetamodel<PROPERTY> right) {
4179
Objects.requireNonNull(left);
4280
Objects.requireNonNull(right);
4381
add(new Criterion.Ne(new Operand.Prop(left), new Operand.Prop(right)));
4482
}
4583

84+
/**
85+
* Adds a {@code >} operator.
86+
*
87+
* @param left the left hand operand
88+
* @param right the right hand operand. If this value is null, the query condition does'nt include
89+
* the operand.
90+
* @param <PROPERTY> the property type
91+
* @throws NullPointerException if {@code left} is null
92+
*/
4693
public <PROPERTY> void gt(PropertyMetamodel<PROPERTY> left, PROPERTY right) {
4794
Objects.requireNonNull(left);
48-
add(new Criterion.Gt(new Operand.Prop(left), new Operand.Param(left, right)));
95+
if (right != null) {
96+
add(new Criterion.Gt(new Operand.Prop(left), new Operand.Param(left, right)));
97+
}
4998
}
5099

100+
/**
101+
* Adds a {@code >} operator.
102+
*
103+
* @param left the left hand operand
104+
* @param right the right hand operand
105+
* @param <PROPERTY> the property type
106+
* @throws NullPointerException if {@code left} or {@code right} is null
107+
*/
51108
public <PROPERTY> void gt(PropertyMetamodel<PROPERTY> left, PropertyMetamodel<PROPERTY> right) {
52109
Objects.requireNonNull(left);
53110
Objects.requireNonNull(right);
54111
add(new Criterion.Gt(new Operand.Prop(left), new Operand.Prop(right)));
55112
}
56113

114+
/**
115+
* Adds a {@code >=} operator.
116+
*
117+
* @param left the left hand operand
118+
* @param right the right hand operand. If this value is null, the query condition does'nt include
119+
* the operand.
120+
* @param <PROPERTY> the property type
121+
* @throws NullPointerException if {@code left} is null
122+
*/
57123
public <PROPERTY> void ge(PropertyMetamodel<PROPERTY> left, PROPERTY right) {
58124
Objects.requireNonNull(left);
59-
add(new Criterion.Ge(new Operand.Prop(left), new Operand.Param(left, right)));
125+
if (right != null) {
126+
add(new Criterion.Ge(new Operand.Prop(left), new Operand.Param(left, right)));
127+
}
60128
}
61129

130+
/**
131+
* Adds a {@code >=} operator.
132+
*
133+
* @param left the left hand operand
134+
* @param right the right hand operand
135+
* @param <PROPERTY> the property type
136+
* @throws NullPointerException if {@code left} or {@code right} is null
137+
*/
62138
public <PROPERTY> void ge(PropertyMetamodel<PROPERTY> left, PropertyMetamodel<PROPERTY> right) {
63139
Objects.requireNonNull(left);
64140
Objects.requireNonNull(right);
65141
add(new Criterion.Ge(new Operand.Prop(left), new Operand.Prop(right)));
66142
}
67143

144+
/**
145+
* Adds a {@code <} operator.
146+
*
147+
* @param left the left hand operand
148+
* @param right the right hand operand. If this value is null, the query condition does'nt include
149+
* the operand.
150+
* @param <PROPERTY> the property type
151+
* @throws NullPointerException if {@code left} is null
152+
*/
68153
public <PROPERTY> void lt(PropertyMetamodel<PROPERTY> left, PROPERTY right) {
69154
Objects.requireNonNull(left);
70-
add(new Criterion.Lt(new Operand.Prop(left), new Operand.Param(left, right)));
155+
if (right != null) {
156+
add(new Criterion.Lt(new Operand.Prop(left), new Operand.Param(left, right)));
157+
}
71158
}
72159

160+
/**
161+
* Adds a {@code <} operator.
162+
*
163+
* @param left the left hand operand
164+
* @param right the right hand operand
165+
* @param <PROPERTY> the property type
166+
* @throws NullPointerException if {@code left} or {@code right} is null
167+
*/
73168
public <PROPERTY> void lt(PropertyMetamodel<PROPERTY> left, PropertyMetamodel<PROPERTY> right) {
74169
Objects.requireNonNull(left);
75170
Objects.requireNonNull(right);
76171
add(new Criterion.Lt(new Operand.Prop(left), new Operand.Prop(right)));
77172
}
78173

174+
/**
175+
* Adds a {@code <=} operator.
176+
*
177+
* @param left the left hand operand
178+
* @param right the right hand operand. If this value is null, the query condition does'nt include
179+
* the operand.
180+
* @param <PROPERTY> the property type
181+
* @throws NullPointerException if {@code left} is null
182+
*/
79183
public <PROPERTY> void le(PropertyMetamodel<PROPERTY> left, PROPERTY right) {
80184
Objects.requireNonNull(left);
81-
add(new Criterion.Le(new Operand.Prop(left), new Operand.Param(left, right)));
185+
if (right != null) {
186+
add(new Criterion.Le(new Operand.Prop(left), new Operand.Param(left, right)));
187+
}
82188
}
83189

190+
/**
191+
* Adds a {@code <=} operator.
192+
*
193+
* @param left the left hand operand
194+
* @param right the right hand operand
195+
* @param <PROPERTY> the property type
196+
* @throws NullPointerException if {@code left} or {@code right} is null
197+
*/
84198
public <PROPERTY> void le(PropertyMetamodel<PROPERTY> left, PropertyMetamodel<PROPERTY> right) {
85199
Objects.requireNonNull(left);
86200
Objects.requireNonNull(right);
87201
add(new Criterion.Le(new Operand.Prop(left), new Operand.Prop(right)));
88202
}
89203

204+
/**
205+
* Adds a {@code IS NULL} operator.
206+
*
207+
* @param propertyMetamodel the left hand operand
208+
* @param <PROPERTY> the property type
209+
* @throws NullPointerException if {@code propertyMetamodel} is null
210+
*/
211+
public <PROPERTY> void isNull(PropertyMetamodel<PROPERTY> propertyMetamodel) {
212+
Objects.requireNonNull(propertyMetamodel);
213+
add(new Criterion.IsNull(new Operand.Prop(propertyMetamodel)));
214+
}
215+
216+
/**
217+
* Adds a {@code IS NOT NULL} operator.
218+
*
219+
* @param propertyMetamodel the left hand operand
220+
* @param <PROPERTY> the property type
221+
* @throws NullPointerException if {@code propertyMetamodel} is null
222+
*/
223+
public <PROPERTY> void isNotNull(PropertyMetamodel<PROPERTY> propertyMetamodel) {
224+
Objects.requireNonNull(propertyMetamodel);
225+
add(new Criterion.IsNotNull(new Operand.Prop(propertyMetamodel)));
226+
}
227+
228+
/**
229+
* Adds a {@code =} operator or a {@code IS NULL} operator.
230+
*
231+
* @param left the left hand operand
232+
* @param right the right hand operand. If this value is null, the query condition includes the
233+
* {@code IS NULL} operator.
234+
* @param <PROPERTY> the property type
235+
* @throws NullPointerException if {@code left} is null
236+
*/
237+
public <PROPERTY> void eqOrIsNull(PropertyMetamodel<PROPERTY> left, PROPERTY right) {
238+
Objects.requireNonNull(left);
239+
if (right == null) {
240+
add(new Criterion.IsNull(new Operand.Prop(left)));
241+
} else {
242+
add(new Criterion.Eq(new Operand.Prop(left), new Operand.Param(left, right)));
243+
}
244+
}
245+
246+
/**
247+
* Adds a {@code <>} operator or a {@code IS NOT NULL} operator.
248+
*
249+
* @param left the left hand operand
250+
* @param right the right hand operand. If this value is null, the query condition includes the
251+
* {@code IS NOT NULL} operator.
252+
* @param <PROPERTY> the property type
253+
* @throws NullPointerException if {@code left} is null
254+
*/
255+
public <PROPERTY> void neOrIsNotNull(PropertyMetamodel<PROPERTY> left, PROPERTY right) {
256+
Objects.requireNonNull(left);
257+
if (right == null) {
258+
add(new Criterion.IsNotNull(new Operand.Prop(left)));
259+
} else {
260+
add(new Criterion.Ne(new Operand.Prop(left), new Operand.Param(left, right)));
261+
}
262+
}
263+
264+
/**
265+
* Add a {@code AND} operator.
266+
*
267+
* @param block the right hand operand
268+
* @throws NullPointerException if {@code block} is null
269+
*/
90270
public void and(Runnable block) {
91271
Objects.requireNonNull(block);
92272
runBlock(block, Criterion.And::new);
93273
}
94274

275+
/**
276+
* Add a {@code OR} operator.
277+
*
278+
* @param block the right hand operand
279+
* @throws NullPointerException if {@code block} is null
280+
*/
95281
public void or(Runnable block) {
96282
Objects.requireNonNull(block);
97283
runBlock(block, Criterion.Or::new);
98284
}
99285

286+
/**
287+
* Add a {@code NOT} operator.
288+
*
289+
* @param block the right hand operand
290+
* @throws NullPointerException if {@code block} is null
291+
*/
100292
public void not(Runnable block) {
101293
Objects.requireNonNull(block);
102294
runBlock(block, Criterion.Not::new);

doma-core/src/main/java/org/seasar/doma/jdbc/criteria/declaration/HavingDeclaration.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.Objects;
44
import org.seasar.doma.jdbc.criteria.context.SelectContext;
55

6+
/** The having declaration. */
67
public class HavingDeclaration extends ComparisonDeclaration {
78

89
public HavingDeclaration(SelectContext context) {

0 commit comments

Comments
 (0)