Mybatis-Plus扩展

7 MybatisX插件[扩展]

7.1 MybatisX插件介绍

MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。

安装方法:打开 IDEA,进入 File -> Settings -> Plugins -> Browse Repositories,输入 mybatisx 搜索并安装。

功能:

  • Java 与 XML 调回跳转
  • Mapper 方法自动生成 XML

在这里插入图片描述

7.2 基于MybatisX实现逆向工程

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

8.逻辑删除[扩展]

实际在删除数据时,为了数据留痕,一般选择逻辑删除,也就是为删除表添加逻辑删除字段,通过修改字段状态值来表示数据是否被删除;

在这里插入图片描述

案例:

为tb_user添加逻辑删除字段:

在这里插入图片描述

mp配置:

# 设置mp运行时行为
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 控制台输出sql
  global-config:
    db-config:
      logic-delete-field: deleted # 约定全局删除字段
      logic-delete-value: 1
      logic-not-delete-value: 0

调整实体类:

@Data
@NoArgsConstructor//主要用于mybatis底层反射构建user实体类对象
@AllArgsConstructor//主要是lombok基于构建者模式构建对象
@Builder
/**
 * 如果变的名称与实体类名称一致,该注解可省略
 */
@TableName("tb_user")
public class User {
	//......
    @TableLogic//指定逻辑删除字段
    private Integer deleted;
}

测试

    @Test
    public void testDelete(){
        //根据id删除
        int count = userMapper.deleteById(15l);
        System.out.println(count);
    }  

输出的效果:

在这里插入图片描述

但是对应的查询如果不加添加,则删除的无法查询到:

    @Test
    public void testGetById(){
        User user = userMapper.selectById(15l);
        System.out.println(user);
    }

效果:

在这里插入图片描述

逻辑删除本质就是拦截sql,动态追加sql片段

​ 查询 deleted=0

​ 删除: 将sql转化成update操作;

9.乐观锁[扩展]

乐观锁就是当前操作者认为在自己操作资源的过程中,其他人操作相同资源的可能性极低,所以无需加锁,而是通过设置一个版本号来加以约束;

悲观锁:排它锁,比如synchronized关键字就是悲观锁,当前线程做操作时,不允许其它线程做操作;

乐观锁:当前线程做操作时,允许其它线程做操作,但是如果其它线程做了操作,则当前操作失败;

乐观锁在数据库中有什么优势?

​ 避免长事务场景锁定数据资源,导致其它线程操作该资源时阻塞,如果阻塞过多,那么导致数据库连接资源耗尽,进而数据库宕机了;

​ 本质上就是在操作前,先获取操作行的version版本号,然后再做前天操作,然后最后再更新这一行,更新时,给sql条件一个判断版本号的sql片段: select version,xxx from user where id=100; version=30 --> 做其他操作(20s);—> update user set xxx,version=version+1 where xxxx and version=30;

使用场景:

​ 1.业务操作周期长,如果业务整个加入事务,导致数据库资源锁定周期过长,性能降低;

​ 2.如果资源争抢过于激烈,会导致失败重试次数过多,导致性能降低;

示例:

在这里插入图片描述

实体类配置:

@Data
@NoArgsConstructor//主要用于mybatis底层反射构建user实体类对象
@AllArgsConstructor//主要是lombok基于构建者模式构建对象
@Builder
/**
 * 如果变的名称与实体类名称一致,该注解可省略
 */
@TableName("tb_user")
public class User {
	//......
    @Version
    private Integer version;
}

配置乐观锁拦截器:

    /**
     * 注册插件
     * @return
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        //构建mp的插件注册器bean,通过该bean可批量注册多个插件
        MybatisPlusInterceptor plusInterceptor = new MybatisPlusInterceptor();
        //配置乐观锁拦截器
        OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor = new OptimisticLockerInnerInterceptor();
        //注册
        plusInterceptor.addInnerInterceptor(optimisticLockerInnerInterceptor);
        return plusInterceptor;
    }

测试:

    /**
     * @Description 测试乐观锁
     */
    @Test
    public void testOp(){
        User user = userMapper.selectById(5l);
        System.out.println(user);
        user.setName("zws777");
        userMapper.updateById(user);
    }

使用mp的乐观锁,需要先自己根据主键id查询用户信息,信息中包含了此时的version数据,然后再更新,更新时会将查询的version值作为更新条件取更新;

效果:

在这里插入图片描述

在这里插入图片描述

typora-copy-images-to: imgs


10.MP字段自动填充

10.1 背景说明

在这里插入图片描述

说明:

实际开发中有些字段存在大量的重复操作,比如create_time update_time等,需要经常在实体类中设置new Date(),比较繁琐,可以借助MP的自动填充功能

10.2 定义实体类

@TableName("tb_user")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
	//指定插入时自动填充的字段
    @TableField(value = "create_time",fill = FieldFill.INSERT)
    private Date createTime;
  	//自定插入或者更新时自动填充的字段
    @TableField(value = "update_time",fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
}

10.3 配置填充规则

package com.itheima.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * @author by itheima
 * @Date 2022/8/12
 * @Description
 */
@Component
public class FillDataHandler implements MetaObjectHandler {

    /**
     * 定义自动填充的方法
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        //设置insert操作时的时间点
        metaObject.setValue("createTime",new Date());
        //设置update操作时的时间点
        metaObject.setValue("updateTime",new Date());
    }

    /**
     * 定义更新时填充的方法
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        //设置update操作时的时间点
        metaObject.setValue("updateTime",new Date());
    }
}

10.4 测试

更新测试:

    /**
     * @Description 根据主键id更新用户信息(开发最常用)
     */
    @Test
    public void test04(){
        long id=12l;
        //把主键信息和要更新的信息封装到实体类中,设置什么值,就更新什么值,为null的属性,不做处理
        User user = User.builder().id(id).userName("张三丰2").age(120).build();
        //UPDATE tb_user SET real_name=?, age=? WHERE id=?
        //如何获取real_name字段的? user--->User.class--->通过反射获取userName Field字段对象---》
        // 获取字段上的注解对象----》value值就可获取--》real_name
        int count = userMapper.updateById(user);
        System.out.println(count);
    }

插入测试:

    /**
     * @Description 测试插入
     */
    @Test
    public void test02(){
        User user =
                User.builder()
                        .userName("itheima4")
                        .name("itcast4")
                        .age(14)
                        .email("itcast@itcast4.cn")
                        .password("44444")
                        .build();
        //插入数据
        int count = userMapper.insert(user);
        System.out.println("受影响行数:"+count);
    }
  • 25
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值