创建数据库
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, '[email protected]'),
(2, 'Jack', 20, '[email protected]'),
(3, 'Tom', 28, '[email protected]'),
(4, 'Sandy', 21, '[email protected]'),
(5, 'Billie', 24, '[email protected]');
初始化项目
添加依赖(数据库依赖看自己的数据库来导入)
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>最新版本version>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plusartifactId>
<version>3.5.3.1version>
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
在插入语句中,实体类id自动回填,并且id为全局唯一id
public void test() {
User user = new user();
user.setName("zhong");
user.setAge(3);
user.setEmail("[email protected]");
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字符串表示
mp中根据你实体类中传入的参数实现了,sql的动态拼接
public void test() {
User user = new user();
user.setId(1122);
user.setName("zhong");
user.setAge(3);
user.setEmail("[email protected]");
int i = userMapper.updateById(user);
}
只需要数据库中存在该字段即可,不需要设置默认值
在实体类中创建和修改事件上增加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
默认为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>p6spygroupId>
<artifactId>p6spyartifactId>
<version>3.9.1version>
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);
}
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.baomidougroupId>
<artifactId>mybatis-plus-generatorartifactId>
<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;
/**
*
* 快速生成
*
*
* @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)