目录
1.MyBatis-Plus介绍
(1)简介
(2)特性
(3)结构
(4)支持数据库
2.快速开始
3.安装与配置
4.代码生成
5.综合案例
(1)主键生成策略
(3)自动填充
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis
的基础上只做增强不做改变,为简化开发、提高效率而生。它提供了一些常用功能的增强,使得开发者可以更加便捷地进行数据库访问操作。
我们的愿景是成为
MyBatis
最好的搭档,就像魂斗罗中的1P
、2P
,基友搭配,效率翻倍。
CRUD操作的增强:Mybatis-Plus
通过提供通用的Mapper接口和封装的CRUD方法,简化了数据库的增删改查操作。开发者可以通过继承通用Mapper接口,无需编写SQL语句,就能完成基本的CRUD操作。
条件构造器:Mybatis-Plus
提供了强大的条件构造器,使得构建复杂的查询条件变得更加灵活和易于维护。条件构造器支持链式调用,可以根据需求动态添加查询条件,包括等值条件、范围条件、模糊查询等。
自动分页:Mybatis-Plus
可以自动处理分页查询,开发者只需要在查询方法中添加分页参数,即可实现数据的分页查询。它支持多种数据库的分页方式,如MySQL
的LIMIT语句、Oracle的ROWNUM
等。
代码生成器:Mybatis-Plus
提供了一个代码生成器,可以根据数据库表结构自动生成实体类、Mapper接口、XML映射文件等基本代码。开发者可以通过简单的配置,快速生成大量的基础代码,减少了手写重复代码的工作量。
全局通用操作:Mybatis-Plus
还提供了一些全局通用操作的增强,如逻辑删除、字段自动填充、乐观锁等。这些功能可以通过注解或配置进行开启,并且可以自定义实现,以满足不同业务场景的需求。
总的来说,Mybatis-Plus
简化了Mybatis
的开发流程,提高了开发效率。它提供了一些常用功能的增强,使得开发者无需编写繁琐的SQL语句,即可完成常见的数据库操作。同时,它也提供了一些附加功能,如条件构造器、自动分页、代码生成器等,进一步提升了开发效率和代码质量。
核心模块(Core Module):核心模块包含了Mybatis-Plus的核心功能和基本组件。它提供了通用的Mapper接口、通用的CRUD方法的实现、条件构造器、分页插件等核心功能的实现。核心模块是整个框架的基础,其他模块都依赖于它。
代码生成器(Code Generator):代码生成器是一个可选的辅助工具,用于根据数据库表结构自动生成实体类、Mapper接口、XML映射文件等基础代码。通过代码生成器,开发者可以快速生成基础代码,减少手写重复代码的工作量。
扩展模块(Extension Module):扩展模块是Mybatis-Plus提供的一些扩展功能和增强组件的集合。它包括了一些常用的增强功能,如逻辑删除、字段自动填充、乐观锁等。开发者可以通过引入扩展模块,轻松地增加这些功能的支持。
注解(annotation):用于对实体类、Mapper接口以及SQL语句进行配置和标记。通过使用注解,可以简化配置文件的编写,提高代码的可读性和可维护性。
MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb,informix,TDengine,redshift
达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库,优炫数据库
使用Spring Initializer快速初始化一个 Spring Boot 工程(工程将以 MySQL 作为默认数据库)
添加依赖:
org.springframework.boot
spring-boot-starter-freemarker
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
com.baomidou
mybatis-plus-boot-starter
3.5.2
com.baomidou
mybatis-plus-generator
3.5.2
mysql
mysql-connector-java
5.1.44
在 application.yml
配置文件中添加 MySQL
数据库的相关配置:
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 1234
url: jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8&useSSL=false
mybatis-plus:
# Mybatis Mapper所对应的XML位置
mapper-locations: classpath:mapper/*.xml
# 别名包扫描路径
type-aliases-package: com.cqy.spbootmp.model
# 是否开启自动驼峰命名规则(camel case)映射
configuration:
map-underscore-to-camel-case: true
logging:
level:
com.cqy.spbootmp.mapper: debug
在 Spring Boot 启动类中添加 @MapperScan
注解,扫描 Mapper 文件夹:
@MapperScan({"com.cqy.spbootmp.mapper"})
@SpringBootApplication
public class SpbootMpApplication {
public static void main(String[] args) {
SpringApplication.run(SpbootMpApplication.class, args);
}
}
导入代码生成类
package com.zking.dsxm.config;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import lombok.extern.slf4j.Slf4j;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@Slf4j
public class MySQLGenerator {
private final static String URL = "jdbc:mysql://localhost:3306/good";//数据库表名
private final static String USERNAME = "root";//数据库名称
private final static String PASSWORD = "4502";//数据库密码
private final static DataSourceConfig.Builder DATA_SOURCE_CONFIG =
new DataSourceConfig.Builder(URL, USERNAME, PASSWORD);
public static void main(String[] args) {
FastAutoGenerator.create(DATA_SOURCE_CONFIG)
.globalConfig(
(scanner, builder) ->
builder.author(scanner.apply("请输入作者名称?"))
.outputDir(System.getProperty("user.dir") + "\\src\\main\\java")
.commentDate("yyyy-MM-dd")
.dateType(DateType.TIME_PACK)
)
.packageConfig((builder) ->
builder.parent("com.cqy.spbootmp")//项目名称
.entity("pojo")
.service("service")
.serviceImpl("service.impl")
.mapper("mapper")
.xml("mapper.xml")
.pathInfo(Collections.singletonMap(OutputFile.xml, System.getProperty("user.dir") + "\\src\\main\\resources\\mapper"))
)
.injectionConfig((builder) ->
builder.beforeOutputFile(
(a, b) -> log.warn("tableInfo: " + a.getEntityName())
)
)
.strategyConfig((scanner, builder) ->
builder.addInclude(getTables(scanner.apply("请输入表名,多个英文逗号分隔?所有输入 all")))
.addTablePrefix("tb_", "t_", "lay_", "meeting_", "sys_")
.entityBuilder()
.enableChainModel()
.enableLombok()
.enableTableFieldAnnotation()
.controllerBuilder()
.enableRestStyle()
.enableHyphenStyle()
.build()
)
.templateEngine(new FreemarkerTemplateEngine())
.execute();
}
protected static List getTables(String tables) {
return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
}
}
@TableId
主键注解,放置于实体类中的主键字段上。
@Getter
@Setter
@TableName("t_book")
public class Book implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 书本编号
*/
@TableId("bookid")
private String bookid;
}
@TableId注解属性
属性 | 类型 | 必须指定 | 默认值 | 描述 |
---|---|---|---|---|
value | String | 否 | "" | 主键字段名 |
type | Enum | 否 | IdType.NONE | 指定主键类型 |
@TableId注解type属性IdType
主键生成策略介绍:
值 | 描述 |
---|---|
AUTO | 数据库 ID 自增 |
NONE | 无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT) |
INPUT | insert 前自行 set 主键值 |
ASSIGN_ID | 分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator 的方法nextId (默认实现类为DefaultIdentifierGenerator 雪花算法) |
ASSIGN_UUID | 分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator 的方法nextUUID (默认 default 方法) |
@TableField字段注解(非主键),其中fill字段自动填充策略,具体策略如下:
值 | 描述 |
---|---|
DEFAULT | 默认不处理 |
INSERT | 插入时填充字段 |
UPDATE | 更新时填充字段 |
INSERT_UPDATE | 插入和更新时填充字段 |
注解则是指定该属性在对应情况下必有值,如果无值则入库会是null
。
自定义实现类 MyMetaObjectHandler
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("开始新增操作自动填充 ....");
this.strictInsertFill(metaObject, "createdate", LocalDateTime.class, LocalDateTime.now());
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("开始更新操作自动填充 ....");
this.strictUpdateFill(metaObject, "createdate", LocalDateTime.class, LocalDateTime.now());
}
}
情况一:fill = FieldFill.DEFAULT,无论是新增和更新都不进行自动填充;
情况二:fill = FieldFill.INSERT,执行新增操作自动填充数据;
情况三:fill = FieldFill.UPDATE,执行更新操作,若字段不为空则自动填充数据;再次执行更新操作不会刷新数据。