0
点赞
收藏
分享

微信扫一扫

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境


简介:大家好,我是枫哥🌟一线互联网的IT民工、📝资深面试官、🌹Java跳蚤网课堂创始人。拥有多年一线研发经验,曾就职过科大讯飞、美团网、平安等公司。在上海有自己小伙伴组建的副业团队,目前业余时间专注Java技术分享,春招/秋招/社招/跳槽,一对一学习辅助,项目接活开发。


目录

​​1.Insert​​

​​1)插入测试​​

​​ 2)主键策略​​

​​ 2.Update​​

​​ 3.自动填充​​

​​ 1)方式一:数据库级别​​

​​2)方式二:代码级别​​

​​ 4.乐观锁​​

​​ 1)修改数据库​​

​​ 2)修改实体类​​

​​ 3)注册乐观锁组件​​

​​ 4)测试​​

​​5.Select​​

​​1)通过id查询单个用户​​

​​ 2)通过id查询多个用户​​

​​ 3)条件查询 通过map封装​​

​​ 4)分页查询​​

​​6.Delete​​

​​1)物理删除​​

​​ 2)逻辑删除​​

 

1.Insert

1)插入测试

@Test
void testInsert(){
User user = new User();
user.setName("tuwer");
user.setAge(8);
user.setEmail("abc@qq.com");
// 会自动生成id
int res = userMapper.insert(user);
System.out.println(res);
System.out.println(user);
}

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_java

 2)主键策略

 

@TableId

描述:主键注解
使用位置:实体类主键字段

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface TableId {

/**
* 字段名(该值可无)
*/
String value() default "";

/**
* 主键类型
* {@link IdType}
*/
IdType type() default IdType.NONE;
}

  •  IdType 枚举类

public enum IdType {
/**
* 数据库ID自增
* <p>该类型请确保数据库设置了 ID自增 否则无效</p>
*/
AUTO(0),
/**
* 该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
*/
NONE(1),
/**
* 用户输入ID
* <p>该类型可以通过自己注册自动填充插件进行填充</p>
*/
INPUT(2),

/* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
/**
* 分配ID (主键类型为number或string),
* 默认实现类 {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(雪花算法)
*
* @since 3.3.0
*/
ASSIGN_ID(3),
/**
* 分配UUID (主键类型为 string)
* 默认实现类 {@link com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator}(UUID.replace("-",""))
*/
ASSIGN_UUID(4);

private final int key;

IdType(int key) {
this.key = key;
}
}

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_spring boot_02

 雪花(snowflake)算法
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心(北京、香港···),5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。

 2.Update

@Test
void testUpdate(){
User user = new User();
user.setId(8L);
user.setName("tuwer测试");
user.setAge(28);
user.setEmail("abc@qq.com");
// 虽然方法是ById,但参数是类对象user
int i = userMapper.updateById(user);
System.out.println(i);
}

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_java_03

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_java_04

 3.自动填充

创建时间、更改时间! 这些操作一般都是自动化完成,不需要手动更新

阿里巴巴开发手册︰几乎所有的表都要配置 gmt_create、gmt_modified !而且需要自动化

 1)方式一:数据库级别

实际开发中不允许修改数据库级别 

  •  修改数据库:添加 ​​gmt_create​​​ 和 ​​gmt_modified​​ 字段

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_数据库_05

alter table user add gmt_create datetime default CURRENT_TIMESTAMP null comment '创建时间';
alter table user add gmt_modified datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP comment '更新时间';

  •  修改实体类

驼峰命名:​​gmtCreate​​​ 对应于数据库中的 ​​gmt_create​

日期类型可以用 ​​Date​​​ 和 ​​LocalDateTime​​​,建议用 ​​LocalDateTime​

private Date gmtCreate;
private LocalDateTime gmtModified;

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_数据库_06

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_java_07

2)方式二:代码级别

  • 删除数据库级别中的操作:默认值、更新
  • 实体类字段属性上增加注解

// 插入时填充
@TableField(fill = FieldFill.INSERT)
private Date gmtCreate;

// 插入、更新时填充
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime gmtModified;

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_java_08

  •  填充处理器

 填充处理器 ​​MyMetaObjectHandler​​​ 在 Spring Boot 中需要声明 ​​@Component​​​ 或 ​​@Bean​​ 注入

@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("开始插入时填充...");
this.strictInsertFill(metaObject, "gmtCreate", Date.class, new Date());
this.strictInsertFill(metaObject, "gmtModified", LocalDateTime.class, LocalDateTime.now());
}

@Override
public void updateFill(MetaObject metaObject) {
log.info("开始插入更新时填充...");
this.strictUpdateFill(metaObject, "gmtModified", LocalDateTime.class, LocalDateTime.now());
}
}

  •  测试

 插入测试

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_数据库_09

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_后端_10

 更新测试

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_java_11

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_User_12

 4.乐观锁

 乐观锁:十分乐观,总是认为不会出现问题;无论干什么都不上锁!如果出现问题,再次更新值测试

悲观锁:十分悲观,总是认为会出现问题;无论干什么都会上锁!再去操作!

 乐观锁实现方式

当要更新一条记录的时候,希望这条记录没有被别人更新

  • 取出记录时,获取当前 version
  • 更新时,带上这个 version
  • 执行更新时, ​​set version = newVersion where version = oldVersion​
  • 如果 version 不对,就更新失败

 1)修改数据库

 添加 ​​version​​ 字段

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_数据库_13

 2)修改实体类

 添加 ​​version​​​ 属性,并添加 ​​@Version​​ 注解

@Version
private Integer version;

 3)注册乐观锁组件

 

@Configuration
@MapperScan("com.tuwer.mapper")
public class MybatisPlusConfig {
/**
* 注册乐观锁组件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mybatisPlusInterceptor;
}
}

 4)测试

  •  单线程

@Test
public void testOptimisticLocker1(){
//1、查询用户信息
User user = userMapper.selectById(8L);
//2、修改用户信息
user.setAge(18);
user.setEmail("111@qq.com");
//3、执行更新操作
userMapper.updateById(user);
}

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_后端_14

 

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_java_15

  •  模拟多线程

 

@Test
public void testOptimisticLocker2(){
// 线程1
User user1 = userMapper.selectById(8L);
user1.setAge(1);
user1.setEmail("222@qq.com");

// 模拟另外一个线程执行了插队操作
User user2 = userMapper.selectById(8L);
user2.setAge(2);
user2.setEmail("333@qq.com");
userMapper.updateById(user2);

// 自旋锁来多次尝试提交!
userMapper.updateById(user1);//如果没有乐观锁就会覆盖插队线程的值
}

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_User_16

5.Select

1)通过id查询单个用户

@Test
public void testSelectById(){
User user = userMapper.selectById(8L);
System.out.println(user);
}

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_后端_17

 2)通过id查询多个用户

@Test
public void testSelectBatchIds(){
List<User> users = userMapper.selectBatchIds(Arrays.asList(1L, 2L, 5L));
users.forEach(System.out::println);
}

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_java_18

 3)条件查询 通过map封装

@Test
public void testSelectByMap() {
HashMap<String, Object> map = new HashMap<>();
map.put("name", "tuwer");
map.put("age", 2);

List<User> users = userMapper.selectByMap(map);
}

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_数据库_19

 4)分页查询

  •  selectPage()

// 参数1:IPage对象
// 参数2:Wrapper 条件构造器
// 返回:IPage对象;把结果封装进参数1的IPage对象
<P extends IPage<T>> P selectPage(P page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

  •  Page 类

public class Page<T> implements IPage<T> {

// ...

/**
* 每页显示条数,默认 10
*/
protected long size = 10;

/**
* 当前页
*/
protected long current = 1;

// ...
}

  •  构造器

 

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_后端_20

  •  注册分页拦截器

/**
* 注册组件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
// 乐观锁 ...
// 分页
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return mybatisPlusInterceptor;
}

 查询

 

@Test
public void testSelectPage(){
// 按Page默认值查询
Page<User> page = new Page<>();
userMapper.selectPage(page, null);

page.getRecords().forEach(System.out::println);
}

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_User_21

@Test
public void testSelectPage(){
// 查第2页,3条记录
Page<User> page = new Page<>(2,3);
userMapper.selectPage(page, null);

page.getRecords().forEach(System.out::println);
}

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_数据库_22

6.Delete

1)物理删除

从数据库中直接删除

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_后端_23

 2)逻辑删除

  • 在数据库中没有被删除,而是通过一个变量来使它失效! deleted=0 ==> deleted=1
  • 逻辑删除是为了 方便数据恢复 和 保护数据本身价值 等等的一种方案,但实际就是删除
  • 删除: 转变为 更新
  •  修改数据库:增加 ​​deleted​​ 字段

alter table user add deleted tinyint default 0 not null comment '逻辑删除';

  •  配置

mybatis-plus:
global-config:
db-config:
#logic-delete-field: deleted # 逻辑删除的实体字段名(配置后可以忽略不配置实体类)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

  •  修改实体类:增加 ​​deleted​​​ 属性,并添加 ​​@TableLogic​​ 注解

@TableLogic // 如果配置了logic-delete-field: deleted,此处可以省略 @TableLogic
private Integer deleted;

 删除

@Test
public void testDelete(){
userMapper.deleteById(8L);
}

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_java_24

 配置​​logic-delete-field: deleted​​​,省略 ​​@TableLogic​

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_spring boot_25

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_后端_26

  •  删除后再查询 

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_spring boot_27

 

MyBatisplus3.12.CRUD扩展:自动填充。乐观锁。分页查询。逻辑删除SpringBoot环境_后端_28


举报

相关推荐

03Mybatis-Plus自动填充和乐观锁

0 条评论