0
# Spring Boot Integration
1
2
MyBatis-Plus provides seamless Spring Boot integration with auto-configuration, properties binding, starter dependencies, and comprehensive configuration options for rapid application development.
3
4
## Capabilities
5
6
### Auto-Configuration Classes
7
8
#### MybatisPlusAutoConfiguration
9
10
Main auto-configuration class for MyBatis-Plus integration.
11
12
```java { .api }
13
@Configuration
14
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
15
@ConditionalOnSingleCandidate(DataSource.class)
16
@EnableConfigurationProperties(MybatisPlusProperties.class)
17
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class})
18
public class MybatisPlusAutoConfiguration implements InitializingBean {
19
20
/**
21
* Create SqlSessionFactory bean
22
* @param dataSource Data source
23
* @return SqlSessionFactory instance
24
* @throws Exception if configuration fails
25
*/
26
@Bean
27
@ConditionalOnMissingBean
28
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception;
29
30
/**
31
* Create SqlSessionTemplate bean
32
* @param sqlSessionFactory SqlSessionFactory instance
33
* @return SqlSessionTemplate instance
34
*/
35
@Bean
36
@ConditionalOnMissingBean
37
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory);
38
39
/**
40
* Create MapperScannerConfigurer for automatic mapper scanning
41
* @return MapperScannerConfigurer instance
42
*/
43
@Bean
44
@ConditionalOnMissingBean
45
public MapperScannerConfigurer mapperScannerConfigurer();
46
}
47
```
48
49
#### MybatisPlusProperties
50
51
Configuration properties class for MyBatis-Plus settings.
52
53
```java { .api }
54
/**
55
* MyBatis-Plus configuration properties
56
*/
57
@ConfigurationProperties(prefix = "mybatis-plus")
58
public class MybatisPlusProperties {
59
60
/**
61
* MyBatis configuration file location
62
*/
63
private String config;
64
65
/**
66
* MyBatis configuration file location (alias for config)
67
*/
68
private String configLocation;
69
70
/**
71
* Mapper XML file locations
72
*/
73
private String[] mapperLocations = new String[]{"classpath*:/mapper/**/*.xml"};
74
75
/**
76
* Type aliases package
77
*/
78
private String typeAliasesPackage;
79
80
/**
81
* Type aliases super type
82
*/
83
private Class<?> typeAliasesSuperType;
84
85
/**
86
* Type handlers package
87
*/
88
private String typeHandlersPackage;
89
90
/**
91
* Executor type
92
*/
93
private ExecutorType executorType;
94
95
/**
96
* Configuration properties
97
*/
98
private Properties configurationProperties;
99
100
/**
101
* MyBatis-Plus global configuration
102
*/
103
private GlobalConfig globalConfig = new GlobalConfig();
104
105
// getters and setters...
106
}
107
```
108
109
### Configuration Customizers
110
111
#### ConfigurationCustomizer
112
113
Interface for customizing MyBatis Configuration.
114
115
```java { .api }
116
/**
117
* Configuration customizer interface
118
*/
119
@FunctionalInterface
120
public interface ConfigurationCustomizer {
121
122
/**
123
* Customize MyBatis Configuration
124
* @param configuration MyBatis Configuration instance
125
*/
126
void customize(Configuration configuration);
127
}
128
```
129
130
#### MybatisPlusPropertiesCustomizer
131
132
Interface for customizing MyBatis-Plus properties.
133
134
```java { .api }
135
/**
136
* MyBatis-Plus properties customizer interface
137
*/
138
@FunctionalInterface
139
public interface MybatisPlusPropertiesCustomizer {
140
141
/**
142
* Customize MyBatis-Plus properties
143
* @param properties MybatisPlusProperties instance
144
*/
145
void customize(MybatisPlusProperties properties);
146
}
147
```
148
149
### VFS Integration
150
151
#### SpringBootVFS
152
153
Spring Boot VFS implementation for resource loading.
154
155
```java { .api }
156
/**
157
* Spring Boot VFS implementation
158
*/
159
public class SpringBootVFS extends VFS {
160
161
/**
162
* Check if VFS is valid for current environment
163
* @return true if valid
164
*/
165
@Override
166
public boolean isValid();
167
168
/**
169
* List resources matching the path pattern
170
* @param path Resource path pattern
171
* @return List of resource URLs
172
* @throws IOException if resource loading fails
173
*/
174
@Override
175
protected List<String> list(URL path, String forPath) throws IOException;
176
}
177
```
178
179
## Usage Examples
180
181
**Basic Spring Boot Setup:**
182
183
```xml
184
<!-- pom.xml -->
185
<dependency>
186
<groupId>com.baomidou</groupId>
187
<artifactId>mybatis-plus-boot-starter</artifactId>
188
<version>3.5.7</version>
189
</dependency>
190
191
<dependency>
192
<groupId>mysql</groupId>
193
<artifactId>mysql-connector-java</artifactId>
194
<scope>runtime</scope>
195
</dependency>
196
```
197
198
```yaml
199
# application.yml
200
spring:
201
datasource:
202
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
203
username: root
204
password: password
205
driver-class-name: com.mysql.cj.jdbc.Driver
206
207
mybatis-plus:
208
mapper-locations: classpath*:/mapper/**/*.xml
209
type-aliases-package: com.example.entity
210
configuration:
211
map-underscore-to-camel-case: true
212
cache-enabled: false
213
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
214
global-config:
215
db-config:
216
id-type: AUTO
217
logic-delete-field: deleted
218
logic-delete-value: 1
219
logic-not-delete-value: 0
220
```
221
222
**Application Configuration:**
223
224
```java
225
@SpringBootApplication
226
@MapperScan("com.example.mapper")
227
public class Application {
228
public static void main(String[] args) {
229
SpringApplication.run(Application.class, args);
230
}
231
}
232
```
233
234
**Comprehensive Configuration:**
235
236
```yaml
237
# application.yml
238
mybatis-plus:
239
# MyBatis mapper xml file path
240
mapper-locations: classpath*:/mapper/**/*.xml
241
242
# MyBatis type aliases package
243
type-aliases-package: com.example.entity
244
245
# MyBatis type aliases super type
246
type-aliases-super-type: com.example.base.BaseEntity
247
248
# MyBatis type handlers package
249
type-handlers-package: com.example.typehandler
250
251
# MyBatis executor type
252
executor-type: SIMPLE
253
254
# MyBatis configuration
255
configuration:
256
# Enable automatic camel case mapping
257
map-underscore-to-camel-case: true
258
259
# Cache configuration
260
cache-enabled: true
261
lazy-loading-enabled: true
262
aggressive-lazy-loading: false
263
264
# Log implementation
265
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
266
267
# Call setters on null values
268
call-setters-on-nulls: true
269
270
# Return instance for empty row
271
return-instance-for-empty-row: true
272
273
# Auto mapping behavior
274
auto-mapping-behavior: PARTIAL
275
276
# Auto mapping unknown column behavior
277
auto-mapping-unknown-column-behavior: NONE
278
279
# Default statement timeout
280
default-statement-timeout: 30
281
282
# Default fetch size
283
default-fetch-size: 100
284
285
# MyBatis-Plus global configuration
286
global-config:
287
# Banner configuration
288
banner: true
289
290
# Database configuration
291
db-config:
292
# Primary key type
293
id-type: ASSIGN_ID
294
295
# Table prefix
296
table-prefix: t_
297
298
# Schema
299
schema: test_db
300
301
# Column format
302
column-format: '%s'
303
304
# Property format
305
property-format: '%s'
306
307
# Table name underline conversion
308
table-underline: true
309
310
# Column name underline conversion
311
column-underline: true
312
313
# Capital mode
314
capital-mode: false
315
316
# Logic delete configuration
317
logic-delete-field: deleted
318
logic-delete-value: 1
319
logic-not-delete-value: 0
320
321
# Field strategy
322
insert-strategy: NOT_NULL
323
update-strategy: NOT_NULL
324
where-strategy: NOT_NULL
325
```
326
327
**Configuration Beans:**
328
329
```java
330
@Configuration
331
public class MybatisPlusConfig {
332
333
/**
334
* MyBatis-Plus interceptor configuration
335
*/
336
@Bean
337
public MybatisPlusInterceptor mybatisPlusInterceptor() {
338
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
339
340
// Pagination interceptor
341
PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
342
paginationInterceptor.setMaxLimit(1000L);
343
paginationInterceptor.setOverflow(true);
344
interceptor.addInnerInterceptor(paginationInterceptor);
345
346
// Optimistic locking interceptor
347
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
348
349
// Block attack interceptor
350
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
351
352
return interceptor;
353
}
354
355
/**
356
* Meta object handler for auto-fill
357
*/
358
@Bean
359
public MetaObjectHandler metaObjectHandler() {
360
return new MetaObjectHandler() {
361
@Override
362
public void insertFill(MetaObject metaObject) {
363
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
364
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
365
}
366
367
@Override
368
public void updateFill(MetaObject metaObject) {
369
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
370
}
371
};
372
}
373
374
/**
375
* Custom ID generator
376
*/
377
@Bean
378
public IdentifierGenerator identifierGenerator() {
379
return new CustomIdGenerator();
380
}
381
382
/**
383
* SQL injector for custom methods
384
*/
385
@Bean
386
public ISqlInjector sqlInjector() {
387
return new DefaultSqlInjector() {
388
@Override
389
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
390
List<AbstractMethod> methodList = super.getMethodList(mapperClass);
391
// Add custom methods
392
methodList.add(new SelectByIdWithDeleted());
393
methodList.add(new DeleteAllMethod());
394
return methodList;
395
}
396
};
397
}
398
}
399
```
400
401
**Custom Configuration Customizers:**
402
403
```java
404
@Component
405
public class MyBatisConfigurationCustomizer implements ConfigurationCustomizer {
406
407
@Override
408
public void customize(Configuration configuration) {
409
// Custom MyBatis configuration
410
configuration.setMapUnderscoreToCamelCase(true);
411
configuration.setDefaultStatementTimeout(30);
412
configuration.setDefaultFetchSize(100);
413
414
// Add custom type handlers
415
configuration.getTypeHandlerRegistry().register(LocalDateTime.class, JdbcType.TIMESTAMP, LocalDateTimeTypeHandler.class);
416
417
// Add custom object wrappers
418
configuration.setObjectWrapperFactory(new CustomObjectWrapperFactory());
419
}
420
}
421
422
@Component
423
public class MyBatisPlusPropertiesCustomizer implements MybatisPlusPropertiesCustomizer {
424
425
@Override
426
public void customize(MybatisPlusProperties properties) {
427
// Custom MyBatis-Plus properties
428
GlobalConfig globalConfig = properties.getGlobalConfig();
429
GlobalConfig.DbConfig dbConfig = globalConfig.getDbConfig();
430
431
// Set custom configurations
432
dbConfig.setIdType(IdType.ASSIGN_ID);
433
dbConfig.setTablePrefix("sys_");
434
dbConfig.setLogicDeleteField("is_deleted");
435
dbConfig.setLogicDeleteValue("1");
436
dbConfig.setLogicNotDeleteValue("0");
437
}
438
}
439
```
440
441
**Conditional Configuration:**
442
443
```java
444
@Configuration
445
public class MybatisPlusConfig {
446
447
@Bean
448
@ConditionalOnProperty(name = "mybatis-plus.pagination.enabled", havingValue = "true", matchIfMissing = true)
449
public PaginationInnerInterceptor paginationInnerInterceptor() {
450
PaginationInnerInterceptor interceptor = new PaginationInnerInterceptor(DbType.MYSQL);
451
interceptor.setMaxLimit(1000L);
452
return interceptor;
453
}
454
455
@Bean
456
@ConditionalOnProperty(name = "mybatis-plus.tenant.enabled", havingValue = "true")
457
public TenantLineInnerInterceptor tenantLineInnerInterceptor() {
458
return new TenantLineInnerInterceptor(new CustomTenantLineHandler());
459
}
460
461
@Bean
462
@Profile("dev")
463
public MybatisPlusInterceptor devMybatisPlusInterceptor() {
464
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
465
// Development-specific interceptors
466
interceptor.addInnerInterceptor(new SqlExplainInterceptor());
467
return interceptor;
468
}
469
470
@Bean
471
@Profile("prod")
472
public MybatisPlusInterceptor prodMybatisPlusInterceptor() {
473
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
474
// Production-specific interceptors
475
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
476
interceptor.addInnerInterceptor(new IllegalSQLInnerInterceptor());
477
return interceptor;
478
}
479
}
480
```
481
482
**Multiple DataSource Configuration:**
483
484
```java
485
@Configuration
486
public class MultiDataSourceConfig {
487
488
@Primary
489
@Bean("primaryDataSource")
490
@ConfigurationProperties(prefix = "spring.datasource.primary")
491
public DataSource primaryDataSource() {
492
return DruidDataSourceBuilder.create().build();
493
}
494
495
@Bean("secondaryDataSource")
496
@ConfigurationProperties(prefix = "spring.datasource.secondary")
497
public DataSource secondaryDataSource() {
498
return DruidDataSourceBuilder.create().build();
499
}
500
501
@Primary
502
@Bean("primarySqlSessionFactory")
503
public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource,
504
MybatisPlusInterceptor interceptor) throws Exception {
505
MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
506
factory.setDataSource(dataSource);
507
factory.setPlugins(interceptor);
508
factory.setMapperLocations(new PathMatchingResourcePatternResolver()
509
.getResources("classpath*:/mapper/primary/**/*.xml"));
510
return factory.getObject();
511
}
512
513
@Bean("secondarySqlSessionFactory")
514
public SqlSessionFactory secondarySqlSessionFactory(@Qualifier("secondaryDataSource") DataSource dataSource,
515
MybatisPlusInterceptor interceptor) throws Exception {
516
MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
517
factory.setDataSource(dataSource);
518
factory.setPlugins(interceptor);
519
factory.setMapperLocations(new PathMatchingResourcePatternResolver()
520
.getResources("classpath*:/mapper/secondary/**/*.xml"));
521
return factory.getObject();
522
}
523
524
@Primary
525
@Bean("primarySqlSessionTemplate")
526
public SqlSessionTemplate primarySqlSessionTemplate(@Qualifier("primarySqlSessionFactory") SqlSessionFactory factory) {
527
return new SqlSessionTemplate(factory);
528
}
529
530
@Bean("secondarySqlSessionTemplate")
531
public SqlSessionTemplate secondarySqlSessionTemplate(@Qualifier("secondarySqlSessionFactory") SqlSessionFactory factory) {
532
return new SqlSessionTemplate(factory);
533
}
534
}
535
536
@MapperScan(basePackages = "com.example.mapper.primary", sqlSessionTemplateRef = "primarySqlSessionTemplate")
537
@Configuration
538
public class PrimaryMapperConfig {
539
}
540
541
@MapperScan(basePackages = "com.example.mapper.secondary", sqlSessionTemplateRef = "secondarySqlSessionTemplate")
542
@Configuration
543
public class SecondaryMapperConfig {
544
}
545
```
546
547
**Testing Configuration:**
548
549
```java
550
@TestConfiguration
551
public class TestMybatisPlusConfig {
552
553
@Bean
554
@Primary
555
public DataSource testDataSource() {
556
return new EmbeddedDatabaseBuilder()
557
.setType(EmbeddedDatabaseType.H2)
558
.addScript("classpath:schema.sql")
559
.addScript("classpath:data.sql")
560
.build();
561
}
562
563
@Bean
564
public MybatisPlusInterceptor testMybatisPlusInterceptor() {
565
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
566
// Test-specific interceptors only
567
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
568
return interceptor;
569
}
570
}
571
572
@SpringBootTest
573
@Transactional
574
@Rollback
575
class UserServiceTest {
576
577
@Autowired
578
private UserService userService;
579
580
@Test
581
void testSaveUser() {
582
User user = new User();
583
user.setName("Test User");
584
user.setEmail("test@example.com");
585
586
boolean result = userService.save(user);
587
588
assertThat(result).isTrue();
589
assertThat(user.getId()).isNotNull();
590
}
591
592
@Test
593
void testPageQuery() {
594
Page<User> page = new Page<>(1, 10);
595
IPage<User> result = userService.page(page);
596
597
assertThat(result.getRecords()).isNotEmpty();
598
assertThat(result.getTotal()).isGreaterThan(0);
599
}
600
}
601
```
602
603
**Monitoring and Health Checks:**
604
605
```java
606
@Component
607
@ConditionalOnProperty(name = "management.health.mybatis-plus.enabled", havingValue = "true", matchIfMissing = true)
608
public class MybatisPlusHealthIndicator implements HealthIndicator {
609
610
@Autowired
611
private SqlSessionFactory sqlSessionFactory;
612
613
@Override
614
public Health health() {
615
try {
616
// Test database connectivity
617
try (SqlSession session = sqlSessionFactory.openSession()) {
618
session.getConnection().isValid(1000);
619
return Health.up()
620
.withDetail("database", "Available")
621
.withDetail("mybatis-plus", "Operational")
622
.build();
623
}
624
} catch (Exception e) {
625
return Health.down(e)
626
.withDetail("database", "Unavailable")
627
.withDetail("mybatis-plus", "Non-operational")
628
.build();
629
}
630
}
631
}
632
633
@Component
634
@EventListener
635
public class MybatisPlusEventListener {
636
637
private static final Logger logger = LoggerFactory.getLogger(MybatisPlusEventListener.class);
638
639
@EventListener
640
public void handleApplicationReady(ApplicationReadyEvent event) {
641
logger.info("MyBatis-Plus integration initialized successfully");
642
}
643
644
@EventListener
645
public void handleContextClosed(ContextClosedEvent event) {
646
logger.info("MyBatis-Plus integration shutting down");
647
}
648
}
649
```
650
651
This comprehensive Spring Boot integration provides seamless auto-configuration, extensive customization options, and production-ready defaults for rapid development with MyBatis-Plus.