MybatisPlus学习-03-配置日志和CRUD扩展

配置日志

使用mybatisplus后,所有的sql都是不可见的,开发时需要查看,所以需要配置日志
在配置文件application中配置
#配置日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
测试结果

mybaties sql里面会打印日志 如何屏蔽 mybatisplus关闭日志_User

CRUD扩展

insert
@Test
    void testInsert(){
        User user = new User();
        user.setName("gui");
        user.setAge(23);
        user.setEmail("987654321@qq.com");

        int result = userMapper.insert(user);
        System.out.println(result);
        System.out.println(user);
    }

mybaties sql里面会打印日志 如何屏蔽 mybatisplus关闭日志_User_02


数据库插入的id默认值为:全局的唯一id

主键策略
默认ID_WORKER 全局唯一id
分布式系统唯一id生成
雪花算法:
SnowFlake 算法,是 Twitter 开源的分布式 id 生成算法。其核心思想就是:使用一个 64 bit 的 long 型的数字作为全局唯一 id。这 64 个 bit 中,其中 1 个 bit 是不用的,然后用其中的 41 bit 作为毫秒数,用 10 bit 作为工作机器 id,12 bit 作为序列号。
主键自增
我们需要配置主键自增:
    实体类字段上 @TableId(type = IdType.AUTO)
    数据库字段一定是自增的
ID主键设置源码解释
public enum IdType {
    AUTO(0),//ID自增
    NONE(1),//未设置主键
    INPUT(2),//手动输入
    ID_WORKER(3),//默认全局唯一id
    UUID(4),//全局唯一id uuid
    ID_WORKER_STR(5);//ID_WORKER字符串表示法
}
update
@Test
    void testupdate(){
        User user = new User();
        user.setId(5L);
        user.setName("gui");
        user.setAge(23);
        int i = userMapper.updateById(user);
        System.out.println(i);
    }

mybaties sql里面会打印日志 如何屏蔽 mybatisplus关闭日志_乐观锁_03


多次测试后发现,所有的sql都会自动动态配置。

自动填充
创建时间,修改时间!这些个操作一遍都是自动化完成的,不希望手动更新!
阿里巴巴开发手册:所有的数据库表:gmt_create、gmt_modified都要配置,且需要自动化!
方式一:数据库级别
    在表中新增字段 create_time、update_time
方式二:代码级别
    删除数据库默认值,更新操作

mybaties sql里面会打印日志 如何屏蔽 mybatisplus关闭日志_User_04


在实体类字段属性上添加注解

//    字段添加填充内容
    @TableField(fill = FieldFill.INSERT)
    private Date create_time;
    @TableField(fill = FieldFill.UPDATE)
    private Date update_time;
编写处理器来处理这个注解!
@Slf4j//日志
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ...");
        this.setFieldValByName("create_time",new Date(),metaObject);
        this.setFieldValByName("update_time",new Date(),metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ...");
        this.setFieldValByName("update_time",new Date(),metaObject);
    }
}

乐观锁

乐观锁:总是认为不会出现问题,无论干什么都不去上锁
悲观锁:总是认为会出现问题,无论干什么都会上锁

乐观锁的实现方式
    取出记录时,获取当前的version
    更新时,带上version
    执行更新时,set version = newVersion where version = oldVersion
    如果version不对,就更新失败
//乐观锁:1、先查询,获取版本号 version=1
---A
update user set name = "gui", version = version +1
where id = 2 and version = 1
---B 线程B抢先完成,这时 version = 2,会导致 A 修改失败
update user set name = "gui", version = version +1
where id = 2 and version = 1
测试用例
在数据库添加version字段

mybaties sql里面会打印日志 如何屏蔽 mybatisplus关闭日志_字段_05


在实体类添加对应字段

@Version//乐观锁version注解
    private String version;
注册组件:添加MybatisPlusConfig配置类
@MapperScan("com.dui.mapper")
@EnableTransactionManagement
@Configuration
public class MybatisPlusConfig {

    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor(){
        return new OptimisticLockerInterceptor();
    }

}
测试乐观锁
@Test//乐观锁单线程必然成功
    public void testOptimisticLocker(){
        //查询
        User user = userMapper.selectById(1L);
        //修改
        user.setName("gui");
        user.setEmail("123456789@qq.com");
        //执行更新
        userMapper.updateById(user);
    }
    @Test//测试失败,多线程下
    public void testOptimisticLocker2(){
        User user = userMapper.selectById(1L);
        user.setName("gui");
        user.setEmail("123456789@qq.com");

        //模拟另一个线程执行了插队操作
        User user2 = userMapper.selectById(1L);
        user2.setName("gui22222");
        user2.setEmail("22222222@qq.com");
        userMapper.updateById(user2);


        userMapper.updateById(user);//如果没有乐观锁就会覆盖插队的值
    }

分页查询

在MybatisPlusConfig中添加分页插件
@Bean
    public PaginationInterceptor paginationInterceptor(){
        return new PaginationInterceptor();
    }
测试使用:Page对象
@Test
    public void testPage(){
        Page<User> page = new Page<>(1, 5);
        userMapper.selectPage(page,null);
        page.getRecords().forEach(System.out::println);

    }

逻辑删除

物理删除:从数据库中直接移除
逻辑删除:在数据库中没有移除,通过一个变量让他失效
测试用例
在数据库添加deleted字段

mybaties sql里面会打印日志 如何屏蔽 mybatisplus关闭日志_字段_06


在实体类添加对应字段

@TableLogic//逻辑删除
    private Integer deleted;
在MybatisPlusConfig中添加逻辑删除组件
@Bean
    public ISqlInjector sqlInjector(){
        return new LogicSqlInjector();
    }
在配置文件中配置逻辑删除
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
测试使用

mybaties sql里面会打印日志 如何屏蔽 mybatisplus关闭日志_字段_07


本质为update操作,查询时会自动过滤delete字段