MyBatis-plus的功能

目录

1、主键自增

1.1、id自增策略

1.2、id主键自增不连续

2、自动填充数据功能

代码级别

1)使用注解@TableField

2)数据库中新增字段

3)自定义实现类处理注解

3)测试

数据库级别

3、代码生成器

方式一:下插件

方式二:写代码

4、逻辑删除

1)数据库中添加字段

2)实体类上加注解

3)配置文件

4)测试

4、条件构造器

5、乐观锁

5.1、实现方式:

5.2、实现步骤

5.3、测试乐观锁


mybatis-plus官方文档

1、主键自增

1.1、id自增策略 

 
@TableId(type = IdType.AUTO)
     private Integer id;

从源码中可以看到,除了AUTO这个策略以外,还有如下几种生成策略:

  • NONE: 不设置id生成策略

  • INPUT:用户手工输入id

  • ASSIGN_ID:雪花算法生成id(可兼容数值型与字符串型)

  • ASSIGN_UUID:以UUID生成算法作为id生成策略

其他的几个策略均已过时,都将被ASSIGN_ID和ASSIGN_UUID代替掉。

1.2、id主键自增不连续

在使用idea删除数据时,id自增会自动从删除的id号向上加1,导致不连续

执行语句:

1)若删完数据后还未新增,

 
# 缺点:每次删完数据,想再插入一条数据前,都要
 ALTER TABLE user3 AUTO_INCREMENT=1;

2)若表中已出现不连贯的数据ID,

 
set @auto_id=0;
 update 表名 set 自增字段名 = (@auto_id :=@auto_id+1);
 ALTER TABLE user3 AUTO_INCREMENT=1;

2.1)先使用truncate来删除表数据

 truncate table 表名 

2.2)执行语句

 ALTER TABLE 表名 AUTO_INCREMENT=1;

2、自动填充数据功能

当数据进行添加或修改时,自动为字段填充数据,常用业务中有些属性需要配置默认值,

比如创建时间、修改时间,这些操作都是自动化完成的,不需要手动去更新

添加或修改数据时每次都需要使用相同的方式进行填充

MP支持自动填充这些字段的数据

方法:

数据库级别 代码级别

代码级别

1)使用注解@TableField

标注需要进行填充的字段updateTime/createTime

实体类中修改

 @TableField(fill = FieldFill.INSERT,value = "createTime")
 private Date createTime;
 @TableField(fill = FieldFill.INSERT_UPDATE,value = "updateTime")
 private Date updateTime;

2)数据库中新增字段

createTime和updateTime

3)自定义实现类处理注解

 
import java.util.Date;
 @Slf4j
 @Component
 public class MyMetaObjectHandler implements MetaObjectHandler {
     public void insertFill(MetaObject metaObject) {
         this.setFieldValByName("create_time",new Date(),metaObject);
         this.setFieldValByName("update_time",new Date(),metaObject);
     }
 ​
     public void updateFill(MetaObject metaObject) {
         this.setFieldValByName("update_time",new Date(),metaObject);
     }
 }

3)测试

 
@Test
     void test01(){
         Users users=new Users();
         users.setName("ss");
         users.setAge(1);
         users.setCreateTime(new Date());
         users.setUpdateTime(new Date());
         int row=userMapper.updateById(users);
         System.out.println(row);
     }

结果:

 

字段更新成功,数据自动填充

数据库级别

删除注解

不需要处理类

勾选图中的部分

 

 

3、代码生成器

方式一:下插件

EasyCode是一个代码生成插件用于自动生成Entity\controller、Service

功能:

  • 支持多表同时操作

  • 支持同时生成多个模板

  • 支持自定义模板

  • 支持自定义类型映射

  • 支持自定义附加列

  • 支持列附加属性

方式二:写代码

1、pom.xml文件下导包

 
<!--代码生成器-->
 <dependency>
     <groupId>com.baomidou</groupId>
     <artifactId>mybatis-plus-generator</artifactId>
     <version>3.4.1</version>
 </dependency>
 <!--velocity模板引擎-->
 <dependency>
     <groupId>org.apache.velocity</groupId>
     <artifactId>velocity-engine-core</artifactId>
     <version>2.3</version>
 </dependency>

2、编写配置类添加乐观锁拦截器

 @SpringBootApplication
 public class Mybatisplus04GeneratorApplication {
     public static void main(String[] args) {
         SpringApplication.run(Mybatisplus04GeneratorApplication.class, args);
     }
 }

3、创建代码生成器类

 public class CodeGenerator {
     public static void main(String[] args) {
         //1.获取代码生成器的对象
         AutoGenerator autoGenerator = new AutoGenerator();
         //设置数据库相关配置
         DataSourceConfig dataSource = new DataSourceConfig();
         dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
         //设置全局配置
         GlobalConfig globalConfig = new GlobalConfig();
         //设置包名相关配置
         PackageConfig packageInfo = new PackageConfig();
         packageInfo.setParent("com.aaa"); //设置生成的包名,与代码所在位置不冲突
         packageInfo.setEntity("domain"); //设置实体类包名
         packageInfo.setMapper("dao"); //设置数据层包名
         autoGenerator.setPackageInfo(packageInfo);
         //执行代码生成操作
         autoGenerator.execute();
     }   

4、逻辑删除

普通的增删改查这里就不演示了

删除操作分为两种:

物理删除:数据库中直接删除

逻辑删除:在数据库中没有被删除而是通过一个变量使它失效

delete=0

1)数据库中添加字段

默认值为0,表示没有被删除

2)实体类上加注解

 
//逻辑删除
     @TableLogic
     private Integer deleted;

3)配置文件

 # 配置逻辑删除
 # 全局逻辑删除的实体字段名
 mybatis-plus.global-config.db-config.logic-delete-field=flag
 # 逻辑已删除默认为1
 mybatis-plus.global-config.db-config.logic-delete-value=1
 # 逻辑未删除值默认为0
 mybatis-plus.global-config.db-config.logic-not-delete-value=0

4)测试

@Test
     void delete(){
         int a = userMapper.deleteById(0);
         System.out.println(a);
     }

结果:

4、条件构造器

MyBatis-Plus自带的四种lambda条件构造器

1、new LambdaQueryWrapper<>()

LambdaQueryWrapper<User> lambda=new LambdaQueryWrapper<>();
 lambda.eq(user::getUsername,username);
 User user=userMapper.select--(lambda);

2、new QueryWrapper<实体类>().lambda()

 
LambdaQueryWrapper<user> lambda=new QueryWrapper<User>().lambda();
 lambda.eq(User::getUsername,username);
 User user=userMapper.select--(lambda);

3、Wrappers.<User>lambdaQuery()

LambdaQueryWrapper<user> lambda=Wrappers.<User>lambdaQuery();
 lambda.eq(User::getUsername,username);
 User user=userMapper.select--(lambda);

5、乐观锁

业务并发现象带来的问题:秒杀

假如有100个商品或者票在出售,为了能保证每个商品或者票只能被一个人购买,如何保证不会出

现超买或者重复卖

对于这一类问题,其实有很多的解决方案可以使用

第一个最先想到的就是锁,锁在一台服务器中是可以解决的,但是如果在多台服务器下锁就没有办

法控制,比如12306有两台服务器在进行卖票,在两台服务器上都添加锁的话,那也有可能会导致

在同一时刻有两个线程在进行卖票,还是会出现并发问题

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

操作数据的时候不会对数据进行枷锁(可使多个任务可以并行对数据操作),只有在提交的时候才通过机制来验证数据是否存在冲突

5.1、实现方式:

取出记录时,获取当前version

更新时,带上这个version

执行更新时,set version=newVersion where version=oldVersion

如果version不对就更新失败

5.2、实现步骤

1)数据库添加字段version

2)实体类

 @Version
  private Integer version;

3)配置插件

springboot注解方式

创建配置类

 @Configuration
 @EnableTransactionManagement//自动管理事务,默认开启
 public class MPConfig {
     //注册乐观锁插件
     @Bean
     public MybatisPlusInterceptor mybatisPlusInterceptor(){
         MybatisPlusInterceptor interceptor=new MybatisPlusInterceptor();
         interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
         return interceptor;
     }
 }

5.3、测试乐观锁

1)成功的测试

 
//测试成功的乐观锁
     @Test
     void testLock01(){
         //查询用户
         Users users=userMapper.selectById(4);
         //修改信息
         users.setAge(89);
         users.setName("硝烟");
         //执行更新
         userMapper.updateById(users);
     }

我们传递的是1,MP会将1进行加1,然后,更新回到数据库表中。

所以要想实现乐观锁,首先第一步应该是拿到表中的version,然后拿version当条件在将version

加1更新回到数据库表中,所以我们在查询的时候,需要对其进行查询

 

2)失败的测试

模拟用户抢票

 //测试失败的乐观锁
    
 @Test
     void testLock02(){
         //模拟多线程实现插队
         //线程一
         Users user1=userMapper.selectById(4);
         //修改信息
         user1.setAge(99);
         user1.setName("天使");
         //线程二
         Users user2=userMapper.selectById(4);
         //修改信息
         user2.setAge(23);
         user2.setName("昊天");
         //在这里插队
         userMapper.updateById(user2);
         //如果没有乐观锁,就会覆盖插队线程的值
         userMapper.updateById(user1);
     }

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值