Boost Your Java Backend with MyBatisPlusPro: A Complete CRUD Controller Guide
This article walks through building a reusable BaseController using MyBatisPlusPro in a Spring Boot application, covering dependency setup, utility methods for query conversion, generic CRUD endpoints, pagination configuration, and how to extend the controller for specific entities, providing ready‑to‑use code snippets for each step.
MyBatisPlusPro Overview
This guide demonstrates how to create a reusable BaseController that provides generic CRUD operations for any entity in a Spring Boot project using MyBatisPlusPro.
Step 1 – Add MyBatisPlus Dependency
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>Step 2 – Write Utility Class
The ApprenticeUtil class contains helper methods for converting between camel‑case and snake‑case, building QueryWrapper objects from an entity, and retrieving field values via reflection.
public class ApprenticeUtil {
private static Pattern humpPattern = Pattern.compile("[A-Z]");
private static Pattern linePattern = Pattern.compile("_(\\w)");
/** Convert camelCase to snake_case */
public static String humpToLine(String str) {
Matcher matcher = humpPattern.matcher(str);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
}
matcher.appendTail(sb);
return sb.toString();
}
/** Convert snake_case to camelCase */
public static String lineToHump(String str) {
str = str.toLowerCase();
Matcher matcher = linePattern.matcher(str);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
}
matcher.appendTail(sb);
return sb.toString();
}
/** Build QueryWrapper from non‑null fields */
public static <E> QueryWrapper<E> getQueryWrapper(E entity) {
Field[] fields = entity.getClass().getDeclaredFields();
QueryWrapper<E> queryWrapper = new QueryWrapper<>();
for (Field field : fields) {
if (Modifier.isFinal(field.getModifiers())) continue;
field.setAccessible(true);
try {
Object value = field.get(entity);
if (!ObjectUtils.isEmpty(value)) {
String name = humpToLine(field.getName());
queryWrapper.eq(name, value);
}
} catch (IllegalAccessException e) {
return null;
}
}
return queryWrapper;
}
/** Reflectively get a field value */
public static <E> Object getValueForClass(E entity, String value) {
try {
Field field = entity.getClass().getDeclaredField(value);
PropertyDescriptor pd = new PropertyDescriptor(field.getName(), entity.getClass());
Method getter = pd.getReadMethod();
return ReflectionUtils.invokeMethod(getter, entity);
} catch (NoSuchFieldException | IntrospectionException e) {
e.printStackTrace();
return null;
}
}
}Step 3 – Core Generic Controller
The BaseController class defines CRUD endpoints (insert, delete, update, getById, save, list, page, count) using generic types S extends IService<E> and E. Each method delegates to the injected service and returns a standardized ResponseUtils result.
public class BaseController<S extends IService<E>, E> {
@Autowired
protected S baseService;
@ApiOperation("增")
@PostMapping("/insert")
public ResponseUtils insert(@RequestBody E entity) {
baseService.save(entity);
return ResponseUtils.success("添加成功");
}
@ApiOperation("删")
@PostMapping("/deleteById")
public ResponseUtils delete(@RequestBody List<Integer> ids) {
baseService.removeByIds(ids);
return ResponseUtils.success("删除成功");
}
@ApiOperation("改")
@PostMapping("/updateById")
public ResponseUtils updateById(@RequestBody E entity) {
baseService.updateById(entity);
return ResponseUtils.success("更新成功");
}
@ApiOperation("查")
@GetMapping("/getById")
public ResponseUtils getById(@RequestParam Integer id) {
return ResponseUtils.success(baseService.getById(id));
}
@ApiOperation("存")
@PostMapping("/save")
public ResponseUtils save(@RequestBody E entity) {
baseService.saveOrUpdate(entity);
return ResponseUtils.success("保存成功");
}
@ApiOperation("list查")
@PostMapping("/list")
public ResponseUtils list(@RequestBody E entity) {
QueryWrapper<E> queryWrapper = ApprenticeUtil.getQueryWrapper(entity);
List<E> list = baseService.list(queryWrapper);
return ResponseUtils.success(list);
}
@ApiOperation("page查")
@PostMapping("/page")
public ResponseUtils page(@RequestBody PageParamDto<E> pageParamDto) {
if (pageParamDto.getPage() < 1) pageParamDto.setPage(1);
if (pageParamDto.getSize() > 100) pageParamDto.setSize(100);
Page<E> page = new Page<>(pageParamDto.getPage(), pageParamDto.getSize());
QueryWrapper<E> queryWrapper = new QueryWrapper<>();
if (!StrUtil.isEmpty(pageParamDto.getAsc()) && !"null".equals(pageParamDto.getAsc())) {
queryWrapper.orderByAsc(pageParamDto.getAsc().split(","));
}
if (!StrUtil.isEmpty(pageParamDto.getDesc()) && !"null".equals(pageParamDto.getDesc())) {
queryWrapper.orderByDesc(pageParamDto.getDesc().split(","));
}
Page<E> ePage = baseService.page(page, queryWrapper);
return ResponseUtils.success(ePage);
}
@ApiOperation("获取数量")
@PostMapping("/count")
public ResponseUtils count(@RequestBody E entity) {
QueryWrapper<E> queryWrapper = ApprenticeUtil.getQueryWrapper(entity);
long count = baseService.count(queryWrapper);
return ResponseUtils.success(count);
}
}Step 4 – Pagination Configuration
@Configuration
public class MybatisPlusConfig {
/** Register pagination interceptor */
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}Step 5 – Extend the Generic Controller
Create concrete controllers by extending BaseController and specifying the service and entity types.
@RestController
@RequestMapping("/apprentice/dynamic")
@Api("动态管理")
public class DynamicController extends BaseController<IDynamicService, Dynamic> {} @RestController
@RequestMapping("/apprentice/blog")
@Api(tags = "博客管理")
public class BlogController extends BaseController<IBlogService, Blog> {}After these steps, the application automatically supports standard CRUD operations for the defined entities.
Reference
https://gitee.com/WangFuGui-Ma/mybatis-plus-proArchitect's Tech Stack
Java backend, microservices, distributed systems, containerized programming, and more.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
