快速开始demo
-
创建数据库
DROP TABLE IF EXISTS user; CREATE TABLE user ( id BIGINT(20) NOT NULL COMMENT '主键ID', name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名', age INT(11) NULL DEFAULT NULL COMMENT '年龄', email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱', PRIMARY KEY (id) ); INSERT INTO user (id, name, age, email) VALUES (1, 'Jone', 18, 'test1@baomidou.com'), (2, 'Jack', 20, 'test2@baomidou.com'), (3, 'Tom', 28, 'test3@baomidou.com'), (4, 'Sandy', 21, 'test4@baomidou.com'), (5, 'Billie', 24, 'test5@baomidou.com');
-
初始化项目
添加依赖(数据库依赖看自己的数据库来导入)
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>最新版本</version> </dependency> <!-- 启动器和普通依赖二选一即可 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>3.5.3.1</version> </dependency>
配置
spring: datasource: username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.driver url: jdbc:mysql://localhost:3306/mybatis_puls?useSSL=falsel&useUnicode=true&characterEncoding=utf-8
传统的mybatis开发需要创建一个实体类;创建mapper接口,创建mapper.xml实现。
myabtis-plus已经帮助我们做好了增删改查,我们需要在接口上继承一个baseMapper,并传递一个需要被操作的对象泛型。添加注解@Repostitory注册到spring容器,添加注解@Mapper被mybatisplus扫描或者在启动类上添加注解@MapperScan()设置扫描路径。
配置日志
使用mybaitsplus在使用的过程中,所有的sql是不可见的,对于开发者来说,这很不好。配置日志的目的就是让sql语句能够被看见
# mybatis-plus 配置
mybatis-plus:
configuration:
# 使用默认配置的控制台输出日志,不需要导入依赖
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
CRUD
insert
在插入语句中,实体类id自动回填,并且id为全局唯一id
public void test() {
User user = new user();
user.setName("zhong");
user.setAge(3);
user.setEmail("222222@qq.com");
int result = userMapper.insert(user);
}
主键生成策略,推特的雪花算法
雪花算法
myabtis-plus中可以使用注解@TableId(type = ?)改变生成主键的策略,默认为IdType.ID_WORKER,也就是生成全局唯一id
主键自增策略
配置:
- 实体类中主键字段配置注解
@Table(type = IdType.AUTO)
- 数据库中字段设置为自增
其他策略
none:不设置策略
input:手动输入id
UUID:全局唯一UUID
ID_WORKER_STR:ID_WORKER字符串表示
update
mp中根据你实体类中传入的参数实现了,sql的动态拼接
public void test() {
User user = new user();
user.setId(1122);
user.setName("zhong");
user.setAge(3);
user.setEmail("222222@qq.com");
int i = userMapper.updateById(user);
}
自动填充
方式一:数据库级别
- 数据中新增字段gmt_create,gmt_modified,并且设置默认值为current_timestamp,更新需要勾选更新选项
方式二:代码级别
-
只需要数据库中存在该字段即可,不需要设置默认值
-
在实体类中创建和修改事件上增加mp中的注解,@TableField(fill = FieldFill.Insert)和@TableField(fill = FieldFill.insert_update)。设置之后会在插入和更新的时候实现自动填充。但是需要我们设置填充的内容
-
编写处理器来处理上面我们加上的两个填充注解,新建处理器
MyMateObjectHandler
,实现MateObjectHandler
。重写insertFill和updateFill方法并且将该类注册为组件@Slf4j @Component public class MyMetaObjectHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { log.info("start insert fill"); this.setFieldValByName("createTime", new Date(), metaObject); this.setFieldValByName("updateTime", new Date(), metaObject); } @Override public void updateFill(MetaObject metaObject) { log.info("start update fill"); this.setFieldValByName("updateTime", new Date(), metaObject); } }
乐观锁
乐观锁:总是认为不会出现问题,无论做什么事情都不会上锁,性能好,如果出现了问题再考虑加锁
悲观锁:总是认为一定会出现问题,无论做什么都会加上锁,性能较低
实现
在mp中乐观锁的实现机制是
- 取出某条记录的时候,获取当前的version
- 更新的时候,带上version值
- 执行更新的时候,set version = newVersion where version = oldVerison
- 如果version不对,更新失败
mp使用乐观锁
-
数据库中增加字段
version
默认为1,实体类中添加字段version
并且使用mp中的注解@Version,该注解表示使用mo中的乐观锁插件 -
注册组件,在config包下新建myabtisPlusConfig类,配置注解@Coniguration,@EnableTransactionManagement开启事务管理,@MapperScan(“com.zhong.mapper”)配置mapper扫描。在传统的myabtis中,在启动类上添加该扫描注解,或者在每个mapper添加@Mapper注解,此时只需要mybatisplus配置类去扫描mapper即可。随后该配置类中,注册bean
@MapperScan("com.zhong.mapper") @EnableTransactionManagement @Coniguration public class myBatisPlusConfig() { @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); } }
-
在每次修改用户信息的时候,都查询一遍version
查询
查询api
.selectBatchIds(Arrays.asList(1,2,3))//按id批量查询
.selectByMap(map);//条件查询
分页查询
mp中内置了分页插件,可以直接使用。需要在myabtisplusconfig中配置分页插件拦截器
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor;
}
测试使用
@Test
public void testPage() {
Page<T> page = new Page<>(1,5);
userMapper.selectPage(page);
page.getRecords();//获取查询到的一页的记录
}
删除
删除api
.deleteById();
.deleteBatchIds(Arrays.asList(1,2,4));
deleteByMap(map);
逻辑删除(软删除)
一般情况下,新增字段deleted,字段为1表示不在查询出来
实体类中增加字段deleted,并加上mp注解@TableLogic表示逻辑删除字段
增加逻辑删除组件
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
配置yml
#配置逻辑删除
mybatis-plus:
global-config:
db-config:
#配置让逻辑删除字段填充的内容
logic-delete-value: 1
logic-not-delete-value: 0
性能分析插件
mp提供了性能分析插件在3.2.0版本后被移除,推荐使用第三方插件
官方插件
设置开发环境
spring:
profiles:
active: dev
添加组件
@Bean
@Profile({"dev", "test"})
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(1);
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
第三方插件的使用(推荐)
使用p6psy替代或者使用druid数据源
依赖
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.9.1</version>
</dependency>
yml配置
spring:
datasource:
driver-class-name: com.p6spy.engine.spy.P6SpyDriver #换成p6spy的驱动
url: jdbc:p6spy:mysql://localhost:3306/yogurt?serverTimezone=Asia/Shanghai #url修改
username: root
password: root
在src/main/resources资源目录下添加配置文件spy.properties
#spy.properties
#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
# 真实JDBC driver , 多个以逗号分割,默认为空。由于上面设置了modulelist, 这里可以不用设置driverlist
#driverlist=com.mysql.cj.jdbc.Driver
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
#若要日志输出到文件, 把上面的appnder注释掉, 或者采用下面的appender, 再添加logfile配置
#不配置appender时, 默认是往文件进行输出的
#appender=com.p6spy.engine.spy.appender.FileLogger
#logfile=log.log
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2
# 执行时间设置, 只有超过这个执行时间的才进行记录, 默认值0, 单位毫秒
executionThreshold=10
条件构造器
简单的使用wrapper
@Test
void contextLoads() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.isNotNull("name")//查询name字段不为空
.isNotNull("email")//查询email字段不为空
.ge("age",12);//查询age字段大于等于12,g是大于e是等于
userMapper.selectList(wrapper).forEach(System.sout::println);
}
api
wrapper.eq("name", "zhong");//查询name字段为zhong的记录
userMapper.selectOne(wrapper);//查询单条记录
wrapper.between("age", 20 ,30);//查询区间
userMapper.selectCount(wrapper);//查询结果数
wrapper.notLike("name", "e");//模糊查询不包含e
.likeRight("email", "t");//模糊查询右匹配
userMapper.selectMaps(wrapper);
wrapper.inSql("id", "select id from user where id <3");//子查询
userMapper.selectObject(wrapper);
代码生成器
mybatis-plus-generator 3.5.1 及其以上版本,对历史版本不兼容!
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>最新版本</version>
</dependency>
FastAutoGenerator.create("url", "username", "password")
.globalConfig(builder -> {
builder.author("baomidou") // 设置作者
.enableSwagger() // 开启 swagger 模式
.fileOverride() // 覆盖已生成文件
.outputDir("D://"); // 指定输出目录
})
.dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
int typeCode = metaInfo.getJdbcType().TYPE_CODE;
if (typeCode == Types.SMALLINT) {
// 自定义类型转换
return DbColumnType.INTEGER;
}
return typeRegistry.getColumnType(metaInfo);
}))
.packageConfig(builder -> {
builder.parent("com.baomidou.mybatisplus.samples.generator") // 设置父包名
.moduleName("system") // 设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.xml, "D://")); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.addInclude("t_simple") // 设置需要生成的表名
.addTablePrefix("t_", "c_"); // 设置过滤表前缀
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
快速生成sample
package com.baomidou.mybatisplus.generator.samples;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.engine.EnjoyTemplateEngine;
import java.sql.SQLException;
/**
* <p>
* 快速生成
* </p>
*
* @author lanjerry
* @since 2021-09-16
*/
public class FastAutoGeneratorTest extends BaseGeneratorTest {
/**
* 数据源配置
*/
private static final DataSourceConfig.Builder DATA_SOURCE_CONFIG = new DataSourceConfig
.Builder("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;CASE_INSENSITIVE_IDENTIFIERS=TRUE;MODE=MYSQL", "sa", "");
/**
* 执行 run
*/
public static void main(String[] args) throws SQLException {
// 初始化数据库脚本
initDataSource(DATA_SOURCE_CONFIG.build());
FastAutoGenerator.create(DATA_SOURCE_CONFIG)
// 数据库配置
.dataSourceConfig((scanner, builder) -> builder.schema(scanner.apply("请输入表名称")))
// 全局配置
.globalConfig((scanner, builder) -> builder.author(scanner.apply("请输入作者名称")))
// 包配置
.packageConfig((scanner, builder) -> builder.parent(scanner.apply("请输入包名")))
// 策略配置
.strategyConfig((scanner, builder) -> builder.addInclude(scanner.apply("请输入表名,多个表名用,隔开")))
/*
模板引擎配置,默认 Velocity 可选模板引擎 Beetl 或 Freemarker 或 Enjoy
.templateEngine(new BeetlTemplateEngine())
.templateEngine(new FreemarkerTemplateEngine())
.templateEngine(new EnjoyTemplateEngine())
*/
.execute();
}
}
更多设置:
代码生成器配置新 | MyBatis-Plus (baomidou.com)