mybatis-plus复习 (mybatis-plus的基本使用,与常用的方法)
1.安装依赖
// mybatis-plus 依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
// 代码生成器依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
2.代码生成器
- 使用的时候一定要注意路径是否正确,否则就会生成到其他项目中
public class MyGernerator {
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://127.0.0.1:3306/db0926", "root", "lzq123")
.globalConfig(builder -> {
builder.author("指挥官乄") // 设置作者
.dateType(DateType.ONLY_DATE) // 时间策略
.enableSwagger() // 开启 swagger 模式
.outputDir("D:\\桌面\\日期\\三阶段(下)\\boot\\boot-shiro_\\src\\main\\java"); // 指定输出目录
})
.packageConfig(builder -> {
builder.parent("com.zking") // 设置父包名
.pathInfo(Collections.singletonMap(OutputFile.xml, "D:\\桌面\\日期\\三阶段(下)\\boot\\boot-shiro_\\src\\main\\resources\\mapper")); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
//开启lombok模式
builder.entityBuilder().enableLombok();
// builder.entityBuilder().enableFileOverride(); //覆盖现有文件
// 设置生成表名
builder.addInclude("emp"); // 设置需要生成的表名
})
.execute();
}
}
3.application 配置文件
spring:
datasource:
url: jdbc:mysql:///db0926
username: root
password: lzq123
thymeleaf:
cache: false # 开发阶段关闭缓存,上线之后开启缓存
prefix: classpath:/templates/ # 前缀
suffix: .html # 后缀
mybatis-plus:
type-aliases-package: com.zking.entity # 实体类别名扫描
logging:
level:
com.zking.mapper: debug # 日志文件配置
4.mapper扫描,在任何一个配置类中都可以
package com.zking.config;
@Configuration
@MapperScan("com.zking.mapper") // mapper接口扫描
public class PlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//设置分页插件
PaginationInnerInterceptor pi = new PaginationInnerInterceptor();
pi.setDbType(DbType.MYSQL); // 设置数据库
pi.setOverflow(true); // 分页合理化
interceptor.addInnerInterceptor(pi);
// 乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
5.业务层的CRUD
1. service层的基本使用
- get相关的查询 (查一条数据)
@Autowired
IsongsService songsService;
songsService.getOne('888');
- list 查全部
songsService.list();
- 条件构造器
使用条件构造器的前提,要创建
QueryWrapper qw = new QueryWrapper();
eq : =
nq : !=
gt : >
ge : >=
lt : < 等等,
每个条件构造器都会跟一个函数重载,
eq(R column, Object val)
eq(boolean condition, R column, Object val)
重载函数的第一个参数是判断,如果条件成立,才会进行下一步操作
方便: 可以不用自己去写if,直接放入函数进行判断
between
like,等等贼多,自己看文档,不写了
查询指定的列
qw.select ("id,name");
只有指定的列会有数据
- 分组
QueryWrapper qw = new QueryWrapper();
qw.groupBy('singer_name')
qw.select ("singer_name,count(*) num")
这样就可以分组查询指定的列
- 排序
qw.orderByDesc(hiredate); // 按照日期进行排序
2.添加,save (业务层调用的是mapper层)
- saveOrUpdate方法: 如果没有数据就添加,有数据就修改,参照的是主键
3.删除
删除分为: 直接删除 和 逻辑删除
直接删除,在service方法中调用
逻辑删除,请看 7 点中详细说明
// 根据 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);
6.分页插件的配置
package com.zking.config;
@Configuration
@MapperScan("com.zking.mapper") // mapper接口扫描
public class PlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//设置分页插件
PaginationInnerInterceptor pi = new PaginationInnerInterceptor();
pi.setDbType(DbType.MYSQL); // 设置数据库
pi.setOverflow(true); // 分页合理化
interceptor.addInnerInterceptor(pi);
// 乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
- 使用
// 创建分页对象
Ipage<Songs> page = new Page<>(1,5); // 参数,当前页,一页几条数据
songsService.page(page);
// 高级一点相比autowired
@Resource
IEmpService empService;
@RequestMapping({"find","find/{page}"})
public IPage<Emp> find(@PathVariable(required = false) Integer page){
if(page == null) page =1;
IPage<Emp> iPage = new Page<>(page,5);
return empService.page(iPage);
}
7.逻辑删除
1.步骤:
- 表格中添加del字段,表示逻辑删除
- 实体类中,在del字段上添加@TableLogic 注解
注意:
- 逻辑删除默认是使用 0 ,1 表示,不需要手动配置,如果要修改其他状态表示,需要自行配置,具体看官网说明
public class Songs implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String singerName;
private String album;
private String albumImg;
private String name;
private String releaseDate;
@TableLogic
private Integer del;
}
2.官网说明:
只对自动注入的 sql 起效:
- 插入: 不作限制
- 查找: 追加 where 条件过滤掉已删除数据,如果使用 wrapper.entity 生成的 where 条件也会自动追加该字段
- 更新: 追加 where 条件防止更新到已删除数据,如果使用 wrapper.entity 生成的 where 条件也会自动追加该字段
- 删除: 转变为 更新
3.测试
@Test
public void 逻辑删除() {
boolean b = iSongsService.removeById(1);
System.out.println(b);
}
- 调用同样的删除方法,如果没有添加逻辑删除,该数据已经从数据库中小时,逻辑删除中,数据库的变化,与sql语句变化
- 再次去查询的时候现在该条数据不存在
8、乐观锁的使用
1.步骤
- 在数据库中添加字段v ,并且统一复制,0或1 ,统一版本号
- 在实体类中添加注解 @Version
- 支持的数据类型只有 整数 int Integer Date ,整数 或者 是 日期类型
2.乐观锁的概念
-- 解决多个用户同时修改相同数据库的冲突问题
-- 乐观锁是业务的实现(代码不加锁)
-- 修改时,会根据版本修改,修改成功后版本会加1,如果两个用户同时修改,一个人会修改成功,另一个人必定修改失败,因为修改成功时,版本已经改变了,另一个用户修改时,版本的条件已经不成立
update songs set name = '代码真好敲' ,v=v+1 where id = 1 and v= 1;
3.配置插件
- 在config中配置,之前已经配置了分页插件
@Configuration
@MapperScan("com.zking.mapper") // mapper接口扫描
public class PlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
// 乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
public class Songs implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String singerName;
private String album;
private String albumImg;
private String name;
private String releaseDate;
@TableLogic
private Integer del; // 逻辑删除配置
@Version
private Integer v; // 乐观锁配置
}
4.测试
@Test
public void 乐观锁() {
// 查询到的版本号是一样的
Songs s1 = iSongsService.getById(2);
Songs s2 = iSongsService.getById(2);
// 模拟修改,修改之后版本号会改变,之后s2版本号查不到就会修改失败false
s1.setName("乐观锁测试1");
boolean b1 = iSongsService.updateById(s1);
s2.setName("乐观锁测试2");
boolean b2 = iSongsService.updateById(s2);
System.out.println(b1);
System.out.println(b2);
}
- 结果