【问题标题】:Migrate SQL data from Hibernate @OneToMany list which used @OrderColumn index but now is replaced by a double-linked list从使用 @OrderColumn 索引但现在被双链表替换的 Hibernate @OneToMany 列表迁移 SQL 数据
【发布时间】:2018-11-15 06:26:22
【问题描述】:

我有两个数据库模式,都是由 Hibernate 生成的,其中一个 Section 内的元素列表是使用 @OneToMany 关系排序的 @OrderColumn 和另一个其中 Section 元素排序是一个双链表,引用了前一个和下一个元素。 我现在正在尝试使用纯 SQL 脚本将数据从原始数据库迁移到新数据库。

到目前为止,我能够为一个部分的一个元素执行此操作,但我无法将其概括为所有项目或所有部分。

(我可以为每个可能的索引手动编写片段(每个部分少于 20 个元素),但不是为所有部分(有数千个)。

这是数据库架构

架构 1

注释

@Entity
@Table(name = "elements")
public class Element {
  private UUID id;

  ...
}

@Entity
@Table(name = "sections")
public class Section {
  ...

  @OneToMany
    @OrderColumn(name = "order")
    private List<Element> elements = new ArrayList<Element>();

  ...
}

生成

CREATE TABLE public.elements
(
  id uuid NOT NULL,
  section_id uuid,
  ...
}

CREATE TABLE public.sections_elements
(
  section_id uuid NOT NULL,
  element_id uuid NOT NULL,
  order integer NOT NULL,
  CONSTRAINTS ...
)


CREATE TABLE public.sections
(
  id uuid NOT NULL,
  ...
)

架构 2

注释

@Entity
@Table(name = "elements")
public class Element {
  private UUID id;

  @ManyToOne
    private ModelSection section;

  @ManyToOne
    private Element beforeEl;

    @ManyToOne
    private Element afterEl;

  ...

}

@Entity
@Table(name = "sections")
public class Section {
  ...
  (No reference to the elements)
  ...
}

生成

CREATE TABLE public.elements
(
  id uuid NOT NULL,
  after_el_id uuid,
  before_el_id uuid,
  section_id uuid,
  ...
)

CREATE TABLE public.sections
(
  id uuid NOT NULL,
  ...
)

这是更新一个Section的前两个Elementbefore_el_idafter_el_id的脚本(由硬编码的id指定)

-- SET THE ID OF THE BEFORE ELEMENT ID OF THE ELEMENT AT INDEX 0 WITH THAT AT INDEX 1
UPDATE elements els
SET before_el_id = (
    SELECT element_id
    FROM OLD_DB.section_elements sec_els
    JOIN elements els
    ON sec_els.element_id = els.id
    WHERE sec_els.order = 1
    AND sec_els.sec_id = 'ac1031fa-5e4d-1452-815e-51cdc32d002f')
WHERE id = (
  SELECT element_id
  FROM OLD_DB.section_elements sec_els
  JOIN elements els
  ON sec_els.element_id = els.id
  WHERE sec_els.order = 0
  AND sec_els.sec_id = 'ac1031fa-5e4d-1452-815e-51cdc32d002f')
);

-- SET THE ID OF THE AFTER ELEMENT ID OF THE ELEMENT AT INDEX 1 WITH THAT AT INDEX 0
UPDATE elements els
SET before_el_id = (
    SELECT element_id
    FROM OLD_DB.section_elements sec_els
    JOIN elements els
    ON sec_els.element_id = els.id
    WHERE sec_els.order = 1
    AND sec_els.sec_id = 'ac1031fa-5e4d-1452-815e-51cdc32d002f')
WHERE id = (
  SELECT element_id
  FROM OLD_DB.section_elements sec_els
  JOIN elements els
  ON sec_els.element_id = els.id
  WHERE sec_els.order = 0
  AND sec_els.sec_id = 'ac1031fa-5e4d-1452-815e-51cdc32d002f')
);

问题

有没有办法将其概括为至少更新所有Sections 列表的所有第一个Elements? 有没有办法将其概括为更新所有Sections 中的所有Elements?

如果使用普通 SQL 无法做到这一点(我实际上使用的是 PostgreSQL),也许有一些脚本工具会有所帮助?

【问题讨论】:

    标签: sql postgresql hibernate


    【解决方案1】:

    我不知道是否有仅使用 SQL 的解决方案。我最终做的是编写一个连接到两个数据库的简短 Node.js 程序,并使用循环在程序内部运行 SELECT 和 UPDATES。

    创建一个连接到两个数据库的 javascript 脚本非常容易。我以此为起点

    How to make connection to Postgres via Node.js

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-16
      • 2019-07-16
      • 2019-07-25
      • 2016-07-23
      • 1970-01-01
      • 2011-11-16
      相关资源
      最近更新 更多