数据库主键生成策略:

  1. 自增长:

优点:有序容易实现,缺点:无法保证数据的安全性,容易泄密、攻击

  1. UUID:基于时间、机器等随机生成的字符串

优点:安全、保密,缺点:长度较长,随机生成的字符串无法保证有序

  1. 思路:

不论基于何种策略,查询的时候都是基于自然顺序即数据物理地址,而物理地址是有序的。问题在于插入的时候, 自增长策略保证了有序插入,而UUID是随机生成的字符串,按ASCII排序,后生成的字符串有可能排在前面,导致了查询的时候是无序的,没有先后顺序。如果把ID字符串拆分成两部分,第一部分用来排序,第二部分用来保证唯一性,则既保证了先后顺序,又保证了数据安全性。所以第一部分采用时间戳到秒(同一秒的数据也无所谓先后顺序),后一部分采用UUID,然后加密为MD5的16位,缩短长度。

ID生成工具类

package com.lezic.util; import java.util.Date; import java.util.UUID; /** * 主键ID生成工具 * * @author lincl */ public class IdUtil { /** * 获取有序的UUID * * @return */ public static String sortUUID() { String uuid = UUID.randomUUID().toString(); String md5 = EncryptUtil.shortMd5(uuid); return DateUtil.format(new Date(), "yyyyMMddHHmmss") "_" md5; } public static void main(String[] args) throws InterruptedException { System.out.println(IdUtil.sortUUID()); Thread.sleep(1000); System.out.println(IdUtil.sortUUID()); Thread.sleep(1000); System.out.println(IdUtil.sortUUID()); Thread.sleep(1000); System.out.println(IdUtil.sortUUID()); Thread.sleep(1000); System.out.println(IdUtil.sortUUID()); } }

生成效果

时序数据库druid使用案例(基于UUID的有序主键生成策略)(1)

基于mybatis-plus注册ID生成器,便于插入数据库的ID自动生成

package com.lezic.config; import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer; import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties; import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator; import com.baomidou.mybatisplus.extension.MybatisMapWrapperFactory; import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; @Configuration @MapperScan({"com.lezic.modules.**.dao", "com.lezic.service.**.dao"}) public class MybatisPlusConfig { @Bean public IdentifierGenerator idGenerator() { return new MybatisSortUUIDGenerator(); } }

实体类定义

package com.lezic.modules.demo.domain; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.extension.activerecord.Model; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import java.time.LocalDate; import java.time.LocalDateTime; /** * Demo例子 * * @author lincl * @date 2020-07-09 */ @Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) public class DemoStudent extends Model<DemoStudent> { private static final long serialVersionUID = 1L; /** * 学生ID */ @TableId(value = "demo_student_id", type = IdType.ASSIGN_UUID) private String demoStudentId; /** * 学号 */ private String studentNo; // 其它字段定义 }

,