0
# Service Layer Interface
1
2
Business logic abstraction with enhanced CRUD operations, batch processing, and query chaining. The IService interface provides a comprehensive service layer pattern that's perfect for service-oriented architectures and dependency injection frameworks.
3
4
## Capabilities
5
6
### IService Interface
7
8
Comprehensive service interface providing business logic layer operations with enhanced functionality beyond basic CRUD.
9
10
```java { .api }
11
/**
12
* Enhanced service layer interface for business logic operations
13
* @param <T> Entity type
14
*/
15
public interface IService<T> {
16
int DEFAULT_BATCH_SIZE = 1000;
17
18
/**
19
* Get the base mapper for entity operations
20
* @return BaseMapper instance
21
*/
22
BaseMapper<T> getMapper();
23
24
// ===== Save operations =====
25
26
/**
27
* Save single entity (ignores null properties)
28
* @param entity entity to save
29
* @return true if successful
30
*/
31
boolean save(T entity);
32
33
/**
34
* Save multiple entities in batch (default batch size: 1000)
35
* @param entities collection of entities to save
36
* @return true if all successful
37
*/
38
boolean saveBatch(Collection<T> entities);
39
40
/**
41
* Save multiple entities with custom batch size
42
* @param entities collection of entities to save
43
* @param batchSize number of entities per batch
44
* @return true if all successful
45
*/
46
boolean saveBatch(Collection<T> entities, int batchSize);
47
48
/**
49
* Save or update entity based on primary key existence (ignores null properties)
50
* @param entity entity to save or update
51
* @return true if successful
52
*/
53
boolean saveOrUpdate(T entity);
54
55
/**
56
* Save or update multiple entities in batch (default batch size: 1000)
57
* @param entities collection of entities
58
* @return true if all successful
59
*/
60
boolean saveOrUpdateBatch(Collection<T> entities);
61
62
/**
63
* Save or update multiple entities with custom batch size
64
* @param entities collection of entities
65
* @param batchSize number of entities per batch
66
* @return true if all successful
67
*/
68
boolean saveOrUpdateBatch(Collection<T> entities, int batchSize);
69
70
// ===== Remove operations =====
71
72
/**
73
* Remove entities by query wrapper conditions
74
* @param query query conditions
75
* @return true if successful
76
*/
77
boolean remove(QueryWrapper query);
78
79
/**
80
* Remove entities by query condition
81
* @param condition query condition
82
* @return true if successful
83
*/
84
boolean remove(QueryCondition condition);
85
86
/**
87
* Remove entity by entity object (using primary key)
88
* @param entity entity object with primary key
89
* @return true if successful
90
*/
91
boolean removeById(T entity);
92
93
/**
94
* Remove entity by primary key
95
* @param id primary key value
96
* @return true if successful
97
*/
98
boolean removeById(Serializable id);
99
100
/**
101
* Remove entities by primary key collection
102
* @param ids collection of primary key values
103
* @return true if successful
104
*/
105
boolean removeByIds(Collection<? extends Serializable> ids);
106
107
/**
108
* Remove entities by Map conditions (prevents empty map to avoid full table deletion)
109
* @param query Map of column-value conditions
110
* @return true if successful
111
* @throws FlexException if map is null or empty
112
*/
113
boolean removeByMap(Map<String, Object> query);
114
115
// ===== Update operations =====
116
117
/**
118
* Update entity by primary key (ignores null properties by default)
119
* @param entity entity to update
120
* @return true if successful
121
*/
122
boolean updateById(T entity);
123
124
/**
125
* Update entity by primary key with null handling option
126
* @param entity entity to update
127
* @param ignoreNulls whether to ignore null properties
128
* @return true if successful
129
*/
130
boolean updateById(T entity, boolean ignoreNulls);
131
132
/**
133
* Update entity by Map conditions
134
* @param entity entity with new values
135
* @param query Map of where conditions
136
* @return true if successful
137
*/
138
boolean update(T entity, Map<String, Object> query);
139
140
/**
141
* Update entity by query wrapper conditions
142
* @param entity entity with new values
143
* @param query query wrapper conditions
144
* @return true if successful
145
*/
146
boolean update(T entity, QueryWrapper query);
147
148
/**
149
* Update entity by query condition
150
* @param entity entity with new values
151
* @param condition query condition
152
* @return true if successful
153
*/
154
boolean update(T entity, QueryCondition condition);
155
156
/**
157
* Batch update entities by primary key (default batch size: 1000, ignores null properties)
158
* @param entities collection of entities to update
159
* @return true if all successful
160
*/
161
boolean updateBatch(Collection<T> entities);
162
163
/**
164
* Batch update entities with null handling option (default batch size: 1000)
165
* @param entities collection of entities to update
166
* @param ignoreNulls whether to ignore null properties
167
* @return true if all successful
168
*/
169
boolean updateBatch(Collection<T> entities, boolean ignoreNulls);
170
171
/**
172
* Batch update entities with custom batch size (ignores null properties)
173
* @param entities collection of entities to update
174
* @param batchSize number of entities per batch
175
* @return true if all successful
176
*/
177
boolean updateBatch(Collection<T> entities, int batchSize);
178
179
/**
180
* Batch update entities with custom batch size and null handling option
181
* @param entities collection of entities to update
182
* @param batchSize number of entities per batch
183
* @param ignoreNulls whether to ignore null properties
184
* @return true if all successful
185
*/
186
boolean updateBatch(Collection<T> entities, int batchSize, boolean ignoreNulls);
187
188
// ===== Query operations =====
189
190
/**
191
* Get entity by primary key
192
* @param id primary key value
193
* @return entity or null if not found
194
*/
195
T getById(Serializable id);
196
197
/**
198
* Get entity by entity primary key
199
* @param entity entity object with primary key
200
* @return entity or null if not found
201
*/
202
T getOneByEntityId(T entity);
203
204
/**
205
* Get entity by entity primary key with Optional wrapper
206
* @param entity entity object with primary key
207
* @return Optional containing entity or empty
208
*/
209
Optional<T> getByEntityIdOpt(T entity);
210
211
/**
212
* Get entity by primary key with Optional wrapper
213
* @param id primary key value
214
* @return Optional containing entity or empty
215
*/
216
Optional<T> getByIdOpt(Serializable id);
217
218
/**
219
* Get single entity by query wrapper conditions
220
* @param query query conditions
221
* @return single entity or null
222
*/
223
T getOne(QueryWrapper query);
224
225
/**
226
* Get single entity by query wrapper with Optional wrapper
227
* @param query query conditions
228
* @return Optional containing entity or empty
229
*/
230
Optional<T> getOneOpt(QueryWrapper query);
231
232
/**
233
* Get single entity by query wrapper and transform to target type
234
* @param query query conditions
235
* @param asType target type class
236
* @return transformed object or null
237
*/
238
<R> R getOneAs(QueryWrapper query, Class<R> asType);
239
240
/**
241
* Get single entity by query wrapper, transform to target type with Optional wrapper
242
* @param query query conditions
243
* @param asType target type class
244
* @return Optional containing transformed object or empty
245
*/
246
<R> Optional<R> getOneAsOpt(QueryWrapper query, Class<R> asType);
247
248
/**
249
* Get single entity by query condition
250
* @param condition query condition
251
* @return single entity or null
252
*/
253
T getOne(QueryCondition condition);
254
255
/**
256
* Get single entity by query condition with Optional wrapper
257
* @param condition query condition
258
* @return Optional containing entity or empty
259
*/
260
Optional<T> getOneOpt(QueryCondition condition);
261
262
/**
263
* Get first column value of first row from query result
264
* @param query query conditions
265
* @return object value or null
266
*/
267
Object getObj(QueryWrapper query);
268
269
/**
270
* Get first column value of first row with Optional wrapper
271
* @param query query conditions
272
* @return Optional containing object value or empty
273
*/
274
Optional<Object> getObjOpt(QueryWrapper query);
275
276
/**
277
* Get first column value of first row and cast to target type
278
* @param query query conditions
279
* @param asType target type class (e.g., Long.class, String.class)
280
* @return typed value or null
281
*/
282
<R> R getObjAs(QueryWrapper query, Class<R> asType);
283
284
/**
285
* Get first column value of first row, cast to target type with Optional wrapper
286
* @param query query conditions
287
* @param asType target type class
288
* @return Optional containing typed value or empty
289
*/
290
<R> Optional<R> getObjAsOpt(QueryWrapper query, Class<R> asType);
291
292
/**
293
* Get all values from first column of query result
294
* @param query query conditions
295
* @return list of object values
296
*/
297
List<Object> objList(QueryWrapper query);
298
299
/**
300
* Get all values from first column and cast to target type
301
* @param query query conditions
302
* @param asType target type class
303
* @return list of typed values
304
*/
305
<R> List<R> objListAs(QueryWrapper query, Class<R> asType);
306
307
/**
308
* Get all entities
309
* @return list of all entities
310
*/
311
List<T> list();
312
313
/**
314
* Get entities by query wrapper conditions
315
* @param query query conditions
316
* @return list of entities
317
*/
318
List<T> list(QueryWrapper query);
319
320
/**
321
* Get entities by query condition
322
* @param condition query condition
323
* @return list of entities
324
*/
325
List<T> list(QueryCondition condition);
326
327
/**
328
* Get entities by query wrapper and transform to target type
329
* @param query query conditions
330
* @param asType target type class
331
* @return list of transformed objects
332
*/
333
<R> List<R> listAs(QueryWrapper query, Class<R> asType);
334
335
/**
336
* Get entities by primary key collection
337
* @param ids collection of primary key values
338
* @return list of entities
339
*/
340
List<T> listByIds(Collection<? extends Serializable> ids);
341
342
/**
343
* Get entities by Map conditions
344
* @param query Map of column-value conditions
345
* @return list of entities
346
*/
347
List<T> listByMap(Map<String, Object> query);
348
349
// ===== Count and existence operations =====
350
351
/**
352
* Check if entities exist by query wrapper conditions
353
* @param query query conditions
354
* @return true if exists, false otherwise
355
*/
356
boolean exists(QueryWrapper query);
357
358
/**
359
* Check if entities exist by query condition
360
* @param condition query condition
361
* @return true if exists, false otherwise
362
*/
363
boolean exists(QueryCondition condition);
364
365
/**
366
* Count all entities
367
* @return total count
368
*/
369
long count();
370
371
/**
372
* Count entities by query wrapper conditions
373
* @param query query conditions
374
* @return count matching conditions
375
*/
376
long count(QueryWrapper query);
377
378
/**
379
* Count entities by query condition
380
* @param condition query condition
381
* @return count matching condition
382
*/
383
long count(QueryCondition condition);
384
385
// ===== Pagination operations =====
386
387
/**
388
* Paginate all entities
389
* @param page pagination parameters
390
* @return page of entities
391
*/
392
Page<T> page(Page<T> page);
393
394
/**
395
* Paginate entities by query wrapper conditions
396
* @param page pagination parameters
397
* @param query query conditions
398
* @return page of entities
399
*/
400
Page<T> page(Page<T> page, QueryWrapper query);
401
402
/**
403
* Paginate entities by query condition
404
* @param page pagination parameters
405
* @param condition query condition
406
* @return page of entities
407
*/
408
Page<T> page(Page<T> page, QueryCondition condition);
409
410
/**
411
* Paginate entities with type transformation
412
* @param page pagination parameters
413
* @param query query conditions
414
* @param asType target type class
415
* @return page of transformed objects
416
*/
417
<R> Page<R> pageAs(Page<R> page, QueryWrapper query, Class<R> asType);
418
419
// ===== Query wrapper and chain operations =====
420
421
/**
422
* Create default QueryWrapper
423
* @return QueryWrapper instance
424
*/
425
QueryWrapper query();
426
427
/**
428
* Create query chain for fluent operations
429
* @return QueryChain instance
430
*/
431
QueryChain<T> queryChain();
432
433
/**
434
* Create update chain for fluent operations
435
* @return UpdateChain instance
436
*/
437
UpdateChain<T> updateChain();
438
}
439
```
440
441
**Service Implementation Example:**
442
443
```java
444
import com.mybatisflex.core.service.IService;
445
import org.springframework.stereotype.Service;
446
447
// Entity
448
@Table("users")
449
public class User {
450
@Id
451
private Long id;
452
private String name;
453
private Integer age;
454
private String email;
455
private Boolean active;
456
private Date createTime;
457
458
// Constructors, getters, setters...
459
}
460
461
// Service interface
462
public interface UserService extends IService<User> {
463
// Custom business methods
464
List<User> findActiveUsers();
465
List<User> findUsersByAgeRange(int minAge, int maxAge);
466
boolean deactivateUser(Long userId);
467
}
468
469
// Service implementation
470
@Service
471
public class UserServiceImpl implements UserService {
472
473
@Override
474
public List<User> findActiveUsers() {
475
return list(QueryWrapper.create()
476
.from(User.class)
477
.where(USER.ACTIVE.eq(true))
478
.orderBy(USER.CREATE_TIME.desc()));
479
}
480
481
@Override
482
public List<User> findUsersByAgeRange(int minAge, int maxAge) {
483
return list(QueryWrapper.create()
484
.from(User.class)
485
.where(USER.AGE.between(minAge, maxAge))
486
.and(USER.ACTIVE.eq(true)));
487
}
488
489
@Override
490
public boolean deactivateUser(Long userId) {
491
User user = getById(userId);
492
if (user != null) {
493
user.setActive(false);
494
return update(user);
495
}
496
return false;
497
}
498
}
499
```
500
501
### Save Operations
502
503
Comprehensive save operations with batch processing and upsert functionality.
504
505
```java { .api }
506
/**
507
* Save single entity (ignores null properties)
508
* @param entity entity to save
509
* @return true if successful
510
*/
511
boolean save(T entity);
512
513
/**
514
* Save multiple entities in batch (default batch size: 1000)
515
* @param entities collection of entities to save
516
* @return true if all successful
517
*/
518
boolean saveBatch(Collection<T> entities);
519
520
/**
521
* Save multiple entities with custom batch size
522
* @param entities collection of entities to save
523
* @param batchSize number of entities per batch
524
* @return true if all successful
525
*/
526
boolean saveBatch(Collection<T> entities, int batchSize);
527
528
/**
529
* Save or update entity based on primary key existence (ignores null properties)
530
* @param entity entity to save or update
531
* @return true if successful
532
*/
533
boolean saveOrUpdate(T entity);
534
535
/**
536
* Save or update multiple entities in batch (default batch size: 1000)
537
* @param entities collection of entities
538
* @return true if all successful
539
*/
540
boolean saveOrUpdateBatch(Collection<T> entities);
541
542
/**
543
* Save or update multiple entities with custom batch size
544
* @param entities collection of entities
545
* @param batchSize number of entities per batch
546
* @return true if all successful
547
*/
548
boolean saveOrUpdateBatch(Collection<T> entities, int batchSize);
549
```
550
551
**Save Examples:**
552
553
```java
554
@Autowired
555
private UserService userService;
556
557
public void demonstrateSaveOperations() {
558
// Single save
559
User user = new User("Alice", 25, "alice@example.com");
560
boolean saved = userService.save(user);
561
562
// Batch save
563
List<User> users = Arrays.asList(
564
new User("Bob", 30, "bob@example.com"),
565
new User("Charlie", 28, "charlie@example.com"),
566
new User("Diana", 32, "diana@example.com")
567
);
568
boolean batchSaved = userService.saveBatch(users);
569
570
// Custom batch size
571
boolean customBatchSaved = userService.saveBatch(users, 2);
572
573
// Save or update
574
User existingUser = userService.getById(1L);
575
existingUser.setAge(26);
576
boolean upserted = userService.saveOrUpdate(existingUser);
577
578
// New user (will be inserted)
579
User newUser = new User("Eve", 29, "eve@example.com");
580
boolean newUpserted = userService.saveOrUpdate(newUser);
581
582
// Save or update multiple entities in batch
583
List<User> existingUsers = userService.listByIds(Arrays.asList(1L, 2L, 3L));
584
existingUsers.forEach(user -> user.setAge(user.getAge() + 1));
585
boolean batchUpserted = userService.saveOrUpdateBatch(existingUsers);
586
587
// Save or update with custom batch size
588
boolean customBatchUpserted = userService.saveOrUpdateBatch(existingUsers, 500);
589
}
590
```
591
592
### Remove Operations
593
594
Comprehensive remove operations with query conditions and safety features.
595
596
```java { .api }
597
/**
598
* Remove entities by query wrapper conditions
599
* @param query query wrapper with conditions
600
* @return true if successful
601
*/
602
boolean remove(QueryWrapper query);
603
604
/**
605
* Remove entities by query condition
606
* @param condition single query condition
607
* @return true if successful
608
*/
609
boolean remove(QueryCondition condition);
610
611
/**
612
* Remove entity by entity object (using primary key)
613
* @param entity entity object with primary key
614
* @return true if successful
615
*/
616
boolean removeById(T entity);
617
618
/**
619
* Remove entity by primary key
620
* @param id primary key value
621
* @return true if successful
622
*/
623
boolean removeById(Serializable id);
624
625
/**
626
* Remove entities by primary key collection
627
* @param ids collection of primary key values
628
* @return true if successful
629
*/
630
boolean removeByIds(Collection<? extends Serializable> ids);
631
632
/**
633
* Remove entities by Map conditions (prevents empty map)
634
* @param query Map of column-value conditions
635
* @return true if successful
636
* @throws FlexException if map is null or empty
637
*/
638
boolean removeByMap(Map<String, Object> query);
639
```
640
641
**Remove Examples:**
642
643
```java
644
public void demonstrateRemoveOperations() {
645
// Remove by primary key
646
boolean removed = userService.removeById(1L);
647
648
// Remove by entity object
649
User user = userService.getById(2L);
650
boolean removedByEntity = userService.removeById(user);
651
652
// Remove by multiple IDs
653
List<Long> ids = Arrays.asList(3L, 4L, 5L);
654
boolean batchRemoved = userService.removeByIds(ids);
655
656
// Remove by query wrapper
657
boolean removedByQuery = userService.remove(
658
QueryWrapper.create()
659
.from(User.class)
660
.where(USER.ACTIVE.eq(false))
661
.and(USER.LAST_LOGIN_TIME.lt(oneYearAgo))
662
);
663
664
// Remove by query condition
665
boolean removedByCondition = userService.remove(
666
USER.AGE.lt(18).and(USER.ACTIVE.eq(false))
667
);
668
669
// Remove by Map conditions (safer than manual SQL)
670
Map<String, Object> conditions = new HashMap<>();
671
conditions.put("status", "INACTIVE");
672
conditions.put("deleted", true);
673
boolean removedByMap = userService.removeByMap(conditions);
674
675
// Note: Empty map will throw FlexException to prevent accidental full table deletion
676
// userService.removeByMap(new HashMap<>()); // This would throw an exception
677
}
678
```
679
680
### Update Operations
681
682
Advanced update operations with batch processing and null handling options.
683
684
```java { .api }
685
/**
686
* Update entity by primary key (ignores null properties by default)
687
* @param entity entity to update
688
* @return true if successful
689
*/
690
boolean updateById(T entity);
691
692
/**
693
* Update entity by primary key with null handling option
694
* @param entity entity to update
695
* @param ignoreNulls whether to ignore null properties
696
* @return true if successful
697
*/
698
boolean updateById(T entity, boolean ignoreNulls);
699
700
/**
701
* Update entity by Map conditions
702
* @param entity entity with new values
703
* @param query Map of where conditions
704
* @return true if successful
705
*/
706
boolean update(T entity, Map<String, Object> query);
707
708
/**
709
* Update entity by query wrapper conditions
710
* @param entity entity with new values
711
* @param query query wrapper conditions
712
* @return true if successful
713
*/
714
boolean update(T entity, QueryWrapper query);
715
716
/**
717
* Update entity by query condition
718
* @param entity entity with new values
719
* @param condition query condition
720
* @return true if successful
721
*/
722
boolean update(T entity, QueryCondition condition);
723
724
/**
725
* Batch update entities by primary key (default batch size: 1000)
726
* @param entities collection of entities to update
727
* @return true if all successful
728
*/
729
boolean updateBatch(Collection<T> entities);
730
731
/**
732
* Batch update entities with null handling option
733
* @param entities collection of entities to update
734
* @param ignoreNulls whether to ignore null properties
735
* @return true if all successful
736
*/
737
boolean updateBatch(Collection<T> entities, boolean ignoreNulls);
738
739
/**
740
* Batch update entities with custom batch size
741
* @param entities collection of entities to update
742
* @param batchSize number of entities per batch
743
* @return true if all successful
744
*/
745
boolean updateBatch(Collection<T> entities, int batchSize);
746
747
/**
748
* Batch update entities with custom batch size and null handling
749
* @param entities collection of entities to update
750
* @param batchSize number of entities per batch
751
* @param ignoreNulls whether to ignore null properties
752
* @return true if all successful
753
*/
754
boolean updateBatch(Collection<T> entities, int batchSize, boolean ignoreNulls);
755
```
756
757
**Update Examples:**
758
759
```java
760
public void demonstrateUpdateOperations() {
761
// Basic update by ID (ignores null properties)
762
User user = userService.getById(1L);
763
user.setAge(26);
764
user.setEmail(null); // This field will be ignored
765
boolean updated = userService.updateById(user);
766
767
// Update by ID with null handling control
768
User user2 = userService.getById(2L);
769
user2.setAge(27);
770
user2.setEmail(null); // This field will be set to NULL in database
771
boolean updatedWithNulls = userService.updateById(user2, false);
772
773
// Update by query conditions
774
User updateData = new User();
775
updateData.setActive(false);
776
updateData.setUpdateTime(new Date());
777
778
boolean updatedByQuery = userService.update(updateData,
779
QueryWrapper.create()
780
.from(User.class)
781
.where(USER.LAST_LOGIN_TIME.lt(sixMonthsAgo))
782
);
783
784
// Update by Map conditions
785
Map<String, Object> whereConditions = new HashMap<>();
786
whereConditions.put("department", "IT");
787
whereConditions.put("active", true);
788
789
User salaryUpdate = new User();
790
salaryUpdate.setSalary(salaryUpdate.getSalary() * 1.1); // 10% raise
791
boolean updatedByMap = userService.update(salaryUpdate, whereConditions);
792
793
// Update by single condition
794
User statusUpdate = new User();
795
statusUpdate.setStatus("VERIFIED");
796
boolean updatedByCondition = userService.update(statusUpdate,
797
USER.EMAIL_VERIFIED.eq(true).and(USER.STATUS.eq("PENDING"))
798
);
799
800
// Batch updates
801
List<User> usersToUpdate = userService.listByIds(Arrays.asList(1L, 2L, 3L));
802
usersToUpdate.forEach(u -> u.setLastUpdated(new Date()));
803
804
// Default batch update (ignores nulls, batch size 1000)
805
boolean batchUpdated = userService.updateBatch(usersToUpdate);
806
807
// Batch update with null handling
808
boolean batchUpdatedWithNulls = userService.updateBatch(usersToUpdate, false);
809
810
// Batch update with custom batch size
811
boolean customBatchUpdated = userService.updateBatch(usersToUpdate, 500);
812
813
// Batch update with both custom batch size and null handling
814
boolean fullCustomBatch = userService.updateBatch(usersToUpdate, 500, false);
815
}
816
```
817
818
### Query Operations
819
820
Enhanced query operations with Optional support, type transformations, and advanced querying methods.
821
822
```java { .api }
823
/**
824
* Get entity by primary key
825
* @param id primary key value
826
* @return entity or null if not found
827
*/
828
T getById(Serializable id);
829
830
/**
831
* Get entity by entity primary key
832
* @param entity entity object with primary key
833
* @return entity or null if not found
834
*/
835
T getOneByEntityId(T entity);
836
837
/**
838
* Get entity by entity primary key with Optional wrapper
839
* @param entity entity object with primary key
840
* @return Optional containing entity or empty
841
*/
842
Optional<T> getByEntityIdOpt(T entity);
843
844
/**
845
* Get entity by primary key with Optional wrapper
846
* @param id primary key value
847
* @return Optional containing entity or empty
848
*/
849
Optional<T> getByIdOpt(Serializable id);
850
851
/**
852
* Get single entity by query wrapper conditions
853
* @param query query conditions
854
* @return single entity or null
855
*/
856
T getOne(QueryWrapper query);
857
858
/**
859
* Get single entity by query wrapper with Optional wrapper
860
* @param query query conditions
861
* @return Optional containing entity or empty
862
*/
863
Optional<T> getOneOpt(QueryWrapper query);
864
865
/**
866
* Get single entity by query wrapper and transform to target type
867
* @param query query conditions
868
* @param asType target type class
869
* @return transformed object or null
870
*/
871
<R> R getOneAs(QueryWrapper query, Class<R> asType);
872
873
/**
874
* Get single entity by query wrapper, transform with Optional wrapper
875
* @param query query conditions
876
* @param asType target type class
877
* @return Optional containing transformed object or empty
878
*/
879
<R> Optional<R> getOneAsOpt(QueryWrapper query, Class<R> asType);
880
881
/**
882
* Get single entity by query condition
883
* @param condition query condition
884
* @return single entity or null
885
*/
886
T getOne(QueryCondition condition);
887
888
/**
889
* Get single entity by query condition with Optional wrapper
890
* @param condition query condition
891
* @return Optional containing entity or empty
892
*/
893
Optional<T> getOneOpt(QueryCondition condition);
894
895
/**
896
* Get first column value of first row from query result
897
* @param query query conditions
898
* @return object value or null
899
*/
900
Object getObj(QueryWrapper query);
901
902
/**
903
* Get first column value with Optional wrapper
904
* @param query query conditions
905
* @return Optional containing object value or empty
906
*/
907
Optional<Object> getObjOpt(QueryWrapper query);
908
909
/**
910
* Get first column value and cast to target type
911
* @param query query conditions
912
* @param asType target type class (e.g., Long.class, String.class)
913
* @return typed value or null
914
*/
915
<R> R getObjAs(QueryWrapper query, Class<R> asType);
916
917
/**
918
* Get first column value, cast to target type with Optional wrapper
919
* @param query query conditions
920
* @param asType target type class
921
* @return Optional containing typed value or empty
922
*/
923
<R> Optional<R> getObjAsOpt(QueryWrapper query, Class<R> asType);
924
925
/**
926
* Get all values from first column of query result
927
* @param query query conditions
928
* @return list of object values
929
*/
930
List<Object> objList(QueryWrapper query);
931
932
/**
933
* Get all values from first column and cast to target type
934
* @param query query conditions
935
* @param asType target type class
936
* @return list of typed values
937
*/
938
<R> List<R> objListAs(QueryWrapper query, Class<R> asType);
939
940
/**
941
* Get all entities
942
* @return list of all entities
943
*/
944
List<T> list();
945
946
/**
947
* Get entities by query wrapper conditions
948
* @param query query conditions
949
* @return list of entities
950
*/
951
List<T> list(QueryWrapper query);
952
953
/**
954
* Get entities by query condition
955
* @param condition query condition
956
* @return list of entities
957
*/
958
List<T> list(QueryCondition condition);
959
960
/**
961
* Transform query results to different type
962
* @param query query conditions
963
* @param asType target type class
964
* @return list of transformed objects
965
*/
966
<R> List<R> listAs(QueryWrapper query, Class<R> asType);
967
968
/**
969
* Get entities by primary keys
970
* @param ids collection of primary key values
971
* @return list of entities
972
*/
973
List<T> listByIds(Collection<? extends Serializable> ids);
974
975
/**
976
* Get entities by Map conditions
977
* @param query Map of column-value conditions
978
* @return list of entities
979
*/
980
List<T> listByMap(Map<String, Object> query);
981
```
982
983
**Query Examples:**
984
985
```java
986
public void demonstrateQueryOperations() {
987
// Basic queries
988
User user = userService.getById(1L);
989
Optional<User> userOpt = userService.getByIdOpt(1L);
990
991
// Query by entity object
992
User entityWithId = new User();
993
entityWithId.setId(1L);
994
User foundUser = userService.getOneByEntityId(entityWithId);
995
Optional<User> foundUserOpt = userService.getByEntityIdOpt(entityWithId);
996
997
// Single query with conditions
998
User youngUser = userService.getOne(
999
QueryWrapper.create()
1000
.from(User.class)
1001
.where(USER.AGE.lt(25))
1002
.orderBy(USER.AGE.asc())
1003
);
1004
1005
// Optional query
1006
Optional<User> youngUserOpt = userService.getOneOpt(
1007
QueryWrapper.create()
1008
.from(User.class)
1009
.where(USER.AGE.lt(25))
1010
);
1011
1012
// Query with single condition
1013
User activeUser = userService.getOne(USER.ACTIVE.eq(true));
1014
Optional<User> activeUserOpt = userService.getOneOpt(USER.ACTIVE.eq(true));
1015
1016
// Type transformation queries
1017
UserDTO userDTO = userService.getOneAs(
1018
QueryWrapper.create()
1019
.select(USER.ID, USER.NAME, USER.EMAIL)
1020
.from(User.class)
1021
.where(USER.ID.eq(1L)),
1022
UserDTO.class
1023
);
1024
1025
Optional<UserDTO> userDTOOpt = userService.getOneAsOpt(
1026
QueryWrapper.create()
1027
.select(USER.ID, USER.NAME, USER.EMAIL)
1028
.from(User.class)
1029
.where(USER.ID.eq(1L)),
1030
UserDTO.class
1031
);
1032
1033
// Object value queries (for single column results)
1034
Object maxAge = userService.getObj(
1035
QueryWrapper.create()
1036
.select(QueryMethods.max(USER.AGE))
1037
.from(User.class)
1038
);
1039
1040
Optional<Object> maxAgeOpt = userService.getObjOpt(
1041
QueryWrapper.create()
1042
.select(QueryMethods.max(USER.AGE))
1043
.from(User.class)
1044
);
1045
1046
// Typed object queries
1047
Long userCount = userService.getObjAs(
1048
QueryWrapper.create()
1049
.select(QueryMethods.count())
1050
.from(User.class),
1051
Long.class
1052
);
1053
1054
Optional<Long> userCountOpt = userService.getObjAsOpt(
1055
QueryWrapper.create()
1056
.select(QueryMethods.count())
1057
.from(User.class),
1058
Long.class
1059
);
1060
1061
// Object list queries (for single column multiple rows)
1062
List<Object> allEmails = userService.objList(
1063
QueryWrapper.create()
1064
.select(USER.EMAIL)
1065
.from(User.class)
1066
.where(USER.ACTIVE.eq(true))
1067
);
1068
1069
List<String> allEmailsTyped = userService.objListAs(
1070
QueryWrapper.create()
1071
.select(USER.EMAIL)
1072
.from(User.class)
1073
.where(USER.ACTIVE.eq(true)),
1074
String.class
1075
);
1076
1077
// List queries
1078
List<Long> ids = Arrays.asList(1L, 2L, 3L);
1079
List<User> users = userService.listByIds(ids);
1080
1081
List<User> allUsers = userService.list();
1082
1083
List<User> activeUsers = userService.list(
1084
QueryWrapper.create()
1085
.from(User.class)
1086
.where(USER.ACTIVE.eq(true))
1087
);
1088
1089
// List by single condition
1090
List<User> youngUsers = userService.list(USER.AGE.lt(25));
1091
1092
// List by Map conditions
1093
Map<String, Object> conditions = new HashMap<>();
1094
conditions.put("active", true);
1095
conditions.put("department", "IT");
1096
List<User> itUsers = userService.listByMap(conditions);
1097
1098
// Type transformation
1099
List<UserDTO> userDTOs = userService.listAs(
1100
QueryWrapper.create()
1101
.select(USER.ID, USER.NAME, USER.EMAIL)
1102
.from(User.class)
1103
.where(USER.ACTIVE.eq(true)),
1104
UserDTO.class
1105
);
1106
}
1107
```
1108
1109
### Count and Existence Operations
1110
1111
Efficient counting and existence checking with various query methods.
1112
1113
```java { .api }
1114
/**
1115
* Check if entities exist by query wrapper conditions
1116
* @param query query conditions
1117
* @return true if exists, false otherwise
1118
*/
1119
boolean exists(QueryWrapper query);
1120
1121
/**
1122
* Check if entities exist by query condition
1123
* @param condition query condition
1124
* @return true if exists, false otherwise
1125
*/
1126
boolean exists(QueryCondition condition);
1127
1128
/**
1129
* Count all entities
1130
* @return total count
1131
*/
1132
long count();
1133
1134
/**
1135
* Count entities by query wrapper conditions
1136
* @param query query conditions
1137
* @return count matching conditions
1138
*/
1139
long count(QueryWrapper query);
1140
1141
/**
1142
* Count entities by query condition
1143
* @param condition query condition
1144
* @return count matching condition
1145
*/
1146
long count(QueryCondition condition);
1147
```
1148
1149
**Count and Existence Examples:**
1150
1151
```java
1152
public void demonstrateCountAndExistence() {
1153
// Basic count
1154
long totalUsers = userService.count();
1155
1156
// Count with query wrapper conditions
1157
long activeUserCount = userService.count(
1158
QueryWrapper.create()
1159
.from(User.class)
1160
.where(USER.ACTIVE.eq(true))
1161
);
1162
1163
// Count with single condition
1164
long youngUserCount = userService.count(USER.AGE.lt(25));
1165
1166
// Existence checks
1167
boolean hasActiveUsers = userService.exists(
1168
QueryWrapper.create()
1169
.from(User.class)
1170
.where(USER.ACTIVE.eq(true))
1171
);
1172
1173
boolean hasAdminUsers = userService.exists(USER.ROLE.eq("ADMIN"));
1174
1175
// Complex existence check
1176
boolean hasRecentUsers = userService.exists(
1177
QueryWrapper.create()
1178
.from(User.class)
1179
.where(USER.CREATE_TIME.ge(lastMonth))
1180
.and(USER.ACTIVE.eq(true))
1181
);
1182
1183
// Use existence for conditional logic
1184
if (userService.exists(USER.EMAIL.eq("admin@example.com"))) {
1185
// Admin user already exists, skip creation
1186
System.out.println("Admin user already exists");
1187
} else {
1188
// Create admin user
1189
User admin = new User("admin@example.com", "ADMIN");
1190
userService.save(admin);
1191
}
1192
}
1193
```
1194
1195
### Pagination Operations
1196
1197
Enhanced pagination with type transformation support and multiple query methods.
1198
1199
```java { .api }
1200
/**
1201
* Paginate all entities
1202
* @param page pagination parameters
1203
* @return page of entities
1204
*/
1205
Page<T> page(Page<T> page);
1206
1207
/**
1208
* Paginate entities by query wrapper conditions
1209
* @param page pagination parameters
1210
* @param query query conditions
1211
* @return page of entities
1212
*/
1213
Page<T> page(Page<T> page, QueryWrapper query);
1214
1215
/**
1216
* Paginate entities by query condition
1217
* @param page pagination parameters
1218
* @param condition query condition
1219
* @return page of entities
1220
*/
1221
Page<T> page(Page<T> page, QueryCondition condition);
1222
1223
/**
1224
* Paginate with type transformation
1225
* @param page pagination parameters
1226
* @param query query conditions
1227
* @param asType target type class
1228
* @return page of transformed objects
1229
*/
1230
<R> Page<R> pageAs(Page<R> page, QueryWrapper query, Class<R> asType);
1231
```
1232
1233
**Pagination Examples:**
1234
1235
```java
1236
public void demonstratePagination() {
1237
// Basic pagination
1238
Page<User> page1 = new Page<>(1, 10);
1239
Page<User> result1 = userService.page(page1);
1240
1241
// Pagination with query wrapper conditions
1242
Page<User> page2 = new Page<>(1, 10);
1243
Page<User> result2 = userService.page(page2,
1244
QueryWrapper.create()
1245
.from(User.class)
1246
.where(USER.ACTIVE.eq(true))
1247
.orderBy(USER.CREATE_TIME.desc())
1248
);
1249
1250
// Pagination with single condition
1251
Page<User> page3 = new Page<>(1, 10);
1252
Page<User> result3 = userService.page(page3, USER.ACTIVE.eq(true));
1253
1254
// Pagination with type transformation
1255
Page<UserSummaryDTO> dtoPage = new Page<>(1, 20);
1256
Page<UserSummaryDTO> dtoResult = userService.pageAs(dtoPage,
1257
QueryWrapper.create()
1258
.select(USER.ID, USER.NAME, USER.EMAIL, USER.CREATE_TIME)
1259
.from(User.class)
1260
.where(USER.ACTIVE.eq(true)),
1261
UserSummaryDTO.class
1262
);
1263
1264
System.out.println("Total records: " + dtoResult.getTotalRow());
1265
System.out.println("Total pages: " + dtoResult.getTotalPage());
1266
}
1267
```
1268
1269
### Query Wrapper and Chain Operations
1270
1271
Fluent interfaces for complex query and update operations with query wrapper creation.
1272
1273
```java { .api }
1274
/**
1275
* Create default QueryWrapper
1276
* @return QueryWrapper instance
1277
*/
1278
QueryWrapper query();
1279
1280
/**
1281
* Create query chain for fluent operations
1282
* @return QueryChain instance
1283
*/
1284
QueryChain<T> queryChain();
1285
1286
/**
1287
* Create update chain for fluent operations
1288
* @return UpdateChain instance
1289
*/
1290
UpdateChain<T> updateChain();
1291
1292
/**
1293
* Fluent query interface
1294
* @param <T> Entity type
1295
*/
1296
public interface QueryChain<T> {
1297
QueryChain<T> select(QueryColumn... columns);
1298
QueryChain<T> from(Class<?> entityClass);
1299
QueryChain<T> where(QueryCondition condition);
1300
QueryChain<T> orderBy(QueryColumn... columns);
1301
QueryChain<T> groupBy(QueryColumn... columns);
1302
QueryChain<T> limit(long limit);
1303
1304
T one();
1305
List<T> list();
1306
Page<T> page(Page<T> page);
1307
long count();
1308
}
1309
1310
/**
1311
* Fluent update interface
1312
* @param <T> Entity type
1313
*/
1314
public interface UpdateChain<T> {
1315
UpdateChain<T> set(String column, Object value);
1316
UpdateChain<T> set(QueryColumn column, Object value);
1317
UpdateChain<T> where(QueryCondition condition);
1318
1319
boolean update();
1320
long count();
1321
}
1322
```
1323
1324
**Query Wrapper and Chaining Examples:**
1325
1326
```java
1327
public void demonstrateQueryWrapperAndChaining() {
1328
// Basic QueryWrapper creation
1329
QueryWrapper basicQuery = userService.query()
1330
.from(User.class)
1331
.where(USER.ACTIVE.eq(true));
1332
1333
List<User> basicResults = userService.list(basicQuery);
1334
1335
// Advanced QueryWrapper with multiple conditions
1336
QueryWrapper complexQuery = userService.query()
1337
.select(USER.ID, USER.NAME, USER.EMAIL, USER.CREATE_TIME)
1338
.from(User.class)
1339
.where(USER.AGE.between(25, 45))
1340
.and(USER.ACTIVE.eq(true))
1341
.and(USER.DEPARTMENT.in("IT", "Engineering", "Product"))
1342
.orderBy(USER.CREATE_TIME.desc(), USER.NAME.asc())
1343
.limit(50);
1344
1345
List<User> complexResults = userService.list(complexQuery);
1346
1347
// Query chaining for fluent operations
1348
List<User> chainedUsers = userService.queryChain()
1349
.select(USER.ID, USER.NAME, USER.EMAIL)
1350
.where(USER.AGE.between(25, 35))
1351
.and(USER.ACTIVE.eq(true))
1352
.orderBy(USER.NAME.asc())
1353
.limit(10)
1354
.list();
1355
1356
// Count with chaining
1357
long count = userService.queryChain()
1358
.where(USER.CITY.eq("New York"))
1359
.and(USER.ACTIVE.eq(true))
1360
.count();
1361
1362
// Single result with chaining
1363
User singleUser = userService.queryChain()
1364
.where(USER.EMAIL.eq("john@example.com"))
1365
.and(USER.ACTIVE.eq(true))
1366
.one();
1367
1368
// Pagination with chaining
1369
Page<User> pageResult = userService.queryChain()
1370
.where(USER.DEPARTMENT.eq("IT"))
1371
.orderBy(USER.CREATE_TIME.desc())
1372
.page(new Page<>(1, 20));
1373
1374
// Update chaining for fluent updates
1375
boolean updated = userService.updateChain()
1376
.set(USER.ACTIVE, false)
1377
.set(USER.UPDATE_TIME, new Date())
1378
.set(USER.DEACTIVATION_REASON, "Inactive for 6 months")
1379
.where(USER.LAST_LOGIN_TIME.lt(sixMonthsAgo))
1380
.and(USER.ACTIVE.eq(true))
1381
.update();
1382
1383
// Batch update with chaining
1384
long updateCount = userService.updateChain()
1385
.set(USER.STATUS, "VERIFIED")
1386
.set(USER.VERIFICATION_DATE, new Date())
1387
.where(USER.EMAIL_VERIFIED.eq(true))
1388
.and(USER.PHONE_VERIFIED.eq(true))
1389
.and(USER.STATUS.eq("PENDING"))
1390
.count(); // Returns number of affected rows
1391
}
1392
```
1393
1394
## Types
1395
1396
```java { .api }
1397
// Service layer types
1398
public interface IService<T> {
1399
int DEFAULT_BATCH_SIZE = 1000;
1400
BaseMapper<T> getMapper();
1401
// All CRUD and query methods...
1402
}
1403
1404
// Query wrapper types
1405
public interface QueryWrapper {
1406
QueryWrapper select(QueryColumn... columns);
1407
QueryWrapper from(Class<?> entityClass);
1408
QueryWrapper where(QueryCondition condition);
1409
QueryWrapper and(QueryCondition condition);
1410
QueryWrapper orderBy(QueryColumn... columns);
1411
QueryWrapper limit(long limit);
1412
static QueryWrapper create();
1413
}
1414
1415
public interface QueryCondition {
1416
QueryCondition and(QueryCondition condition);
1417
QueryCondition or(QueryCondition condition);
1418
}
1419
1420
// Chain interfaces
1421
public interface QueryChain<T> {
1422
QueryChain<T> select(QueryColumn... columns);
1423
QueryChain<T> where(QueryCondition condition);
1424
QueryChain<T> and(QueryCondition condition);
1425
QueryChain<T> orderBy(QueryColumn... columns);
1426
QueryChain<T> limit(long limit);
1427
T one();
1428
List<T> list();
1429
Page<T> page(Page<T> page);
1430
long count();
1431
}
1432
1433
public interface UpdateChain<T> {
1434
UpdateChain<T> set(String column, Object value);
1435
UpdateChain<T> set(QueryColumn column, Object value);
1436
UpdateChain<T> where(QueryCondition condition);
1437
UpdateChain<T> and(QueryCondition condition);
1438
boolean update();
1439
long count();
1440
}
1441
1442
// Page and mapper types
1443
public interface BaseMapper<T> {
1444
int insert(T entity, boolean ignoreNulls);
1445
int insertOrUpdate(T entity, boolean ignoreNulls);
1446
int delete(T entity);
1447
int deleteById(Serializable id);
1448
int update(T entity, boolean ignoreNulls);
1449
T selectOneById(Serializable id);
1450
List<T> selectListByQuery(QueryWrapper query);
1451
// ... other mapper methods
1452
}
1453
1454
public class Page<T> {
1455
private long pageNumber; // Current page number
1456
private long pageSize; // Page size
1457
private long totalRow; // Total records
1458
private long totalPage; // Total pages
1459
private List<T> records; // Page data
1460
1461
public Page(long pageNumber, long pageSize);
1462
public long getTotalRow();
1463
public long getTotalPage();
1464
public List<T> getRecords();
1465
}
1466
1467
// Standard Java types
1468
public interface Optional<T> {
1469
boolean isPresent();
1470
T get();
1471
T orElse(T other);
1472
T orElseGet(Supplier<? extends T> other);
1473
<U> Optional<U> map(Function<? super T, ? extends U> mapper);
1474
void ifPresent(Consumer<? super T> consumer);
1475
}
1476
1477
public interface Collection<E> extends Iterable<E> {
1478
int size();
1479
boolean isEmpty();
1480
boolean contains(Object o);
1481
boolean add(E e);
1482
boolean remove(Object o);
1483
}
1484
1485
public interface Map<K,V> {
1486
V get(Object key);
1487
V put(K key, V value);
1488
boolean isEmpty();
1489
int size();
1490
}
1491
1492
public interface Serializable {
1493
// Marker interface for primary key types (Long, String, Integer, etc.)
1494
}
1495
```