Day01(06.01)
springboot版本2.2.1
mybatis_plus版本3.0.5
添加依赖中lombok是简化实体类的,在写代码时,get、set方法只需加一个注解就可以
@MapperScan注解:扫描找到mapper接口对应类的内容
@Data注解,不用写get、set方法
步骤:1、引入依赖(包括lombok,mybatis_plus等)2、创建实体类User(使用@Data注解)3、创建UserMapper接口,继承BaseMapper4、在启动类Mpdemo0601Application里添加注解@MapperScan,使其能够扫描到mapper接口
mp实现添加
不需要设置ID值(主键),mp自动生成ID值(19位ID值)
public void addUser(){//添加操作
User user=new User();
user.setName("lucy");
user.setAge(26);
user.setEmail("lucy@qq.com");
int insert= userMapper.insert(user);
System.out.println("insert:"+insert);
}
mp实现修改
public void updateUser() {//修改操作
User user=new User();
user.setId(2l);
user.setAge(120);
int row =userMapper.updateById(user);
System.out.println(row);
}
mp实现简单查询
-
根据ID查询
//根据ID查询数据 User user=userMapper.selectById(1400282348479639554l);
-
通过多个ID批量查询
//多个ID批量查询 @Test public void testSelectDemo1() { List<User> users = userMapper.selectBatchIds(Arrays.asList(1l, 2l, 3l)); System.out.println(users); }
mp实现分页查询
-
配置分页插件
//分页插件 @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); }
-
编写分页代码
直接new page对象,传入两个参数:当前页和每页显示记录数
调用mp方法实现分页查询
//分页查询 public void testPage(){ //创建page对象 //传入两个参数: 当前页 和 每页显示记录数 Page<User> page=new Page<>(1,3); //调用mp分页查询方法,过程中,底层封装,会把分页所有数据封装到page对象里面 userMapper.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());//是否有下一页 System.out.println(page.hasPrevious());//是否有上一页 }
mp实现删除
-
物理删除(单条)
直接从数据库中完全删除记录
//物理删除 @Test public void testDeleteById(){ int result=userMapper.deleteById(1l); System.out.println(result); }
-
批量删除(物理删除)
//批量删除 @Test public void testDeleteBatchIds() { int result = userMapper.deleteBatchIds(Arrays.asList(8, 9, 10)); System.out.println(result); }
-
逻辑删除
表中数据还存在,但是查询查不到
-
表添加一个逻辑删除字段,对应实体类中添加一个属性,属性添加注解@TableLogic
@TableLogic private Integer deleted;
-
配置逻辑删除插件
//逻辑删除插件 @Bean public ISqlInjector sqlInjector() { return new LogicSqlInjector(); }
-
application.properties 加入配置
此为默认值,如果你的默认值和mp默认的一样,该配置可无
mybatis-plus.global-config.db-config.logic-delete-value=1 mybatis-plus.global-config.db-config.logic-not-delete-value=0
-
执行删除代码,deleted值变为1
-
mp实现复杂条件查询
使用QueryWrapper构造条件
具体步骤:
- 创建QueryWrapper对象
- 调用方法实现各种条件查询
//mp实现复杂查询操作
@Test
public void testSelectQuery(){
//创建QueryWrapper对象
QueryWrapper<User> wrapper =new 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","lilei");
//between
//查询年龄在20-50之间
wrapper.between("age",20,50);
//like
wrapper.like("name","l");
//orderByDesc
wrapper.orderByDesc("id");
//last 在语句最后拼接SQL语句
wrapper.last("limit 1");
//指定要查询的列
wrapper.select("id","name");
}
主键生成策略
- 自动增长 AUTO INCREMENT
- 缺点:例如在分表操作时,后一张表需要知道前一张表的ID值
- UUID 每次生成随机唯一的值
- 缺点:排序不方便
- Redis生成ID (原子操作实现)
- mp自带策略 (snowflake算法)
在IDEA中如何设置主键生成策略
@TableId(type = IdType.AUTO)
private Long id;
AUTO:自动增长
ID_WORKER:mp自带策略,生成 19 位的ID值,数字类型使用这种策略
ID_WORKER_STR:mp自带策略, 生成 19 为ID值,字符串类型使用这种策略
INPUT:需要自己输入/设置ID值
NONE:无额外操作,也需自己输入ID值
UUID:随机生成唯一ID值
自动填充
不需要set到对象里面值,使用mp方式实现数据添加
-
表添加两个字段
- create_time update_time
- 添加实体类属性
-
具体实现过程
-
在实体类里面进行自动填充属性添加注解@TableField
@TableField(fill= FieldFill.INSERT) private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime;
-
INSERT:插入数据时create_time会有值
INSERT_UPDATE:添加和修改时update_time都会有值
UPDATE:修改时会有值
-
创建类,实现接口MetaObjectHandler,实现接口里面的方法
@Component //将这个类交给Spring管理 public class MyMetaObjectHandler implements MetaObjectHandler { //使用mp实现添加操作,这个方法会执行 @Override public void insertFill(MetaObject metaObject) { this.setFieldValByName("createTime",new Date(),metaObject); this.setFieldValByName("updateTime",new Date(),metaObject); } //使用mp实现修改操作,这个方法会执行 @Override public void updateFill(MetaObject metaObject) { this.setFieldValByName("updateTime",new Date(),metaObject); } }
乐观锁
主要解决丢失更新问题
-
如果不考虑事务隔离性,产生读的问题? 脏读、不可重复读、幻读
-
写的问题:丢失更新(多个人同时修改同一条记录,最后提交的数据会将之前提交过的数据覆盖)
解决方案:悲观锁、乐观锁
- 悲观锁:串行操作,只能一个人操作
- 乐观锁:添加一个版本号,取出记录时,获取当前版本号,当要更新时,比较当前版本号和数据库中版本号是否一样,一样可以提交修改,并将版本号加一,不一样无法提交修改。
-
乐观锁具体实现
-
表添加字段,作为乐观锁版本号
-
对应实体类添加版本号属性
-
在实体类版本号属性添加注解@Version
-
配置乐观锁插件
@Configuration @MapperScan("com.lujin.mpdemo0601.mapper") public class MpConfig { //乐观锁插件 @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); } }
-
测试乐观锁
@Test //测试乐观锁 public void testOptimisticLocker() { //根据ID查询数据 User user=userMapper.selectById(1400282348479639554l); //进行修改 user.setAge(200); userMapper.updateById(user); }
-
性能分析插件
性能分析拦截器,用于输出每条 SQL 语句及其执行时间
参数:maxTime: SQL 执行最大时长,超过自动停止运行,有助于发现问题。
参数:format: SQL是否格式化,默认false。
具体步骤:
-
在 MybatisPlusConfig 中配置
/** * 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; }
-
Spring Boot 中设置dev环境
#环境设置:dev、test、prod spring.profiles.active=dev