or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

active-record.mdcondition-builders.mdindex.mdkotlin-extensions.mdpagination.mdplugin-system.mdservice-layer.mdstatic-utilities.md

static-utilities.mddocs/

0

# Static Database Utilities

1

2

MyBatis-Plus Extension provides the `Db` utility class that offers static methods for direct database operations without requiring service layer dependency injection. This is particularly useful in utility classes, static contexts, or when you need database operations outside of the traditional service layer.

3

4

## Core Components

5

6

### Db Utility Class

7

8

The main static utility class providing all common database operations.

9

10

```java { .api }

11

public class Db {

12

13

// Save operations

14

public static <T> boolean save(T entity);

15

public static <T> boolean saveBatch(Collection<T> entityList);

16

public static <T> boolean saveBatch(Collection<T> entityList, int batchSize);

17

public static <T> boolean saveOrUpdate(T entity);

18

public static <T> boolean saveOrUpdateBatch(Collection<T> entityList);

19

public static <T> boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);

20

21

// Remove operations

22

public static <T> boolean removeById(Object entity);

23

public static <T> boolean removeById(Class<T> entityClass, Serializable id);

24

public static <T> boolean removeByIds(Class<T> entityClass, Collection<? extends Serializable> list);

25

public static <T> boolean removeByMap(Class<T> entityClass, Map<String, Object> map);

26

public static <T> boolean remove(Class<T> entityClass, Wrapper<T> queryWrapper);

27

28

// Update operations

29

public static <T> boolean updateById(T entity);

30

public static <T> boolean update(Class<T> entityClass, Wrapper<T> updateWrapper);

31

public static <T> boolean update(Class<T> entityClass, T entity, Wrapper<T> updateWrapper);

32

public static <T> boolean updateBatchById(Collection<T> entityList);

33

public static <T> boolean updateBatchById(Collection<T> entityList, int batchSize);

34

35

// Query operations

36

public static <T> T getById(Class<T> entityClass, Serializable id);

37

public static <T> T getOne(Class<T> entityClass, Wrapper<T> queryWrapper);

38

public static <T> T getOne(Class<T> entityClass, Wrapper<T> queryWrapper, boolean throwEx);

39

public static <T> Optional<T> getOptById(Class<T> entityClass, Serializable id);

40

public static <T> Optional<T> getOneOpt(Class<T> entityClass, Wrapper<T> queryWrapper);

41

public static <T> Optional<T> getOneOpt(Class<T> entityClass, Wrapper<T> queryWrapper, boolean throwEx);

42

public static <T> Map<String, Object> getMap(Class<T> entityClass, Wrapper<T> queryWrapper);

43

public static <T, V> V getObj(Class<T> entityClass, Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

44

45

// List operations

46

public static <T> List<T> list(Class<T> entityClass);

47

public static <T> List<T> list(Class<T> entityClass, Wrapper<T> queryWrapper);

48

public static <T> List<T> listByIds(Class<T> entityClass, Collection<? extends Serializable> idList);

49

public static <T> List<T> listByMap(Class<T> entityClass, Map<String, Object> columnMap);

50

public static <T> List<Map<String, Object>> listMaps(Class<T> entityClass);

51

public static <T> List<Map<String, Object>> listMaps(Class<T> entityClass, Wrapper<T> queryWrapper);

52

public static <T, V> List<V> listObjs(Class<T> entityClass);

53

public static <T, V> List<V> listObjs(Class<T> entityClass, Function<? super Object, V> mapper);

54

public static <T, V> List<V> listObjs(Class<T> entityClass, Wrapper<T> queryWrapper);

55

public static <T, V> List<V> listObjs(Class<T> entityClass, Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

56

57

// Count operations

58

public static <T> long count(Class<T> entityClass);

59

public static <T> long count(Class<T> entityClass, Wrapper<T> queryWrapper);

60

public static <T> boolean exists(Class<T> entityClass, Wrapper<T> queryWrapper);

61

62

// Pagination operations

63

public static <T> Page<T> page(Class<T> entityClass, IPage<T> page);

64

public static <T> Page<T> page(Class<T> entityClass, IPage<T> page, Wrapper<T> queryWrapper);

65

public static <T> Page<Map<String, Object>> pageMaps(Class<T> entityClass, IPage<T> page, Wrapper<T> queryWrapper);

66

67

// Chain operations

68

public static <T> QueryChainWrapper<T> query(Class<T> entityClass);

69

public static <T> LambdaQueryChainWrapper<T> lambdaQuery(Class<T> entityClass);

70

public static <T> KtQueryChainWrapper<T> ktQuery(Class<T> entityClass);

71

public static <T> UpdateChainWrapper<T> update(Class<T> entityClass);

72

public static <T> LambdaUpdateChainWrapper<T> lambdaUpdate(Class<T> entityClass);

73

public static <T> KtUpdateChainWrapper<T> ktUpdate(Class<T> entityClass);

74

}

75

```

76

77

### ChainWrappers Factory

78

79

Factory class for creating chain wrappers directly with mappers or entity classes.

80

81

```java { .api }

82

public class ChainWrappers {

83

84

// Query chain factory methods

85

public static <T> QueryChainWrapper<T> queryChain(BaseMapper<T> baseMapper);

86

public static <T> QueryChainWrapper<T> queryChain(Class<T> entityClass);

87

public static <T> LambdaQueryChainWrapper<T> lambdaQueryChain(BaseMapper<T> baseMapper);

88

public static <T> LambdaQueryChainWrapper<T> lambdaQueryChain(Class<T> entityClass);

89

public static <T> KtQueryChainWrapper<T> ktQueryChain(BaseMapper<T> baseMapper);

90

public static <T> KtQueryChainWrapper<T> ktQueryChain(Class<T> entityClass);

91

92

// Update chain factory methods

93

public static <T> UpdateChainWrapper<T> updateChain(BaseMapper<T> baseMapper);

94

public static <T> UpdateChainWrapper<T> updateChain(Class<T> entityClass);

95

public static <T> LambdaUpdateChainWrapper<T> lambdaUpdateChain(BaseMapper<T> baseMapper);

96

public static <T> LambdaUpdateChainWrapper<T> lambdaUpdateChain(Class<T> entityClass);

97

public static <T> KtUpdateChainWrapper<T> ktUpdateChain(BaseMapper<T> baseMapper);

98

public static <T> KtUpdateChainWrapper<T> ktUpdateChain(Class<T> entityClass);

99

}

100

```

101

102

## Usage Examples

103

104

### Basic Save Operations

105

106

```java

107

// Save single entity

108

User user = new User("John Doe", "john@example.com");

109

boolean saved = Db.save(user);

110

111

if (saved) {

112

System.out.println("User saved with ID: " + user.getId());

113

}

114

115

// Save batch

116

List<User> users = Arrays.asList(

117

new User("Alice", "alice@example.com"),

118

new User("Bob", "bob@example.com"),

119

new User("Charlie", "charlie@example.com")

120

);

121

boolean allSaved = Db.saveBatch(users);

122

123

// Save batch with custom batch size

124

boolean saved = Db.saveBatch(users, 50);

125

126

// Save or update

127

User existingUser = Db.getById(User.class, 1L);

128

if (existingUser != null) {

129

existingUser.setEmail("newemail@example.com");

130

boolean updated = Db.saveOrUpdate(existingUser);

131

}

132

```

133

134

### Query Operations

135

136

```java

137

// Get by ID

138

User user = Db.getById(User.class, 1L);

139

if (user != null) {

140

System.out.println("Found user: " + user.getName());

141

}

142

143

// Get with Optional

144

Optional<User> optionalUser = Db.getOptById(User.class, 1L);

145

optionalUser.ifPresent(u -> System.out.println("User: " + u.getName()));

146

147

// Get single with conditions

148

User activeUser = Db.getOne(User.class,

149

new QueryWrapper<User>().eq("active", true).eq("email", "john@example.com"));

150

151

// Get single with Optional

152

Optional<User> optUser = Db.getOneOpt(User.class,

153

new QueryWrapper<User>().eq("email", "unique@example.com"));

154

155

// List all

156

List<User> allUsers = Db.list(User.class);

157

158

// List with conditions

159

List<User> activeUsers = Db.list(User.class,

160

new QueryWrapper<User>().eq("active", true));

161

162

// List by IDs

163

List<User> specificUsers = Db.listByIds(User.class, Arrays.asList(1L, 2L, 3L));

164

165

// List by column map

166

Map<String, Object> conditions = new HashMap<>();

167

conditions.put("active", true);

168

conditions.put("age", 30);

169

List<User> users = Db.listByMap(User.class, conditions);

170

```

171

172

### Count and Existence

173

174

```java

175

// Count all

176

long totalUsers = Db.count(User.class);

177

System.out.println("Total users: " + totalUsers);

178

179

// Count with conditions

180

long activeUsers = Db.count(User.class,

181

new QueryWrapper<User>().eq("active", true));

182

183

long adultUsers = Db.count(User.class,

184

new QueryWrapper<User>().ge("age", 18));

185

186

// Check existence

187

boolean hasActiveUsers = Db.exists(User.class,

188

new QueryWrapper<User>().eq("active", true));

189

190

if (hasActiveUsers) {

191

System.out.println("Active users exist");

192

}

193

```

194

195

### Update Operations

196

197

```java

198

// Update by ID

199

User user = Db.getById(User.class, 1L);

200

if (user != null) {

201

user.setEmail("updated@example.com");

202

user.setUpdatedTime(LocalDateTime.now());

203

boolean updated = Db.updateById(user);

204

}

205

206

// Update with conditions (using wrapper only)

207

boolean updated = Db.update(User.class,

208

new UpdateWrapper<User>()

209

.set("active", false)

210

.set("updated_time", LocalDateTime.now())

211

.eq("last_login", null)

212

);

213

214

// Update with entity and conditions

215

User updateEntity = new User();

216

updateEntity.setActive(false);

217

boolean updated = Db.update(User.class, updateEntity,

218

new UpdateWrapper<User>().gt("age", 65));

219

220

// Batch update by IDs

221

List<User> usersToUpdate = Db.listByIds(User.class, Arrays.asList(1L, 2L, 3L));

222

usersToUpdate.forEach(user -> user.setActive(true));

223

boolean allUpdated = Db.updateBatchById(usersToUpdate);

224

```

225

226

### Remove Operations

227

228

```java

229

// Remove by entity (uses entity's ID)

230

User user = Db.getById(User.class, 1L);

231

boolean removed = Db.removeById(user);

232

233

// Remove by class and ID

234

boolean removed = Db.removeById(User.class, 1L);

235

236

// Remove by IDs

237

boolean removed = Db.removeByIds(User.class, Arrays.asList(1L, 2L, 3L));

238

239

// Remove by column map

240

Map<String, Object> conditions = new HashMap<>();

241

conditions.put("active", false);

242

conditions.put("last_login", null);

243

boolean removed = Db.removeByMap(User.class, conditions);

244

245

// Remove with conditions

246

boolean removed = Db.remove(User.class,

247

new QueryWrapper<User>()

248

.eq("active", false)

249

.lt("created_time", LocalDateTime.now().minusYears(1))

250

);

251

```

252

253

### Pagination with Static Methods

254

255

```java

256

// Basic pagination

257

Page<User> page = new Page<>(1, 10);

258

Page<User> result = Db.page(User.class, page);

259

260

List<User> users = result.getRecords();

261

long total = result.getTotal();

262

263

// Pagination with conditions

264

Page<User> conditionPage = Db.page(User.class, new Page<>(1, 15),

265

new QueryWrapper<User>().eq("active", true).orderByDesc("created_time"));

266

267

// Paginate map results

268

Page<Map<String, Object>> mapPage = Db.pageMaps(User.class, new Page<>(1, 10),

269

new QueryWrapper<User>().select("id", "name", "email"));

270

```

271

272

### Object Mapping and Maps

273

274

```java

275

// Get as map

276

Map<String, Object> userMap = Db.getMap(User.class,

277

new QueryWrapper<User>().eq("id", 1L));

278

279

// List as maps

280

List<Map<String, Object>> userMaps = Db.listMaps(User.class,

281

new QueryWrapper<User>().eq("active", true));

282

283

// List specific objects

284

List<String> emails = Db.listObjs(User.class,

285

new QueryWrapper<User>().select("email").eq("active", true),

286

Object::toString);

287

288

// List all emails

289

List<String> allEmails = Db.listObjs(User.class, Object::toString);

290

```

291

292

### Chain Operations with Static Methods

293

294

```java

295

// Query chains

296

List<User> activeUsers = Db.query(User.class)

297

.eq("active", true)

298

.gt("age", 18)

299

.orderByDesc("created_time")

300

.list();

301

302

User user = Db.lambdaQuery(User.class)

303

.eq(User::getActive, true)

304

.eq(User::getEmail, "john@example.com")

305

.one();

306

307

// Update chains

308

boolean updated = Db.update(User.class)

309

.set("last_login", LocalDateTime.now())

310

.eq("id", 1L)

311

.update();

312

313

boolean deactivated = Db.lambdaUpdate(User.class)

314

.set(User::getActive, false)

315

.isNull(User::getLastLogin)

316

.update();

317

318

// Remove with chains

319

boolean removed = Db.update(User.class)

320

.eq("active", false)

321

.lt("created_time", LocalDateTime.now().minusMonths(6))

322

.remove();

323

```

324

325

### ChainWrappers Factory Usage

326

327

```java

328

// Using ChainWrappers with entity class

329

List<User> users = ChainWrappers.queryChain(User.class)

330

.eq("department", "IT")

331

.isNotNull("email")

332

.orderByAsc("name")

333

.list();

334

335

boolean updated = ChainWrappers.updateChain(User.class)

336

.set("department", "Engineering")

337

.eq("department", "IT")

338

.update();

339

340

// Lambda chains with ChainWrappers

341

List<User> managers = ChainWrappers.lambdaQueryChain(User.class)

342

.eq(User::getRole, "MANAGER")

343

.isNotNull(User::getTeamId)

344

.orderByDesc(User::getCreatedTime)

345

.list();

346

347

boolean updated = ChainWrappers.lambdaUpdateChain(User.class)

348

.set(User::getStatus, "ACTIVE")

349

.eq(User::getRole, "USER")

350

.update();

351

```

352

353

## Advanced Usage Patterns

354

355

### Utility Class Implementation

356

357

```java

358

public class UserUtils {

359

360

// Static utility methods using Db class

361

public static List<User> findActiveUsersByDepartment(String department) {

362

return Db.list(User.class,

363

new QueryWrapper<User>()

364

.eq("active", true)

365

.eq("department", department)

366

.orderByAsc("name")

367

);

368

}

369

370

public static boolean deactivateInactiveUsers(int inactiveDays) {

371

LocalDateTime cutoffDate = LocalDateTime.now().minusDays(inactiveDays);

372

return Db.update(User.class,

373

new UpdateWrapper<User>()

374

.set("active", false)

375

.set("deactivated_time", LocalDateTime.now())

376

.lt("last_login", cutoffDate)

377

.eq("active", true)

378

);

379

}

380

381

public static long countUsersByRole(String role) {

382

return Db.count(User.class,

383

new QueryWrapper<User>().eq("role", role).eq("active", true)

384

);

385

}

386

387

public static Page<User> searchUsers(String keyword, int page, int size) {

388

return Db.page(User.class, new Page<>(page, size),

389

new QueryWrapper<User>()

390

.and(wrapper -> wrapper

391

.like("name", keyword)

392

.or()

393

.like("email", keyword)

394

)

395

.eq("active", true)

396

.orderByDesc("created_time")

397

);

398

}

399

400

public static boolean bulkUpdateUserStatus(List<Long> userIds, String status) {

401

return Db.update(User.class,

402

new UpdateWrapper<User>()

403

.set("status", status)

404

.set("updated_time", LocalDateTime.now())

405

.in("id", userIds)

406

);

407

}

408

409

public static void cleanupOldInactiveUsers() {

410

LocalDateTime cutoffDate = LocalDateTime.now().minusYears(2);

411

Db.remove(User.class,

412

new QueryWrapper<User>()

413

.eq("active", false)

414

.lt("deactivated_time", cutoffDate)

415

);

416

}

417

}

418

```

419

420

### Scheduled Tasks

421

422

```java

423

@Component

424

public class UserMaintenanceScheduler {

425

426

@Scheduled(cron = "0 0 2 * * ?") // Daily at 2 AM

427

public void deactivateInactiveUsers() {

428

// Deactivate users inactive for 90 days

429

LocalDateTime cutoffDate = LocalDateTime.now().minusDays(90);

430

431

long count = Db.update(User.class,

432

new UpdateWrapper<User>()

433

.set("active", false)

434

.set("deactivated_time", LocalDateTime.now())

435

.lt("last_login", cutoffDate)

436

.eq("active", true)

437

) ? 1 : 0;

438

439

if (count > 0) {

440

System.out.println("Deactivated inactive users");

441

}

442

}

443

444

@Scheduled(cron = "0 0 3 * * 0") // Weekly on Sunday at 3 AM

445

public void cleanupOldData() {

446

// Remove users inactive for over 2 years

447

LocalDateTime cutoffDate = LocalDateTime.now().minusYears(2);

448

449

boolean removed = Db.remove(User.class,

450

new QueryWrapper<User>()

451

.eq("active", false)

452

.lt("deactivated_time", cutoffDate)

453

);

454

455

if (removed) {

456

System.out.println("Cleaned up old inactive user data");

457

}

458

}

459

}

460

```

461

462

### Data Migration Utilities

463

464

```java

465

public class DataMigrationUtils {

466

467

public static void migrateUserRoles() {

468

// Update old role format to new format

469

Db.update(User.class,

470

new UpdateWrapper<User>()

471

.set("role", "ADMIN")

472

.eq("role", "admin")

473

);

474

475

Db.update(User.class,

476

new UpdateWrapper<User>()

477

.setSql("role = UPPER(role)")

478

.ne("role", "ADMIN")

479

);

480

}

481

482

public static void addDefaultValues() {

483

// Add default values for users missing certain fields

484

Db.update(User.class,

485

new UpdateWrapper<User>()

486

.set("status", "ACTIVE")

487

.isNull("status")

488

);

489

490

Db.update(User.class,

491

new UpdateWrapper<User>()

492

.set("created_time", LocalDateTime.now())

493

.isNull("created_time")

494

);

495

}

496

497

public static void normalizeEmailAddresses() {

498

// Normalize email addresses to lowercase

499

List<User> users = Db.list(User.class,

500

new QueryWrapper<User>().isNotNull("email")

501

);

502

503

List<User> toUpdate = users.stream()

504

.filter(user -> !user.getEmail().equals(user.getEmail().toLowerCase()))

505

.peek(user -> user.setEmail(user.getEmail().toLowerCase()))

506

.collect(Collectors.toList());

507

508

if (!toUpdate.isEmpty()) {

509

Db.updateBatchById(toUpdate);

510

}

511

}

512

}

513

```

514

515

### Configuration and Cache Integration

516

517

```java

518

@Component

519

public class UserCacheManager {

520

521

@Cacheable(value = "users", key = "#id")

522

public User getCachedUser(Long id) {

523

return Db.getById(User.class, id);

524

}

525

526

@CacheEvict(value = "users", key = "#user.id")

527

public boolean updateUserWithCacheEviction(User user) {

528

return Db.updateById(user);

529

}

530

531

@CacheEvict(value = "users", allEntries = true)

532

public void clearUserCache() {

533

// Cache will be cleared after method execution

534

}

535

536

public List<User> getActiveUsersWithCache() {

537

// Check cache first, then database

538

return Db.list(User.class,

539

new QueryWrapper<User>().eq("active", true)

540

);

541

}

542

}

543

```

544

545

## Best Practices

546

547

### 1. Error Handling

548

549

```java

550

public class SafeDbOperations {

551

552

public static Optional<User> safeGetById(Long id) {

553

try {

554

return Db.getOptById(User.class, id);

555

} catch (Exception e) {

556

System.err.println("Error fetching user by ID " + id + ": " + e.getMessage());

557

return Optional.empty();

558

}

559

}

560

561

public static boolean safeSave(User user) {

562

try {

563

return Db.save(user);

564

} catch (Exception e) {

565

System.err.println("Error saving user: " + e.getMessage());

566

return false;

567

}

568

}

569

}

570

```

571

572

### 2. Parameter Validation

573

574

```java

575

public class ValidatedDbOperations {

576

577

public static List<User> findUsersByIds(Collection<Long> ids) {

578

if (ids == null || ids.isEmpty()) {

579

return Collections.emptyList();

580

}

581

582

return Db.listByIds(User.class, ids);

583

}

584

585

public static long countActiveUsers() {

586

return Db.count(User.class,

587

new QueryWrapper<User>().eq("active", true)

588

);

589

}

590

}

591

```

592

593

### 3. Performance Considerations

594

595

```java

596

public class PerformantDbOperations {

597

598

// Use batch operations for multiple records

599

public static boolean saveUsers(List<User> users) {

600

if (users.size() > 100) {

601

return Db.saveBatch(users, 50); // Custom batch size

602

} else {

603

return Db.saveBatch(users);

604

}

605

}

606

607

// Use specific field selection when possible

608

public static List<String> getUserEmails() {

609

return Db.listObjs(User.class,

610

new QueryWrapper<User>()

611

.select("email")

612

.eq("active", true),

613

Object::toString

614

);

615

}

616

617

// Use pagination for large result sets

618

public static Page<User> getLargeUserSet(int page, int size) {

619

return Db.page(User.class,

620

new Page<User>(page, size).setOptimizeCountSql(true)

621

);

622

}

623

}

624

```

625

626

The static utility approach is particularly useful for:

627

- Utility classes and helper methods

628

- Scheduled tasks and background jobs

629

- Data migration scripts

630

- Static initialization blocks

631

- Testing scenarios where dependency injection is not available

632

- Simple CRUD operations without complex business logic