在线教育项目-Day 01
文章目录
本文为b站《尚硅谷_谷粒学院-微服务+全栈在线教育实战项目》的个人学习笔记,仅供学习使用
MybatisPlus实现乐观锁
-
乐观锁:为解决某些问题
主要解决:丢失更新
(悲观锁:串行操作,不管是读操作还是写操作,都不允许别人同时进行任何操作。同时只能有一个人操作。)
-
数据库事务的隔离性
读问题:脏读、不可重复读、幻读
写问题:多人同时修改同一条记录时,丢失更新
-
乐观锁的实现方法:
-
取出记录时,获取当前
version
(设置版本号
字段) -
更新时,带上这个
version
-
执行更新时,
set version = newVersion where version = oldVersion
,同时version
+1 -
如果
version
不对,就更新失败具体实现方法:
-
表中添加字段,作为乐观锁的版本号
-
对应实体类添加版本号属性
-
添加注解
@Version
-
配置乐观锁插件
@Configuration @MapperScan("com.atguigu.mybatisplus.mapper") public class MpConfig { /** * 乐观锁插件 */ @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); } }
此时可以将此前的@MapperScan(原本写在启动类中)移动到新建的类(配置类)中
- 为使version有一个初始值(为1),修改MyMetaObjectHandler类:
this.setFieldValByName("version",1,metaObject);
并采用前述的方法设置自动填充:
@TableField(fill=FieldFill.INSERT) @Version private Integer version;//版本号
- 测试乐观锁
//测试乐观锁.必须先查后改 @Test public void testOptimisticLocker(){ //首先根据id查询数据 User user=userMapper.selectById(1378570252328804353L);//提示整数太大,注意在数值后加L //进行修改 user.setAge(200); userMapper.updateById(user); }
修改后,版本号变为2:
附上随堂笔记:
select 查询
1.简单查询
//根据id查询数据
User user=userMapper.selectById(1378570252328804353L);//提示整数太大,注意在数值后加L
2.通过多个id批量查询
//多个id批量查询
@Test
public void testSelectDemo1(){
List<User> users = userMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L));//注意在id后加”L“
//此处有返回值,故在userMapper方法后使用`.var`传递返回值
System.out.println(users);
3.简单条件查询(略):方法selectByMap
@Test
public void testSelectByMap(){
HashMap<String, Object> map = new HashMap<>();
map.put("name", "Helen");
map.put("age", 18);
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}
4.分页查询
代码写法类似于PageHelper
-
配置分页插件
将插件放入配置类中(也可以放入启动类中,但不推荐)
** * 分页插件 */ @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); }
-
编写分页算法
直接new page 对象,传入两个参数:当前页、每页显示的记录数
测试:最终通过
Page对象
获取相关数据//分页查询 @Test public void testPage(){ //1 创建一个配置对象 //2 传入两个参数:当前页、每页显示的记录数 Page<User> page=new Page<>(1,3); //调用mp分页查询方法 //调用mp分页查询方法的过程中,底层会封装: //把分页所有数据都封装到page对象内 userMapper.sele.selectPage(page,null); //通过page对象获取分页数据 System.out.println(page.getCurrent());//获取分页中的当前页 System.out.println(page.getRecords());//每页数据list集合 System.out.println(page.getSize());//每页显示的记录数 System.out.println(page.getTotal());//总记录数 System.out.println(page.getPages());//总页数 System.out.println(page.hasNext());//哈希next,表示是否有下一页 System.out.println(page.hasPrevious());//哈希Previous,表示是否有前一页 }
delete 删除
-
物理删除
在表中将数据删除
//删除操作 物理删除 @Test public void testDeleteById(){ int result = userMapper.deleteById(1L);//id后面注意加”L“,否则报错 System.out.println(result); }
-
批量删除
实际GUI操作中,勾选多个选项,然后批量删除
@Test public void testDeleteBatchIds() { int result = userMapper.deleteBatchIds(Arrays.asList(8, 9, 10)); System.out.println(result); }
-
简单的条件查询删除(略)
@Test public void testDeleteByMap() { HashMap<String, Object> map = new HashMap<>(); map.put("name", "Helen"); map.put("age", 18); int result = userMapper.deleteByMap(map); System.out.println(result); }
-
逻辑删除
使用标志位
deleted
(此方法使用较多,因为不会真正删除数据,更方便作回收处理)(1)在表中添加deleted字段
此处手动添加了默认值。此处的手动添加,与自动填充,只能使用一个。
(2)在实体类中添加deleted字段
并加上
@TableLogic
注解和@TableField(fill=FieldFill.INSERT)
注解(由于前面手动添加了默认值,故不设置默认填充)@TableLogic //作逻辑删除的注解 private Integer deleted;
(3)配置逻辑删除插件(配置类中)
//逻辑删除插件 @Bean public ISqlInjector sqlInjector() { return new LogicSqlInjector(); }
(4)(可选)在properties文件中作下列配置
主动修改默认值。如不修改,表示与mp默认值相同。(1为删除,0为不删除)
mybatis-plus.global-config.db-config.logic-delete-value=1 mybatis-plus.global-config.db-config.logic-not-delete-value=0
逻辑查询测试结果:
注:findAll操作中,会自动加上
where deleted=0
,对于逻辑删除的数据不显示如果要查询被逻辑删除的数据:mp无法进行操作,只能用最原始的sql语句查询(
where deleted=1
)
MybatisPlus性能分析插件
性能分析拦截器,用于输出每条 SQL 语句及其执行时间
SQL 性能执行分析,开发环境使用,超过指定时间,停止运行。有助于发现问题
(1)在配置类中进行配置
/**
* SQL 执行性能分析插件
* 开发环境使用,线上不推荐。 maxTime 指的是 sql 最大执行时长
*
* 项目开发中的三种环境
* dev:开发环境
* test:测试环境
* prod:生产环境
*/
@Bean
@Profile({"dev","test"})// 设置 dev test 环境开启
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(100);//ms,超过此处设置的ms则sql不执行
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}
performanceInterceptor.setMaxTime(100);//ms,超过此处设置的ms则sql不执行
如果某条语句的执行时间过长,则报错。
(2)Spring Boot 中设置dev环境(在properties文件中设置)
#环境设置:dev、test、prod
spring.profiles.active=dev
附:随堂笔记
MybatisPlus实现复杂条件查询
使用QueryWrapper构建条件:
创建QueryWrapper对象
调用方法实现各种条件查询
//ge、gt、le、lt(大于等于、大于、小于等于、小于)
//查询age>=30的记录
wrapper.ge("age",30);//第一个参数:要查询的字段名称,第二个参数:设置值
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
//eq、ne(等于、不等于)
wrapper.eq("name","kelin1");
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
//between(区间查询)
wrapper.between("age",10,20);
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
//like(模糊查询)
wrapper.like("name","k");
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
//orderByDesc(排序:逆序)
wrapper.orderByDesc("id");
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
//last
//直接拼接到 sql 的最后
//指定要查询的列(区别于select *的查询全部)
wrapper.select("id","name");
List<User> users = userMapper.selectList(wrapper);
System.out.println(users);
附:随堂笔记