MyBatis-Plus是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。本文主要介绍 Mybatis-Plus 的基本使用,相关的环境及软件信息如下:Spring Boot 2.6.12、Mybatis-Plus 3.5.2。
1、Mybatis-Plus 简介
1.1、特性
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
- 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
- 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
1.2、支持数据库
- MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb
- 达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库
1.3、框架结构
2、Mybatis-Plus 使用
这里演示下 Mybatis-plus 的基本使用,工程目录结构如下:
2.1、pom.xml
主要配置如下:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> <scope>provided</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>src/main/resources</directory> </resource> </resources> </build>
2.2、配置
2.2.1、应用配置(application.yml)
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://10.49.196.23:3306/test?useUnicode=true&characterEncoding=UTF-8 username: root password: 123456 mybatis-plus: configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
2.2.2、日志配置(logback.xml)
<?xml version="1.0" encoding="utf-8"?> <configuration debug="false"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter> <encoder> <pattern>%d %-5level [%thread] %logger[%L] -> %m%n</pattern> </encoder> </appender> <root level="info"> <appender-ref ref="STDOUT" /> </root> <logger name="com.abc.mapper" level="debug"> </logger> <logger name="com.baomidou.mybatisplus" level="debug"> </logger> </configuration>
2.3、创建 Mybatis-Plus 配置类
package com.abc.config; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MybatisConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); //分页插件 PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor(); //设置请求的页面大于最大页后操作,true调回到首页,false继续请求。默认false pageInterceptor.setOverflow(false); //单页分页条数限制,默认无限制 pageInterceptor.setMaxLimit(500L); //设置数据库类型 pageInterceptor.setDbType(DbType.MYSQL); interceptor.addInnerInterceptor(pageInterceptor); return interceptor; } }
2.4、创建实体类
package com.abc.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.ToString; import java.time.LocalDateTime; @ToString @Data @TableName("a_student") public class Student { @TableId(type = IdType.AUTO) private Long id; private LocalDateTime createTime; private LocalDateTime modifyTime; private String name; private Integer age; private String homeAddress; }
表 a_student 的字段与实体类的属性一一对应(表中字段使用下划线写法,实体类属性使用驼峰写法),字段 id 为自增字段。
2.5、创建 Mapper
package com.abc.mapper; import com.abc.entity.Student; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; import java.util.Map; @Mapper public interface StudentMapper extends BaseMapper<Student> { List<Student> select(@Param("name") String name, @Param("homeAddress") String homeAddress); List<Map<String, Object>> select2(String name, String homeAddress); }
Mybatis-Plus 的 BaseMapper 提供了基础的增删改查功能,如果不能满足需求,可以再定义额外的方法,对应的 XML 文件(StudentMapper.xml)内容为:
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.abc.mapper.StudentMapper"> <select id="select" resultType="com.abc.entity.Student"> select * from a_student where 1=1 <if test="name != null and name != ''"> and name like #{name} </if> <if test="homeAddress != null and homeAddress != ''"> and home_address like #{homeAddress} </if> </select> <select id="select2" resultType="map"> select * from a_student where 1=1 <if test="param1 != null and param1 != ''"> and name like #{param1} </if> <if test="param2 != null and param2 != ''"> and home_address like #{param2} </if> </select> </mapper>
2.6、创建 Service
package com.abc.service; import com.abc.entity.Student; import com.abc.mapper.StudentMapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; @Service public class StudentService extends ServiceImpl<StudentMapper, Student> { public List<Student> select(String name, String homeAddress) { return baseMapper.select(name, homeAddress); } public List<Map<String, Object>> select2(String name, String homeAddress) { return baseMapper.select2(name, homeAddress); } }
Mybatis-Plus 的 ServiceImpl 进一步封装了增删改查的功能,可以更好的满足业务需求;当然对于特定的业务需求也可以定义自己的方法。
2.7、测试用例
2.7.1、Mapper 测试用例
package com.abc.mapper; import com.abc.entity.Student; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; @RunWith(SpringRunner.class) @SpringBootTest public class StudentMapperCase { private static final Logger logger = LoggerFactory.getLogger(StudentMapperCase.class); @Autowired private StudentMapper studentMapper; @Test public void insert() { Student student = new Student(); student.setCreateTime(LocalDateTime.now()); student.setName("李白"); student.setAge(30); student.setHomeAddress("长安"); studentMapper.insert(student); logger.info("id={}", student.getId()); } @Test public void update() { Student student = new Student(); student.setId(261L); student.setName("李白2"); studentMapper.updateById(student); } @Test public void selectById() { Student student = studentMapper.selectById(261L); logger.info(student.toString()); } @Test public void select() { List<Student> students = studentMapper.select("%李%", "%长%"); logger.info(students.toString()); } @Test public void selectForPage() { Page<Student> page = new Page<>(1, 3); QueryWrapper queryWrapper = new QueryWrapper(); queryWrapper.like("name", "%李%"); queryWrapper.like("home_address", "%长%"); Page<Student> result = studentMapper.selectPage(page, queryWrapper); logger.info(result.getRecords().toString()); } @Test public void select2() { List<Map<String, Object>> list = studentMapper.select2("%李%", "%长%"); logger.info(list.toString()); } @Test public void delete() { List<Long> list = new ArrayList(){{ add(260L); add(263L); }}; studentMapper.deleteBatchIds(list); } }
2.7.2、Service 测试用例
package com.abc.service; import com.abc.entity.Student; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.junit.Test; import org.junit.runner.RunWith; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; @RunWith(SpringRunner.class) @SpringBootTest public class StudentServiceCase { private static final Logger logger = LoggerFactory.getLogger(StudentServiceCase.class); @Autowired private StudentService studentService; @Test public void insert() { Student student = new Student(); student.setCreateTime(LocalDateTime.now()); student.setName("李白"); student.setAge(30); student.setHomeAddress("长安"); studentService.save(student); logger.info("id={}", student.getId()); } @Test public void update() { Student student = new Student(); student.setId(261L); student.setName("杜甫"); studentService.saveOrUpdate(student); } @Test public void selectById() { Student student = studentService.getById(261L); logger.info(student.toString()); } @Test public void select() { List<Student> students = studentService.select("%李%", "%长%"); logger.info(students.toString()); } @Test public void selectForPage() { Page<Student> page = new Page<>(1, 3); QueryWrapper queryWrapper = new QueryWrapper(); queryWrapper.like("name", "%李%"); queryWrapper.like("home_address", "%长%"); Page<Student> result = studentService.page(page, queryWrapper); logger.info(result.getRecords().toString()); } @Test public void select2() { List<Map<String, Object>> list = studentService.select2("%李%", "%长%"); logger.info(list.toString()); } @Test public void delete() { List<Long> list = new ArrayList(){{ add(260L); add(263L); }}; studentService.removeBatchByIds(list); } }
更多详细说明及使用方法请参考官网文档:https://baomidou.com/。