or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

active-record.mdbootstrap-config.mdcrud-operations.mddatabase-support.mdindex.mdpagination.mdquery-builder.mdrow-operations.mdservice-layer.mdupdate-chain.md

service-layer.mddocs/

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

```