MyBatisPlus

一、分页

  1. 配置MybatisPlusInterceptor拦截器,添加分页功能
    @Configuration
    public class MybatisPlusConfig {
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() { //利用MybatisPlus提供的分页
            MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
            mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
            return mybatisPlusInterceptor;
        }
    }
    
  2. 利用IPage的实现类Page实现分页
    Page<Entity> pageInfo = new Page<>(page, pageSize);
    entityService.page(pageInfo, queryWrapper); //利用page方法根据pageInfo和传入的条件进行分页
    
  3. 原理分析
     首先讲分页参数PageNum、PageSize放到ThreadLocal中,拦截执行的SQL,根据数据库类型(如默认为MySql)添加对应的分页语句重写SQL。在分页中主要是先计算count(*)总个数,以及添加limit分页查询,进而得出total总条数、当前页的数据,是否为首页,总页数等信息。

二、映射匹配

  1. @TableField:解决数据库表和实体类字段不匹配
    (1)value属性:设置与实体类属性对应的数据库表字段名称。
    (2)exist属性:设置实体类属性在对应的数据库表字段中是否存在,默认为true,无法与value合并使用。
    (3)select属性:设置实体类属性是否参与查询,默认为true,适用于对密码等核心信息的隐藏(若登录时要验证密码,可以使用查询投影,即使用LambdaQueryWrapper的select方法指定要查询的字段)。
    (4)fill属性:使用方法 fill = FieldFill.UPDATE

    (1) 创建工具类,由于客户端发送的每次HTTP请求,在服务器中都会分配一个线程来处理,因此只需在拦截器里设置id到一个ThreadLocal中,就可以在ControllerMyMetaObjectHandler从中取出对应的值,它们都是处于一个线程中。
    public class BaseContextUtils {
        private static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
        public static void setCurrentId(Long id) {
            threadLocal.set(id);
        }
        public static Long getCurrentId() {
            return threadLocal.get();
        }
    }
    (2) 自定义MetaObjectHandler接口的实现类,重写update和insert后填充的字段
    @Component
    public class MyMetaObjectHandler implements MetaObjectHandler {
        @Override
        public void insertFill(MetaObject metaObject) {
            metaObject.setValue("createTime", LocalDateTime.now());
            metaObject.setValue("updateTime", LocalDateTime.now());
            metaObject.setValue("createUser", BaseContextUtils.getCurrentId()); 
            metaObject.setValue("updateUser", BaseContextUtils.getCurrentId());
        }
    
        @Override
        public void updateFill(MetaObject metaObject) {
            metaObject.setValue("updateTime", LocalDateTime.now());
            metaObject.setValue("updateUser", BaseContextUtils.getCurrentId());
        }
    }
    
  2. @TableName:设置与实体类名对应的数据库表名

三、ID生成策略

  1. @TableId:设置当前实体类中主键属性的生成策略
    (1)value属性:设置与实体类主键属性对应的数据库表的主键名称。
    (2)type属性:设置主键属性的生成策略:
       IdType.AUTO:数据库ID自增,即AUTO_INCREMENT(使用时要开启表的自动递增)
       IdType.NONE:没有设置ID生成策略
       IdType.INPUT:用户输入ID
       IdType.ASSIGN_ID:雪花算法生成ID,兼容主键是数值型与字符串型(只有当插入对象ID为空,才自动填充,下同)

       IdType.ASSIGN_UUID:UUID算法生成ID(不包含-)
  2. 全局配置:
    mybatis-plus:
      configuration:
        map-underscore-to-camel-case: true	# 开启数据库表字段下划线连接与实体类驼峰之间的映射
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl	# 在控制台输出Mybatis-plus日志
      global-config:
        db-config:
          id-type: ASSIGN_ID	# 全局ID生成策略
          table-prefix: tb_ 	# 全局表的公共前缀
    

四、逻辑删除

  1. @TableLogic(value = "0", delval = "1"):value指定逻辑删除字段存在时的默认值,delval指定逻辑删除后的默认值。(设置后,删除操作就编程了更新操作,查询操作都会指定逻辑删除字段为0)
  2. 全局配置
    mybatis-plus:
      global-config:
        db-config:
          logic-delete-field: deleted	# 全局逻辑删除字段名
          logic-not-delete-value: 0		# 全局没有逻辑删除时默认值
          logic-delete-value: 1			# 全局逻辑删除后默认值
    

五、乐观锁

 先查询出要修改的数据,并获取对应的version,执行修改操作,谁先抢到就会先执行修改操作,同时会将version自增1,这样后抢到的就会因为version不一致而无法修改。本质就是动态添加了set version = version+1 where version=value

  1. 在数据库表中添加整型字段version
  2. 在实体类上version属性上添加@Version注解
  3. 在MybatisPlusInterceptor拦截器配置中添加乐观锁拦截器:mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());

六、代码生成器

  1. 导入依赖MybatisPlus官网代码生成器
    <!-- MyBatisPlus代码生成器 -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-generator</artifactId>
        <version>3.5.3.1</version>
    </dependency>
    <!-- Velocity模板引擎 -->
    <dependency>
        <groupId>org.apache.velocity</groupId>
        <artifactId>velocity-engine-core</artifactId>
        <version>2.3</version>
    </dependency>
    <!-- Freemarker模板引擎 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-freemarker</artifactId>
        <version>3.0.6</version>
    </dependency>
    
  2. 创建代码生成器类
    public class MyFastAutoGenerator {
        public static void main(String[] args) {
            List<String> tables = new ArrayList<>(); //数据库表
            tables.add("tb_user");
            tables.add("tb_order");
            List<IFill> tableFillList = new ArrayList<>();
            tableFillList.add(new Property("createTime", FieldFill.INSERT));
            tableFillList.add(new Property("createUser", FieldFill.INSERT));
            tableFillList.add(new Property("updateTime", FieldFill.INSERT_UPDATE));
            tableFillList.add(new Property("updateUser", FieldFill.INSERT_UPDATE));
    
            FastAutoGenerator.create("jdbc:mysql://localhost:3306/test?serverTimezone=UTC", "root", "123456")
                    .globalConfig(builder -> {
                        builder.author("superm`超") // 设置作者
                                .enableSwagger() // 开启swagger模式
                                .outputDir(System.getProperty("user.dir") + "\\src\\main\\java"); // 指定输出目录
                    })
                    .dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
                        int typeCode = metaInfo.getJdbcType().TYPE_CODE;
                        if (typeCode == Types.SMALLINT) {
                            // 自定义类型转换
                            return DbColumnType.INTEGER;
                        }
                        return typeRegistry.getColumnType(metaInfo);
                    }))
                    .packageConfig(builder -> {
                        builder.parent("com.superm") // 设置父包名
                                .moduleName("practice") // 设置父包模块名
                                .pathInfo(Collections.singletonMap(OutputFile.xml, System.getProperty("user.dir") + "\\src\\main\\resources\\mapper")); // 设置mapperXml生成路径
                    })
                    .strategyConfig(builder -> {
                        builder.addInclude(tables) // 设置需要生成的表名
                                .addTablePrefix("tb_") // 设置过滤表前缀
                                .entityBuilder() //配置实体类
                                .enableLombok() //开启Lombok
                                .logicDeleteColumnName("deleted") //说明逻辑删除的字段
                                .idType(IdType.ASSIGN_ID) //指定主键ID生成类型
                                .addTableFills(tableFillList) //添加填充字段
                                .controllerBuilder() //配置Controller
                                .enableRestStyle() //开启RestController
                                .enableFileOverride(); //覆盖已生成文件
                    })
                    .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                    .execute();
        }
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值