Mybatisplus的雪花算法及代码生成器的使用

1. 雪花算法

 1.1 背景: 

        雪花算法(Snowflake)的使用背景主要源于高并发分布式系统环境下对唯一ID生成的需求。这种需求在像Twitter这样的社交媒体平台上尤为突出,因为Twitter需要处理每秒上万条消息的请求,并且每条消息都必须分配一个唯一的ID。这些ID不仅需要全局唯一,以跨机器、跨时间区分,还需要保持一定的顺序性(尽管不要求连续),以方便客户端排序和后续的数据处理。

1.2 与自动递增的区别

一、生成原理

雪花算法

  • 雪花算法是一种由Twitter开源的分布式ID生成算法。
  • 它将64位的long型ID分为四个部分:时间戳(41位)、数据中心ID(5位)、机器ID(5位)和序列号(12位)。
  • 通过组合这四个部分来生成全局唯一的ID,其中时间戳确保了ID的顺序性,数据中心ID和机器ID确保了ID的分布式唯一性,序列号则用于在同一毫秒内生成多个ID。

自动递增

  • 自动递增是数据库(如MySQL)提供的一种主键生成机制。
  • 它通过自动递增的方式为每条插入的记录生成一个唯一的ID值。
  • 在MySQL中,自增ID通常与整数类型的列(如INT或BIGINT)结合使用,当插入新记录时,数据库会自动为该列生成一个唯一的ID值,并在下一次插入时自动递增。

二、适用场景

雪花算法:

  • 适用于分布式系统和高并发环境。
  • 能够满足全局唯一性和有序性的需求。
  • 可以在应用层生成ID,减少对数据库的依赖和压力。

自动递增

  • 适用于单机系统或分布式系统中单个数据库节点的场景。
  • 在这些场景下,自增ID能够高效地为每条记录生成唯一的标识符。
  • 然而,在分布式系统中,如果多个节点同时生成自增ID,可能会导致ID冲突,需要额外的处理机制(如分表分库时设置不同的起始递增位置)。

三、性能特点

雪花算法

  • 由于其生成ID的算法较为简单,且不需要依赖数据库,因此生成ID的效率较高。
  • 同时,由于ID是有序的,可以在一定程度上提高数据库的插入和查询效率。

自动递增

  • 在单机系统或单个数据库节点上,自增ID的生成效率也非常高。
  • 但是,在分布式系统中,由于需要处理ID冲突的问题,可能会引入额外的性能开销。

四、全局唯一性保证

雪花算法

  • 通过时间戳、数据中心ID、机器ID和序列号的组合来确保ID的全局唯一性。
  • 即使在不同的数据中心和机器上,也能生成唯一的ID。

自动递增

  • 在单机系统或单个数据库节点上,自增ID能够保证唯一性。
  • 但在分布式系统中,如果多个节点同时生成自增ID,则无法直接保证全局唯一性,需要额外的处理机制来避免ID冲突。

注:雪花算法是由Twitter公布的分布式主键生成算法,它能够保证不同表的主键的不重复性,以及相同表的 主键的有序性。 即不同表的主键也不同,有利于做数据库的分表

2. SpringBoot常用的主键策略以及使用

2.1 常用的主键策略

Mybatisplus的雪花算法及代码生成器的使用_第1张图片

2.2 使用

   2.2.1Mybatisplus默认使用的是雪花算法

   2.2.2也可以自行配置全局的主键策略

mybatis-plus:
  configuration:
    # 配置MyBatis日志
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      # 配置MyBatis-Plus操作表的默认前缀
      table-prefix: t_
      # 配置MyBatis-Plus的主键策略(自动递增)
      id-type: auto

  2.2.3 也可以设置局部的主键策略

       即在实体类的主键上的@TableId 加入type = IdType.ASSIGN_ID(雪花)

    @TableId(type = IdType.ASSIGN_ID)
    private Long id;

3. 代码生成器的使用

2.1 注意

  生成的代码可以设置一个单独的文件夹生成(然后再粘贴过来),但是包名要设置正确

2.2 引入依赖


    com.baomidou
    mybatis-plus-generator
    3.5.1


    org.freemarker
    freemarker
    2.3.31

2.3 快速生成

 注意: 在多数据源配置中,primary用于指定哪个数据源应该被视为“默认”数据源。当应用需要访问数据库,但没有明确指定使用哪个数据源时,就会使用primary指定的数据源。这通常用于读写分离的场景,其中primary通常指向主数据源(写数据源),而其他数据源作为从数据源(读数据源)使用。

   

public class FastAutoGeneratorTest {
  public static void main(String[] args) {
    FastAutoGenerator.create("jdbc:mysql://127.0.0.1:3306/mybatis_plus?           
     characterEncoding=utf-8&userSSL=false", "root", "123456")
    .globalConfig(builder -> {
    builder.author("atguigu") // 设置作者
    //.enableSwagger() // 开启 swagger 模式 .fileOverride() // 覆盖已生成文件
    .outputDir("D://mybatis_plus"); // 指定输出目录 })
    .packageConfig(builder -> {
    builder.parent("com.atguigu") // 设置父包名
    .moduleName("mybatisplus") // 设置父包模块名
    
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, "D://mybatis_plus"));
// 设置mapperXml生成路径
    })
    .strategyConfig(builder -> {
      builder.addInclude("t_user") // 设置需要生成的表名
      .addTablePrefix("t_", "c_"); // 设置过滤表前缀
                                   //addTablePrefix("t_", "c_")方法的作用并不是直接指定哪些前缀的表应该被生成代码,而是用于排除掉那些表名以指定前缀开头的表,除非这些表在其他地方(如addInclude)被明确指定要生成代码。
    })
.    templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker 引擎模板,默认的是Velocity引擎模板
    .execute();
 }
}

你可能感兴趣的:(算法,dreamweaver)