1、MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
2、特性:
- 无侵入:在mybatis基础上只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
扫描实体类,通过反射,分析出表名以及字段,然后自动生成CRUD的SQL语句,最后注入到mybatis容器中
3、Lambda表达式
Lambda 表达式是 Java 8 中引入的一种新特性,它可以用更简洁的语法来表示匿名函数。Lambda 表达式通常由三个部分组成:
-
形参列表:使用小括号 () 括起来,多个参数之间使用逗号分隔。
-
箭头符号:用于连接形参列表和 Lambda 表达式的主体部分,可以是 -> 或者 ::。
-
Lambda 表达式的主体:可以是一个表达式,也可以是一个代码块。如果是一个表达式,则不需要使用 return 关键字返回值;如果是一个代码块,则需要使用大括号 {} 括起来,并使用 return 关键字返回值。
Lambda 表达式的语法如下:
(parameters) -> expression
或者
(parameters) -> { statements; }
其中 parameters 是形参列表,expression 是单个表达式,statements 是一组语句。
Lambda 表达式还可以使用预定义的函数式接口,例如 Runnable、Consumer、Predicate 等,以简化代码的编写。以下是一个使用 Predicate 接口的示例:
List<String> list = Arrays.asList("Java", "Python", "C++", "JavaScript");
Predicate<String> predicate = s -> s.startsWith("J");
list.stream().filter(predicate).forEach(System.out::println); // 输出 Java JavaScript
以上代码中,我们首先创建了一个 Predicate 对象,用于过滤以字母 J 开头的字符串。然后使用 stream() 方法将 List 转化为流,再使用 filter() 方法对流进行过滤,最后使用 forEach() 方法遍历输出结果。
4、条件构造器(Wrapper
)
Wrapper
:条件构造器抽象类,最顶端的父类AbstractWrapper
:查询条件封装抽象类,生成 SQL 的 where 条件QueryWrapper
:用于对象封装UpdateWrapper
:用于条件封装
AbstractLambdaWrapper
:Lambda 语法使用 WrapperLambdaQueryWrapper
:用于对象封装,使用 Lambda 语法LambdaUpdateWrapper
:用于条件封装,使用 Lambda 语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | @SpringBootTest @MapperScan ( "com.wwj.mybatisplusdemo.mapper" ) class MybatisplusDemoApplicationTests { @Autowired private EmployeeMapper employeeMapper; @Test void contextLoads() { // 查询名字中包含'j',年龄大于20岁,邮箱不为空的员工信息 QueryWrapper<Employee> wrapper = new QueryWrapper<>(); wrapper.like( "last_name" , "j" ); wrapper.gt( "age" , 20 ); wrapper.isNotNull( "email" ); List<Employee> list = employeeMapper.selectList(wrapper); list.forEach(System.out::println); } } |
1 2 3 4 5 6 7 8 9 10 | @Test void contextLoads() { // 查询名字中包含'j',年龄大于20岁,邮箱不为空的员工信息 LambdaQueryWrapper<Employee> wrapper = new LambdaQueryWrapper<Employee>() .like(Employee::getLastName, "j" ) .gt(Employee::getAge, 20 ) .isNotNull(Employee::getEmail); List<Employee> list = employeeMapper.selectList(wrapper); list.forEach(System.out::println); } |
UpdateWrapper
与 QueryWrapper
不同,它的作用是封装更新内容的,比如:
1 2 3 4 5 6 7 8 9 | @Test void contextLoads() { UpdateWrapper<Employee> wrapper = new UpdateWrapper<Employee>() .set( "age" , 50 ) .set( "email" , "emp@163.com" ) .like( "last_name" , "j" ) .gt( "age" , 20 ); employeeMapper.update( null , wrapper); } |
5、分页插件
对于分页功能,MyBatisPlus
提供了分页插件,只需要进行简单的配置即可实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @Configuration public class MyBatisConfig { /** * 注册分页插件 * @return */ @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor( new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } } |
接下来我们就可以使用分页插件提供的功能了:
1 2 3 4 5 6 7 8 9 10 11 12 13 | @Test void contextLoads() { Page<Employee> page = new Page<>( 1 , 2 ); employeeService.page(page, null ); List<Employee> employeeList = page.getRecords(); employeeList.forEach(System.out::println); System.out.println( "获取总条数:" + page.getTotal()); System.out.println( "获取当前页码:" + page.getCurrent()); System.out.println( "获取总页码:" + page.getPages()); System.out.println( "获取每页显示的数据条数:" + page.getSize()); System.out.println( "是否有上一页:" + page.hasPrevious()); System.out.println( "是否有下一页:" + page.hasNext()); } |
倘若在分页过程中需要限定一些条件,我们就需要构建 QueryWrapper 来实现:
123456789@Test
void
contextLoads() {
Page<Employee> page =
new
Page<>(
1
,
2
);
employeeService.page(page,
new
QueryWrapper<Employee>()
.between(
"age"
,
20
,
50
)
.eq(
"gender"
,
1
));
List<Employee> employeeList = page.getRecords();
employeeList.forEach(System.out::println);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!