0
# Condition Builders
1
2
MyBatis-Plus Extension provides fluent API builders for constructing complex database queries and updates through method chaining. The condition builders offer both traditional string-based and type-safe lambda-based approaches for building database operations.
3
4
## Core Components
5
6
### Query Chain Wrappers
7
8
Query chain wrappers allow building complex SELECT queries with fluent method chaining.
9
10
```java { .api }
11
public class QueryChainWrapper<T> extends AbstractChainWrapper<T, String, QueryChainWrapper<T>, QueryWrapper<T>>
12
implements ChainQuery<T> {
13
14
public QueryChainWrapper(BaseMapper<T> baseMapper);
15
public QueryChainWrapper(Class<T> entityClass);
16
17
// Terminal operations
18
public List<T> list();
19
public T one();
20
public Optional<T> oneOpt();
21
public long count();
22
public boolean exists();
23
public <E extends IPage<T>> E page(E page);
24
25
// Select operations
26
public QueryChainWrapper<T> select(String... columns);
27
public String getSqlSelect();
28
29
// Access methods
30
public BaseMapper<T> getBaseMapper();
31
public Class<T> getEntityClass();
32
}
33
34
public class LambdaQueryChainWrapper<T> extends AbstractChainWrapper<T, SFunction<T, ?>, LambdaQueryChainWrapper<T>, LambdaQueryWrapper<T>>
35
implements ChainQuery<T> {
36
37
public LambdaQueryChainWrapper(BaseMapper<T> baseMapper);
38
public LambdaQueryChainWrapper(Class<T> entityClass);
39
40
// Terminal operations
41
public List<T> list();
42
public T one();
43
public Optional<T> oneOpt();
44
public long count();
45
public boolean exists();
46
public <E extends IPage<T>> E page(E page);
47
48
// Select operations
49
public LambdaQueryChainWrapper<T> select(SFunction<T, ?>... columns);
50
}
51
```
52
53
### Update Chain Wrappers
54
55
Update chain wrappers provide fluent API for UPDATE and DELETE operations.
56
57
```java { .api }
58
public class UpdateChainWrapper<T> extends AbstractChainWrapper<T, String, UpdateChainWrapper<T>, UpdateWrapper<T>>
59
implements ChainUpdate<T> {
60
61
public UpdateChainWrapper(BaseMapper<T> baseMapper);
62
public UpdateChainWrapper(Class<T> entityClass);
63
64
// Terminal operations
65
public boolean update();
66
public boolean update(T entity);
67
public boolean remove();
68
69
// Set operations
70
public UpdateChainWrapper<T> set(String column, Object val);
71
public UpdateChainWrapper<T> setSql(String sql);
72
73
// Access methods
74
public BaseMapper<T> getBaseMapper();
75
public Class<T> getEntityClass();
76
}
77
78
public class LambdaUpdateChainWrapper<T> extends AbstractChainWrapper<T, SFunction<T, ?>, LambdaUpdateChainWrapper<T>, LambdaUpdateWrapper<T>>
79
implements ChainUpdate<T> {
80
81
public LambdaUpdateChainWrapper(BaseMapper<T> baseMapper);
82
public LambdaUpdateChainWrapper(Class<T> entityClass);
83
84
// Terminal operations
85
public boolean update();
86
public boolean update(T entity);
87
public boolean remove();
88
89
// Set operations
90
public LambdaUpdateChainWrapper<T> set(SFunction<T, ?> column, Object val);
91
public LambdaUpdateChainWrapper<T> setSql(String sql);
92
}
93
```
94
95
### Chain Interfaces
96
97
Base interfaces defining the contract for chain operations.
98
99
```java { .api }
100
public interface ChainQuery<T> {
101
List<T> list();
102
T one();
103
Optional<T> oneOpt();
104
long count();
105
boolean exists();
106
<E extends IPage<T>> E page(E page);
107
}
108
109
public interface ChainUpdate<T> {
110
boolean update();
111
boolean update(T entity);
112
boolean remove();
113
}
114
115
public interface ChainWrapper<T> {
116
BaseMapper<T> getBaseMapper();
117
Class<T> getEntityClass();
118
}
119
```
120
121
### Base Chain Wrapper
122
123
```java { .api }
124
public abstract class AbstractChainWrapper<T, R, Children, Wrapper> implements ChainWrapper<T> {
125
protected BaseMapper<T> baseMapper;
126
protected Class<T> entityClass;
127
protected Wrapper wrapper;
128
129
public BaseMapper<T> getBaseMapper();
130
public Class<T> getEntityClass();
131
protected Wrapper getWrapper();
132
protected Children instance();
133
}
134
```
135
136
## Usage Examples
137
138
### Basic Query Chains
139
140
```java
141
// Using service method to create chain
142
@Autowired
143
private UserService userService;
144
145
// Simple query chain
146
List<User> activeUsers = userService.query()
147
.eq("active", true)
148
.list();
149
150
// Lambda query chain with type safety
151
List<User> adults = userService.lambdaQuery()
152
.ge(User::getAge, 18)
153
.eq(User::getActive, true)
154
.list();
155
156
// Using ChainWrappers factory
157
List<User> users = ChainWrappers.queryChain(userMapper)
158
.eq("status", "ACTIVE")
159
.gt("created_time", LocalDateTime.now().minusDays(30))
160
.list();
161
```
162
163
### Complex Query Conditions
164
165
```java
166
// Multiple conditions with different operators
167
List<User> users = userService.query()
168
.eq("active", true)
169
.ne("status", "DELETED")
170
.gt("age", 18)
171
.le("age", 65)
172
.like("name", "John")
173
.isNotNull("email")
174
.in("role", Arrays.asList("USER", "ADMIN"))
175
.between("created_time", startDate, endDate)
176
.orderByDesc("created_time")
177
.list();
178
179
// Using OR conditions
180
List<User> users = userService.query()
181
.eq("active", true)
182
.and(wrapper -> wrapper
183
.eq("role", "ADMIN")
184
.or()
185
.gt("score", 90)
186
)
187
.list();
188
189
// Nested conditions with lambda
190
List<User> premiumUsers = userService.lambdaQuery()
191
.eq(User::getActive, true)
192
.and(wrapper -> wrapper
193
.eq(User::getSubscriptionType, "PREMIUM")
194
.or()
195
.ge(User::getCredits, 1000)
196
)
197
.orderByDesc(User::getCreatedTime)
198
.list();
199
```
200
201
### Select Specific Columns
202
203
```java
204
// Select specific columns using string names
205
List<User> users = userService.query()
206
.select("id", "name", "email")
207
.eq("active", true)
208
.list();
209
210
// Select specific columns using lambda (type-safe)
211
List<User> users = userService.lambdaQuery()
212
.select(User::getId, User::getName, User::getEmail)
213
.eq(User::getActive, true)
214
.list();
215
```
216
217
### Single Result Queries
218
219
```java
220
// Get single result
221
User user = userService.query()
222
.eq("email", "john@example.com")
223
.one();
224
225
// Get optional result (safer)
226
Optional<User> optionalUser = userService.lambdaQuery()
227
.eq(User::getEmail, "john@example.com")
228
.oneOpt();
229
230
if (optionalUser.isPresent()) {
231
User user = optionalUser.get();
232
// Process user
233
}
234
```
235
236
### Count and Existence Checks
237
238
```java
239
// Count records
240
long totalActive = userService.query()
241
.eq("active", true)
242
.count();
243
244
// Check existence
245
boolean hasAdminUsers = userService.lambdaQuery()
246
.eq(User::getRole, "ADMIN")
247
.exists();
248
```
249
250
### Pagination with Chains
251
252
```java
253
// Paginated query
254
Page<User> page = new Page<>(1, 10);
255
Page<User> result = userService.query()
256
.eq("active", true)
257
.orderByDesc("created_time")
258
.page(page);
259
260
List<User> users = result.getRecords();
261
long total = result.getTotal();
262
263
// Lambda pagination
264
Page<User> premiumPage = userService.lambdaQuery()
265
.eq(User::getSubscriptionType, "PREMIUM")
266
.orderByDesc(User::getLastLogin)
267
.page(new Page<>(1, 20));
268
```
269
270
### Update Chains
271
272
```java
273
// Simple update
274
boolean updated = userService.update()
275
.set("last_login", LocalDateTime.now())
276
.eq("id", 1L)
277
.update();
278
279
// Lambda update with type safety
280
boolean deactivated = userService.lambdaUpdate()
281
.set(User::getActive, false)
282
.set(User::getDeactivatedTime, LocalDateTime.now())
283
.isNull(User::getLastLogin)
284
.update();
285
286
// Update with entity
287
User updateEntity = new User();
288
updateEntity.setActive(false);
289
boolean updated = userService.lambdaUpdate()
290
.eq(User::getRole, "TEMP")
291
.update(updateEntity);
292
```
293
294
### Remove Operations with Chains
295
296
```java
297
// Delete with conditions
298
boolean removed = userService.update()
299
.eq("active", false)
300
.isNull("last_login")
301
.remove();
302
303
// Lambda delete
304
boolean removed = userService.lambdaUpdate()
305
.eq(User::getStatus, "DELETED")
306
.lt(User::getCreatedTime, LocalDateTime.now().minusYears(1))
307
.remove();
308
```
309
310
### Complex Update Operations
311
312
```java
313
// Multiple set operations
314
boolean updated = userService.update()
315
.set("status", "INACTIVE")
316
.set("deactivated_time", LocalDateTime.now())
317
.setSql("login_attempts = login_attempts + 1")
318
.eq("active", true)
319
.gt("failed_login_count", 5)
320
.update();
321
322
// Conditional updates with complex logic
323
boolean updated = userService.lambdaUpdate()
324
.set(User::getStatus, "SUSPENDED")
325
.set(User::getSuspendedTime, LocalDateTime.now())
326
.and(wrapper -> wrapper
327
.gt(User::getFailedLoginCount, 3)
328
.or()
329
.eq(User::getReportedByUsers, true)
330
)
331
.update();
332
```
333
334
### Using with Direct Mapper
335
336
```java
337
@Autowired
338
private UserMapper userMapper;
339
340
// Create chains directly with mapper
341
List<User> users = ChainWrappers.queryChain(userMapper)
342
.eq("department", "IT")
343
.orderByAsc("name")
344
.list();
345
346
boolean updated = ChainWrappers.updateChain(userMapper)
347
.set("department", "Engineering")
348
.eq("department", "IT")
349
.update();
350
351
// Lambda chains with mapper
352
List<User> managers = ChainWrappers.lambdaQueryChain(userMapper)
353
.eq(User::getRole, "MANAGER")
354
.isNotNull(User::getTeamId)
355
.list();
356
```
357
358
### Static Factory Usage
359
360
```java
361
// Using entity class instead of mapper
362
List<User> users = ChainWrappers.queryChain(User.class)
363
.eq("active", true)
364
.list();
365
366
boolean updated = ChainWrappers.lambdaUpdateChain(User.class)
367
.set(User::getLastModified, LocalDateTime.now())
368
.eq(User::getId, 1L)
369
.update();
370
```
371
372
## Advanced Features
373
374
### Custom SQL in Updates
375
376
```java
377
// Using setSql for complex expressions
378
boolean updated = userService.update()
379
.setSql("score = score * 1.1")
380
.setSql("updated_time = NOW()")
381
.eq("active", true)
382
.update();
383
```
384
385
### Combining with Regular Wrappers
386
387
```java
388
// You can still use regular QueryWrapper/UpdateWrapper for more complex scenarios
389
QueryWrapper<User> wrapper = new QueryWrapper<>();
390
wrapper.eq("active", true)
391
.nested(w -> w.eq("role", "ADMIN").or().gt("score", 90))
392
.orderByDesc("created_time");
393
394
List<User> users = userService.list(wrapper);
395
```
396
397
### Error Handling
398
399
```java
400
// Handle single result operations safely
401
try {
402
User user = userService.query()
403
.eq("email", "unique@example.com")
404
.one(); // May throw exception if multiple results
405
} catch (Exception e) {
406
// Handle multiple results or other errors
407
}
408
409
// Safer approach with Optional
410
Optional<User> user = userService.lambdaQuery()
411
.eq(User::getEmail, "unique@example.com")
412
.oneOpt();
413
```
414
415
## Performance Considerations
416
417
- Chain wrappers are lightweight and don't hold database connections
418
- Terminal operations (`list()`, `one()`, `update()`, etc.) execute the actual database query
419
- Use `select()` to limit columns when you don't need the full entity
420
- Consider pagination for large result sets
421
- Lambda chains provide type safety but may have slight performance overhead compared to string-based chains