Spring boot集成MyBatis-plus快速入门
时间:2023-10-21 16:07:00
最好的学习方式就是官方文档:https://baomidou.com/pages/24112f/#特性
1. 快速入门
1.1 简介
MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)增强工具,在 MyBatis 在此基础上,只提高效率,只做增强而不做改变。
1.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.1.2 支持数据库
任何能使用
MyBatis
进行 CRUD, 并支持标准 SQL 具体支持数据库如下。
- MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb
- 大梦数据库、虚谷数据库、人大金仓数据库、南大通用(华库)数据库、神通数据库、汉高数据库
1.1.3 框架结构
[外链图片转存失败,源站可能有防盗链机制,建议保存图片并直接上传(img-DuS1g0rL-1654418423221)(D:\MyConfiguration\le.chen\AppData\Roaming\Typora\typora-user-images\image-20220601190250375.png)]
1.2 快速开始
我们将通过一个简单的 Demo 来阐述 MyBatis-Plus 在此之前,我们假设你已经:
- 拥有 Java 开发环境及相应性 IDE
- 熟悉 Spring Boot
- 熟悉 Maven
1.2.1 相关依赖
这里的依赖包括MP依赖、代码生成器、模板引擎等。
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
1.2.2 配置文件
配置数据库相关链接信息:
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456
1.2.3 代码生成器
我们这里为了简化开发,直接使用代码生成器来生成相关的实体类,dao及service。
这里需要注意的是修改相关目录,然后运行之后输入数据库中已经存在的表名即可。如果不是你想要的目录,则可以自行修改。
public class CodeGenerator {
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
//注意这个springboot-mybatis-plus-demo,由于我是在子模块下生成代码的,所以多加了一层目录;单层项目不需要加。
gc.setOutputDir(projectPath + "/springboot-mybatis-plus-demo" + "/src/main/java");
gc.setAuthor("chen");
gc.setOpen(false);
//实体属性 Swagger2 注解
gc.setSwagger2(false);
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/demo?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("123456");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
// pc.setModuleName(scanner("模块名"));
pc.setParent("com.example.springbootmybatisplusdemo");
pc.setEntity("dal.model");
pc.setMapper("dal.mapper");
pc.setService("service");
pc.setServiceImpl("service.impl");
mpg.setPackageInfo(pc);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig();
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setSuperEntityClass("com.baomidou.mybatisplus.extension.activerecord.Model");
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
strategy.setEntityLombokModel(true);
// 公共父类
// strategy.setSuperControllerClass("com.baomidou.ant.common.BaseController");
// 写于父类中的公共字段
// strategy.setSuperEntityColumns("id");
//表名
strategy.setInclude(scanner("表名").split(","));
strategy.setControllerMappingHyphenStyle(true);
strategy.setTablePrefix(pc.getModuleName() + "_");
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
public static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("请输入" + tip + ":");
System.out.println(help.toString());
if (scanner.hasNext()) {
String ipt = scanner.next();
if (StringUtils.isNotEmpty(ipt)) {
return ipt;
}
}
throw new MybatisPlusException("请输入正确的" + tip + "!");
}
}
1.2.4 测试
在测试之前,需要在启动类中添加扫描注解。
@SpringBootApplication
@MapperScan(value = {
"com.example.springbootmybatisplusdemo.dal.mapper"})
public class SpringbootMybatisPlusDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMybatisPlusDemoApplication.class, args);
}
}
然后在测试类中测试即可成功。
@SpringBootTest
class SpringbootMybatisPlusDemoApplicationTests {
@Autowired
private IUserService userService;
@Test
void contextLoads() {
System.out.println(userService.list());
}
}
2. 核心功能
2.1 CRUD接口
2.1.1 Service CRUD 接口
说明:
- 通用 Service CRUD 封装IService (opens new window)接口,进一步封装 CRUD 采用
get 查询单行
remove 删除
list 查询集合
page 分页
前缀命名方式区分Mapper
层避免混淆,- 泛型
T
为任意实体对象- 建议如果存在自定义通用 Service 方法的可能,请创建自己的
IBaseService
继承Mybatis-Plus
提供的基类- 对象
Wrapper
为 条件构造器
2.1.1.1 Save
// 插入一条记录(选择字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);
类型 | 参数名 | 描述 |
---|---|---|
T | entity | 实体对象 |
Collection | entityList | 实体对象集合 |
int | batchSize | 插入批次数量 |
2.1.1.2 SaveOrUpdate
// TableId 注解存在更新记录,否插入一条记录
boolean saveOrUpdate(T entity);
// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
类型 | 参数名 | 描述 |
---|---|---|
T | entity | 实体对象 |
Wrapper | updateWrapper | 实体对象封装操作类 UpdateWrapper |
Collection | entityList | 实体对象集合 |
int | batchSize | 插入批次数量 |
2.1.1.3 Remove
// 根据 entity 条件,删除记录
boolean remove(Wrapper<T> queryWrapper);
// 根据 ID 删除
boolean removeById(Serializable id);
// 根据 columnMap 条件,删除记录
boolean removeByMap(Map<String, Object> columnMap);
// 删除(根据ID 批量删除)
boolean removeByIds(Collection<? extends Serializable> idList);
类型 | 参数名 | 描述 |
---|---|---|
Wrapper | queryWrapper | 实体包装类 QueryWrapper |
Serializable | id | 主键 ID |
Map |
columnMap | 表字段 map 对象 |
Collection extends Serializable> | idList | 主键 ID 列表 |
2.1.1.4 Update
// 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
boolean update(Wrapper<T> updateWrapper);
// 根据 whereWrapper 条件,更新记录
boolean update(T updateEntity, Wrapper<T> whereWrapper);
// 根据 ID 选择修改
boolean updateById(T entity);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);
类型 | 参数名 | 描述 |
---|---|---|
Wrapper | updateWrapper | 实体对象封装操作类 UpdateWrapper |
T | entity | 实体对象 |
Collection | entityList | 实体对象集合 |
int | batchSize | 更新批次数量 |
2.1.1.5 Get
// 根据 ID 查询
T getById(Serializable id);
// 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根据 Wrapper,查询一条记录
Map<String, Object> getMap(Wrapper<T> queryWrapper);
// 根据 Wrapper,查询一条记录
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
类型 | 参数名 | 描述 |
---|---|---|
Serializable | id | 主键 ID |
Wrapper | queryWrapper | 实体对象封装操作类 QueryWrapper |
boolean | throwEx | 有多个 result 是否抛出异常 |
T | entity | 实体对象 |
Function super Object, V> | mapper | 转换函数 |
2.1.1.6 list
// 查询所有
List<T> list();
// 查询列表
List<T> list(Wrapper<T> queryWrapper);
// 查询(根据ID 批量查询)
Collection<T> listByIds(Collection<? extends Serializable> idList);
// 查询(根据 columnMap 条件)
Collection<T> listByMap(Map<String, Object> columnMap);
// 查询所有列表
List<Map<String, Object>> listMaps();
// 查询列表
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// 查询全部记录
List<Object> listObjs();
// 查询全部记录
<V> List<V> listObjs(Function<? super Object, V> mapper);
// 根据 Wrapper 条件,查询全部记录
List<Object> listObjs(Wrapper<T> queryWrapper);
// 根据 Wrapper 条件,查询全部记录
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
类型 | 参数名 | 描述 |
---|---|---|
Wrapper | queryWrapper | 实体对象封装操作类 QueryWrapper |
Collection extends Serializable> | idList | 主键 ID 列表 |
Map |
columnMap | 表字段 map 对象 |
Function super Object, V> | mapper | 转换函数 |
2.1.1.7 Page
// 无条件分页查询
IPage page(IPage page);
// 条件分页查询
IPage page(IPage page, Wrapper queryWrapper);
// 无条件分页查询
IPage
类型 | 参数名 | 描述 |
---|---|---|
IPage | page | 翻页对象 |
Wrapper | queryWrapper | 实体对象封装操作类 QueryWrapper |
2.1.1.8 Count
// 查询总记录数
int count();
// 根据 Wrapper 条件,查询总记录数
int count(Wrapper queryWrapper);
2.1.1.9 Chain
query
// 链式查询 普通
QueryChainWrapper<T> query();
// 链式查询 lambda 式。注意:不支持 Kotlin
LambdaQueryChainWrapper<T> lambdaQuery();
// 示例:
query().eq("column", value).one();
lambdaQuery().eq(Entity::getId, value).list();
update
// 链式更改 普通
UpdateChainWrapper<T> update();
// 链式更改 lambda 式。注意:不支持 Kotlin
LambdaUpdateChainWrapper<T> lambdaUpdate();
// 示例:
update().eq("column", value).remove();
lambdaUpdate().eq(Entity::getId, value).update(entity);
2.1.2 Mapper CRUD 接口
说明:
- 通用 CRUD 封装BaseMapper (opens new window)接口,为
Mybatis-Plus
启动时自动解析实体表关系映射转换为Mybatis
内部对象注入容器- 泛型
T
为任意实体对象- 参数
Serializable
为任意类型主键Mybatis-Plus