Mybatis-Plus 笔记
一、MB-Plus作用
(1) 简介
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生
无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作
二、MB-Plus快速入门
创建表添加测试数据
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)
);
DELETE FROM user;
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');
引入坐标
//mysql
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
//mybatis-plus相关
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
properties配置文件:
mysql5和8区别:
- msyql5驱动 com.mysql.jdbc.Driver
- msyql8驱动 com.mysql.cj.jdbc.Driver
- mysql8 数据库连接url 需添加时区
#mysql
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/my_java?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#日志输出到控制台
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#逻辑删除配置
mybatis-plus.global-config.db-config.logic-delete-field=delete_flg
mybatis-plus.global-config.db-config.logic-delete-value=2
mybatis-plus.global-config.db-config.logic-not-delete-value=1
#当前环境
spring.profiles.active=dev
配置类引入
@Configuration //配置类
@MapperScan({"com.bootcurd.mapper"}) //扫描mapper
public class MybatisPlusConfig {}
Mapper
//继承Mybatis-Plus的BaseMapper 就可以使用父类的基本CRUD方法,已可以自己扩展方法和mybatis操作一样
@Mapper //或者@Repository
public interface UsersMapper extends BaseMapper<Users> {
}
entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Users {
//主键自增
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
//自动填充添加时间
@TableField(fill = FieldFill.INSERT)
private Date createTime;
//自动填充更新时间
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
//乐观锁
@Version
private Integer version;
//逻辑删除
@TableLogic
private Integer deleteFlg;
}
创建测试类
@SpringBootTest
public class MainApplicationTests {
@Autowired
private UsersMapper usersMapper;
@Test
void mybatisPlusTest() {
List<Users> users;
users = usersMapper.selectList(null);
users.forEach(System.out::println);
}
}
entity主键
(2)IdType.AUTO 主键自增 数据库字段要设置自增
(2)IdType.INPUT 手动输入
(2)IdType.NONE 未设置主键 需要手动添加
(2)IdType.ASSIGN_ID 可以在分布式的情况下使用,生成的是Long类型的数字,可以排序性能也高,但是生成的策略和服务器时间有关,如果修改了系统时间就有可能导致出现重复主键
(2)IdType.ASSIGN_UUID 可以在分布式的情况下使用,而且能够保证唯一,但是生成的主键是32位的字符串,长度过长占用空间而且还不能排序,查询性能也慢
自动填充添加 创建and更新时间
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
//注解配置选项
DEFAULT 数据库默认
INSERT 添加是填充
UPDATE 更新时候填充
INSERT_UPDATE 添加更新时填充
//在handler 中编写handler自动填充处理器
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler{
//插入时候填充策略
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ....");
//填充字段,默认值
this.setFieldValByName("createTime",new Date(),metaObject);
}
//更新时候填充策略
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ....");
//填充字段,默认值
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
乐观锁插件
- 数据库增加version字段
alert table users add version int(10) not null default 1 comment '版本号'
- 添加注册mybatis-plus乐观锁插件
@Bean
//mybatis-plus相关插件注册
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//注册乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
- entity 字段增加 version注解
@Version
private Integer version;
- 测试类测试:
//乐观锁成功测试
@Test
void mybatisPlusOptimisticLockerTest() {
//1:先查询
Users user = usersMapper.selectById(8L);
user.setName("rose李");
user.setEmail("test@qq.com");
//2:更新操作
int res = usersMapper.updateById(user);
System.out.println(res);
}
分页查询插件
- 注册mybatis-plus插件:
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//注册乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
//分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
- 分页查询测试
@Test
void pageSelectTest() {
Page<Users> page = new Page<>(4,2);
usersMapper.selectPage(page,null);
System.out.println("总数:" + page.getTotal());
System.out.println("总页数:" + page.getPages());
System.out.println("当前页码:" + page.getCurrent());
System.out.println("记录数:" + page.getSize());
System.out.println("是否有下一页:" + page.hasNext());
System.out.println("是否有上一页:" + page.hasPrevious());
//数据
page.getRecords().forEach(System.out::println);
}
数据逻辑删除
- properties配置
mybatis-plus.global-config.db-config.logic-delete-field=delete_flg
mybatis-plus.global-config.db-config.logic-delete-value=2
mybatis-plus.global-config.db-config.logic-not-delete-value=1
- 数据库增加delete_flg 删除字段
alter table users add delete_flg tinyint(1) not null default 1 comment '是否删除1正常 2已删除';
- entity deleteFlg字段增加逻辑删除注解
//逻辑删除
@TableLogic
private Integer deleteFlg;
- 逻辑删除测试
@Test
void deleteTest() {
usersMapper.deleteById(5L);
usersMapper.deleteBatchIds(Arrays.asList(6,7));
Map<String ,Object> delMap = new HashMap<>();
delMap.put("name","rose李");
usersMapper.deleteByMap(delMap);
}
Wrapper查询demo
详细使用查看官网条件构造器
@Test
void testWrapper() {
//支持链式查询
//between
QueryWrapper<Users> wrapper = new QueryWrapper<>();
wrapper.between("age",10,20);
usersMapper.selectCount(wrapper);
//模糊
QueryWrapper<Users> wrapper1 = new QueryWrapper<>();
wrapper1.notLike("name","a")
.likeRight("name","t")
.likeLeft("name","b")
.orderByAsc("id");
List<Map<String,Object>> mapUsers = usersMapper.selectMaps(wrapper); //返回集合map对象
//查询对象
QueryWrapper<Users> wrapper2 = new QueryWrapper<>();
wrapper2.inSql("id","select id from users where age > 10");
List<Object> objUsers = usersMapper.selectObjs(wrapper2);
}
三、MB-Plus代码生成器
要先创建表
public static void main(String[] args) {
String url = "jdbc:mysql:///test_databases";
String userName = "root";
String passWord = "root";
String parentPackageName = "com";
String moduleName = "bootcurd";
String outputDir = "/Users/apple/data/java/bootCurdDemo/src/main/java";
String mapperXmlPath = "/Users/apple/data/java/bootCurdDemo/src/main/resources/mapper/" + parentPackageName + "/" + moduleName;
String tableName = "x_user,x_role,x_menu,x_user_role,x_role_menu";
//连接数据库的参数
FastAutoGenerator.create(url, userName, passWord)
.globalConfig(builder -> {
//
builder.author("cdd") // 设置作者
// .enableSwagger() // 开启 swagger 模式
// .fileOverride() // 覆盖已生成文件 代码变更会覆盖
.outputDir(outputDir); // 指定输出目录
}).packageConfig(builder -> {
builder.parent(parentPackageName) // 设置父包名
.moduleName(moduleName) // 设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.xml, mapperXmlPath)); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.addInclude(tableName) // 设置需要生成的表名
.addTablePrefix("x_"); // 设置过滤表前缀 不加会生成Xuser
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
.execute();
}