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

service-layer.mddocs/

0

# Service Layer

1

2

The Service Layer is the core component of MyBatis-Plus Extension, providing a comprehensive abstraction over MyBatis CRUD operations. It consists of the `IService` interface that defines all common database operations and the `ServiceImpl` base class that provides ready-to-use implementations.

3

4

## Core Components

5

6

### IService Interface

7

8

The `IService<T>` interface provides a complete set of CRUD operations for entity management.

9

10

```java { .api }

11

public interface IService<T> {

12

int DEFAULT_BATCH_SIZE = 1000;

13

14

// Save operations

15

boolean save(T entity);

16

boolean saveBatch(Collection<T> entityList);

17

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

18

boolean saveOrUpdate(T entity);

19

boolean saveOrUpdateBatch(Collection<T> entityList);

20

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

21

22

// Remove operations

23

boolean removeById(Serializable id);

24

boolean removeByIds(Collection<? extends Serializable> idList);

25

boolean removeByMap(Map<String, Object> columnMap);

26

boolean remove(Wrapper<T> queryWrapper);

27

boolean removeBatchByIds(Collection<? extends Serializable> idList);

28

29

// Update operations

30

boolean updateById(T entity);

31

boolean update(T entity, Wrapper<T> updateWrapper);

32

boolean updateBatchById(Collection<T> entityList);

33

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

34

35

// Query operations

36

T getById(Serializable id);

37

Optional<T> getOptById(Serializable id);

38

T getOne(Wrapper<T> queryWrapper);

39

Optional<T> getOneOpt(Wrapper<T> queryWrapper);

40

T getOne(Wrapper<T> queryWrapper, boolean throwEx);

41

Optional<T> getOneOpt(Wrapper<T> queryWrapper, boolean throwEx);

42

Map<String, Object> getMap(Wrapper<T> queryWrapper);

43

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

44

45

// List operations

46

List<T> list();

47

List<T> list(Wrapper<T> queryWrapper);

48

List<T> listByIds(Collection<? extends Serializable> idList);

49

List<T> listByMap(Map<String, Object> columnMap);

50

List<Map<String, Object>> listMaps();

51

List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);

52

<V> List<V> listObjs();

53

<V> List<V> listObjs(Function<? super Object, V> mapper);

54

<V> List<V> listObjs(Wrapper<T> queryWrapper);

55

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

56

57

// Count operations

58

long count();

59

long count(Wrapper<T> queryWrapper);

60

boolean exists(Wrapper<T> queryWrapper);

61

62

// Pagination operations

63

<E extends IPage<T>> E page(E page);

64

<E extends IPage<T>> E page(E page, Wrapper<T> queryWrapper);

65

<E extends IPage<Map<String, Object>>> E pageMaps(E page, Wrapper<T> queryWrapper);

66

67

// Chain operations

68

QueryChainWrapper<T> query();

69

LambdaQueryChainWrapper<T> lambdaQuery();

70

KtQueryChainWrapper<T> ktQuery();

71

UpdateChainWrapper<T> update();

72

LambdaUpdateChainWrapper<T> lambdaUpdate();

73

KtUpdateChainWrapper<T> ktUpdate();

74

}

75

```

76

77

### ServiceImpl Base Class

78

79

The `ServiceImpl<M, T>` abstract class provides default implementations for all `IService` methods.

80

81

```java { .api }

82

public abstract class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {

83

protected Log log = LogFactory.getLog(getClass());

84

85

@Autowired

86

protected M baseMapper;

87

88

// Access methods

89

public M getBaseMapper();

90

protected Class<T> getEntityClass();

91

protected Class<?> getMapperClass();

92

93

// Batch operations with optimized implementations

94

@Transactional(rollbackFor = Exception.class)

95

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

96

97

@Transactional(rollbackFor = Exception.class)

98

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

99

100

@Transactional(rollbackFor = Exception.class)

101

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

102

103

// Single entity operations

104

public boolean saveOrUpdate(T entity);

105

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

106

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

107

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

108

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

109

}

110

```

111

112

## Usage Examples

113

114

### Basic Service Setup

115

116

```java

117

// Define entity

118

@TableName("user")

119

public class User {

120

@TableId

121

private Long id;

122

private String name;

123

private String email;

124

private Boolean active;

125

// getters and setters

126

}

127

128

// Define service interface

129

public interface UserService extends IService<User> {

130

// Add custom methods if needed

131

List<User> findActiveUsers();

132

}

133

134

// Implement service

135

@Service

136

public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

137

138

@Override

139

public List<User> findActiveUsers() {

140

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

141

}

142

}

143

```

144

145

### Save Operations

146

147

```java

148

@Autowired

149

private UserService userService;

150

151

// Save single entity

152

User user = new User();

153

user.setName("John Doe");

154

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

155

boolean saved = userService.save(user);

156

157

// Save batch

158

List<User> users = Arrays.asList(

159

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

160

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

161

);

162

boolean allSaved = userService.saveBatch(users);

163

164

// Save or update (based on primary key presence)

165

User existingUser = userService.getById(1L);

166

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

167

boolean updated = userService.saveOrUpdate(existingUser);

168

```

169

170

### Query Operations

171

172

```java

173

// Get by ID

174

User user = userService.getById(1L);

175

Optional<User> optionalUser = userService.getOptById(1L);

176

177

// Get single with conditions

178

User activeUser = userService.getOne(

179

new QueryWrapper<User>()

180

.eq("active", true)

181

.eq("email", "john@example.com")

182

);

183

184

// List operations

185

List<User> allUsers = userService.list();

186

List<User> activeUsers = userService.list(

187

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

188

);

189

190

// Count operations

191

long totalUsers = userService.count();

192

long activeCount = userService.count(

193

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

194

);

195

196

// Check existence

197

boolean hasActiveUsers = userService.exists(

198

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

199

);

200

```

201

202

### Update Operations

203

204

```java

205

// Update by ID

206

User user = userService.getById(1L);

207

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

208

boolean updated = userService.updateById(user);

209

210

// Update with conditions

211

boolean updated = userService.update(

212

new User().setActive(false),

213

new UpdateWrapper<User>().eq("last_login", null)

214

);

215

216

// Batch update by IDs

217

List<User> users = userService.listByIds(Arrays.asList(1L, 2L, 3L));

218

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

219

boolean allUpdated = userService.updateBatchById(users);

220

```

221

222

### Remove Operations

223

224

```java

225

// Remove by ID

226

boolean removed = userService.removeById(1L);

227

228

// Remove by IDs

229

boolean allRemoved = userService.removeByIds(Arrays.asList(1L, 2L, 3L));

230

231

// Remove with conditions

232

boolean inactiveRemoved = userService.remove(

233

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

234

);

235

236

// Remove by column map

237

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

238

conditions.put("active", false);

239

conditions.put("last_login", null);

240

boolean removed = userService.removeByMap(conditions);

241

```

242

243

### Pagination

244

245

```java

246

// Basic pagination

247

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

248

Page<User> result = userService.page(page);

249

250

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

251

long total = result.getTotal();

252

long pages = result.getPages();

253

254

// Pagination with conditions

255

Page<User> activePage = userService.page(

256

new Page<>(1, 10),

257

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

258

);

259

260

// Pagination with custom ordering

261

Page<User> orderedPage = new Page<User>(1, 10)

262

.addOrder(OrderItem.desc("created_time"));

263

Page<User> result = userService.page(orderedPage);

264

```

265

266

### Chain Operations

267

268

```java

269

// Query chains

270

List<User> users = userService.query()

271

.eq("active", true)

272

.gt("age", 18)

273

.list();

274

275

User user = userService.lambdaQuery()

276

.eq(User::getActive, true)

277

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

278

.one();

279

280

// Update chains

281

boolean updated = userService.update()

282

.set("active", false)

283

.eq("last_login", null)

284

.update();

285

286

boolean updated = userService.lambdaUpdate()

287

.set(User::getActive, false)

288

.isNull(User::getLastLogin)

289

.update();

290

```

291

292

## Advanced Features

293

294

### Custom Batch Size

295

296

```java

297

// Use custom batch size for large datasets

298

List<User> largeUserList = createLargeUserList();

299

boolean saved = userService.saveBatch(largeUserList, 500); // batch size 500

300

```

301

302

### Object Mapping

303

304

```java

305

// Get specific fields as objects

306

List<String> emails = userService.listObjs(

307

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

308

Object::toString

309

);

310

311

// Get single field value

312

String email = userService.getObj(

313

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

314

Object::toString

315

);

316

```

317

318

### Map Results

319

320

```java

321

// Get results as maps for dynamic field access

322

List<Map<String, Object>> userMaps = userService.listMaps(

323

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

324

);

325

326

Map<String, Object> userMap = userService.getMap(

327

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

328

);

329

```

330

331

## Error Handling

332

333

The service layer methods return boolean values for modification operations and null/empty collections for query operations when no results are found. For methods that expect single results, you can use the `throwEx` parameter or Optional variants:

334

335

```java

336

// Will throw exception if multiple results found

337

User user = userService.getOne(wrapper, true);

338

339

// Will return Optional.empty() if no result found

340

Optional<User> optionalUser = userService.getOneOpt(wrapper);

341

342

// Safe approach with Optional

343

Optional<User> user = userService.getOptById(1L);

344

if (user.isPresent()) {

345

// Process user

346

} else {

347

// Handle not found case

348

}

349

```