Mybatis-plus进阶之分布式id生成

Mybatis-plus进阶之分布式id生成,第1张

Mybatis-plus进阶之分布式id生成 修改MyEmp
package com.yyoo.boot.mp.beans;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("t_my_emp")
public class MyEmp {
    @TableId(type=IdType.ASSIGN_ID)
    private Long id;
    private String name;
    private int age;
    private int sex;
}

其实就是在我们的主键字段,id上添加了@TableId注解

@TableId注解IdType属性说明 值I说明AUTO数据库 ID 自增NONE无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)默认为NONEINPUTnsert 前自行 set 主键值ASSIGN_ID分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator的方法nextIdASSIGN_UUID分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID 配置IdentifierGenerator自动id生成器
    
    @Bean
    public GlobalConfig globalConfig() {
        GlobalConfig conf = new GlobalConfig();
        conf.setIdentifierGenerator(new DefaultIdentifierGenerator());
        return conf;
    }
配置SqlSessionFactory设置GlobalConfig配置
    @Bean(name = "sessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("hikariDataSource") DataSource ds) throws Exception {
        log.info("数据源:{},aliasesPackage:{}",ds,this.aliasesPackage);
        MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
        factoryBean.setDataSource(ds);
        if(this.aliasesPackage != null && !"".equals(this.aliasesPackage)) {
            factoryBean.setTypeAliasesPackage(this.aliasesPackage);
        }
        //指定mapper xml目录
        Assert.notEmpty(this.mapperLocations,"扫描的Mapper xml不能为空");
        factoryBean.setMapperLocations(resolveMapperLocations(this.mapperLocations));
        // 添加分页插件
        factoryBean.setPlugins(mybatisPlusInterceptor());
        // 添加id生成器的配置
        factoryBean.setGlobalConfig(globalConfig());
        return factoryBean.getObject();
    }
示例代码
    @Test
    public void t1(){
        int num = 100;
        List list = new ArrayList<>();
        for (int i = 0;i < num;i++) {
            Random random = new Random();
            MyEmp myEmp = new MyEmp();
            myEmp.setName(AutoNameUtil.autoSurAndName());
            myEmp.setAge(random.nextInt(50) + 15);// 15岁及以上
            myEmp.setSex(random.nextInt(2));
            list.add(myEmp);
        }
        long start = System.currentTimeMillis();
        myEmpService.saveBatch(list);
        long end = System.currentTimeMillis();
        System.out.println("执行时间:"+(end -start));
    }
执行结果

IdentifierGenerator生成器详解

IdentifierGenerator是生成器的接口,DefaultIdentifierGenerator是其默认的实现,DefaultIdentifierGenerator的nextId方法默认是使用雪花算法实现的分布式id,其nextUUID方法模式是生成不带中划线的 UUID。

我们示例中的配置只是非常简单粗暴的DefaultIdentifierGenerator配置,DefaultIdentifierGenerator还有两个重载的构造方法,请大家仔细阅读源码,以及去多了解雪花算法来合理的进行配置。本文不做过多讲解。

自定义IdentifierGenerator生成器

我们自定义IdentifierGenerator,只需实现IdentifierGenerator接口,重写nextId方法即可。然后再替换上面代码DefaultIdentifierGenerator的配置即可。以下是官网示例:

public class CustomIdGenerator implements IdentifierGenerator {
    @Override
    public Long nextId(Object entity) {
      	//可以将当前传入的class全类名来作为bizKey,或者提取参数来生成bizKey进行分布式Id调用生成.
      	String bizKey = entity.getClass().getName();
        //根据bizKey调用分布式ID生成
        long id = ....;
      	//返回生成的id值即可.
        return id;
    }
}
问题说明

在我们前面的示例中MyEmp对象的id属性的类型为long,使用id生成器就报错,而且id生成器根本没有生成id,需要将它修改为包装类才能成功。

实际使用中我们的JavaBean对应的数字类型建议都尽量使用其包装类型来作为JavaBean的字段类型,因为非包装类是不能表示null的,特别有些可为空的字段,需要使用null这样的表示的时候。

上一篇:Mybatis-plus进阶之分页
下一篇:待续

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5721756.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存