zoukankan      html  css  js  c++  java
  • spring data jpa、Hibernate开启全球唯一UUID设置

     

    spring data jpa、Hibernate开启全球唯一UUID设置

    原文链接:https://www.cnblogs.com/blog5277/p/10662079.html

    原文作者:博客园--曲高终和寡

    *******************如果你看到这一行,说明爬虫在本人还没有发布完成的时候就抓走了我的文章,导致内容不完整,请去上述的原文链接查看原文****************

    UUID这个东西,具体的我就不讲了,网上的内容很多,我这里就随便放一个大家看一下就了解了

    https://www.jianshu.com/p/d77f3ef0868a

    这里面有关于发号器,UUID的介绍,具体各位是使用UUID的哪个版本,或者使用雪花ID,或者使用其他别的方式,请各位自行判断

    在我的业务里面呢:

    1.准备部署至少两台服务器,且两台服务器时区不一样,一台阿里云香港,东八区,一台美国洛杉矶,多少区忘了,反正有13个小时的时差,

    ——雪花ID的方案就被我否了,因为我不能保证美国那台服务器的时区不会根据冬夏令时来回跳,雪花ID在时钟回拨的情况下会一直等候,我也不需要雪花ID有序这个优点。

    2.同样为了容灾,我准备在两台服务器分别部署数据库

    ——主键自增的方案就被我否了,迁移有点麻烦了

    3.我不需要主键来排序,我选用的PostgresQL也不会因为主键是字符型的而导致插入、读取变快

    ——所以我不需要一切主键需要有序的生成方案,UUID完美符合我的需求

    4.既然选用了UUID,我就希望它在任何情况下都不会重复,全球唯一

    ——那么UUID的生成方案2.3.4.5就都不满足我的要求了,虽然概率极地,但是还是有理论上重复的可能性的

    5.UUID的方案1存在一定的危险性,是根据MAC地址(或者IP)生成的,那么理论上能根据MAC地址找到所在地

    ——。。。然后呢。。。?我一台服务器/IP在香港,一台服务器/IP在洛杉矶,想通过这俩地方来找我怕是不太可能嗷。。。更何况我写的东西根本就不会有多少人用,更没有什么法律风险不担心被查水表,更没有什么价值。。。?谁会来搞我?

    所以,最终选用了方案1的UUID生成方法,不可能重复,我开发的时候就不用考虑这种极小概率会导致的BUG,放心大胆的用就是了。

    而生成方案1的UUID有很多工具包,比如Apache common 的UUID 包,还有github上一个项目 JAU,项目地址:

    https://github.com/cowtowncoder/java-uuid-generator

    我太懒了,不想在项目里引入一个包,就为了生成UUID。。。所以就查了一下,原来HIbernate对生成UUID方案1还做了优化:

    Version1变种 – Hibernate

    Hibernate的CustomVersionOneStrategy.java,解决了之前version 1的两个问题

    - 时间戳(6bytes, 48bit):毫秒级别的,从1970年算起,能撑8925年….
    - 顺序号(2bytes, 16bit, 最大值65535): 没有时间戳过了一秒要归零的事,各搞各的,short溢出到了负数就归0。
    - 机器标识(4bytes 32bit): 拿localHost的IP地址,IPV4呢正好4个byte,但如果是IPV6要16个bytes,就只拿前4个byte。
    - 进程标识(4bytes 32bit): 用当前时间戳右移8位再取整数应付,不信两条线程会同时启动。

    值得留意就是,机器进程和进程标识组成的64bit Long几乎不变,只变动另一个Long就够了。

    Hibernate解决了Version1的两个问题,哪两个问题呢:

    但好像Version 1就没考虑过一台机器上起了两个进程这类的问题,也没考虑相同时间戳的并发问题

    很好,HIbernate解决了这俩问题,那完美符合我的需求,并且本来项目就引入了JPA,官方支持岂不美哉?

    废话说了那么多,配置只需要两行的事,然而这个配置国内网站几乎找不到,困扰了我很久怎么在Hibernate里面设置选用CustomVersionOneStrategy.java,作为主键生成策略的

    /**
     * @Author:ShadowSaint
     * @Date:19-4-3 上午4:56
     * @Description: TODO
     */
    @MappedSuperclass
    @Data
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public class BaseDomain {
        @Id
        @GenericGenerator(
                name = "uuid2",
                strategy = "uuid2",
                parameters = {@org.hibernate.annotations.Parameter(
                        name = "uuid_gen_strategy_class",
                        value = "org.hibernate.id.uuid.CustomVersionOneStrategy")
                })
        @GeneratedValue(generator = "uuid2")
        private String id;
        @Column
        private LocalDateTime gmtCreate;
        @Column
        private LocalDateTime gmtModified;
    
        public void initInsert() {
            this.gmtCreate = LocalDateTime.now();
            this.gmtModified = LocalDateTime.now();
        }
    
        public void initUpdate() {
            this.gmtModified = LocalDateTime.now();
        }
    }

    这样就可以了,以后每一个DO都继承这个BaseDomain,ID就自动生成Hibernate优化版的版本1UUID了

  • 相关阅读:
    站立会议04(第二阶段)附加站立会议02、03
    第二阶段冲刺---站立会议01
    网络:Session原理及存储
    网络:Xen理解
    网络:LVS负载均衡原理
    网络:OSPF理解
    语音笔记:信号分析
    语音笔记:CTC
    语音笔记:矢量量化
    语音笔记:MFCC
  • 原文地址:https://www.cnblogs.com/blog5277/p/10662079.html
Copyright © 2011-2022 走看看