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了

  • 相关阅读:
    react ts axios 配置跨域
    npm run eject“Remove untracked files, stash or commit any changes, and try again.”错误
    java 进程的参数和list的线程安全
    帆软报表 大屏列表跑马灯效果JS
    帆软报表 快速复用数据集,避免重复劳动
    分析云 OA中部门分级思路和实现方法
    分析云 分段器 只显示一个块的数据
    分析云 更改服务默认的端口号
    分析云U8项目配置方法新版本(2)
    Oracle 创建时间维度表并更新是否工作日字段
  • 原文地址:https://www.cnblogs.com/blog5277/p/10662079.html
Copyright © 2011-2022 走看看