Available in versions: Dev (3.21) | Latest (3.20) | 3.19

继承

适用于 ❌ 开源版   ✅ Express 版   ✅ 专业版   ✅ 企业版

父表的策略可以被其子表继承,这大大简化了在整个模式中定义策略的任务。

例如,假设有一个 TENANT 表,其中包含一个 TENANT_ID 主键,并且正在应用一个策略来形成一个类似 TENANT.TENANT_ID = 42 的谓词。现在,对于像这样的模式

CREATE TABLE TENANT (
  TENANT_ID BIGINT NOT NULL PRIMARY KEY
  ...
);

CREATE TABLE CUSTOMER (
  CUSTOMER_ID BIGINT NOT NULL PRIMARY KEY,
  TENANT_ID BIGINT NOT NULL REFERENCES TENANT,
  ...
);

CREATE TABLE INVOICE (
  INVOICE_ID BIGINT NOT NULL PRIMARY KEY,
  CUSTOMER_ID BIGINT NOT NULL REFERENCES CUSTOMER,
  ...
)
出于性能原因,通过在 INVOICE 表和所有其他表上重复 TENANT_ID 列来稍微反规范化您的模式可能是有用的,即使从模式设计的角度来看这不是必需的。本示例特意避免了这种方法,以展示该功能的强大之处。

现在,自然地,如果用户只能访问 TENANT.TENANT_ID = 42,那么所有其他租户的客户和发票也应该无法访问。当手动实现行级别安全性时,这有多容易被遗忘?有了这个功能就不会!只需像这样声明策略的继承

Configuration configuration = ...;
configuration.set(new DefaultPolicyProvider().append(

    // The table on which to apply a policy
    TENANT,

    // The condition to apply to queries against the table
    TENANT.TENANT_ID.eq(42),

    // Implicit join paths from a child table to the TENANT table
    // All child tables will automatically inherit the policy
    CUSTOMER.tenant(),
    INVOICE.customer().tenant()
));

这相当于声明了 3 个策略

Configuration configuration = ...;
configuration.set(new DefaultPolicyProvider()
    .append(TENANT, TENANT.TENANT_ID.eq(42))
    .append(CUSTOMER, CUSTOMER.tenant().TENANT_ID.eq(42))
    .append(INVOICE, INVOICE.customer().tenant().TENANT_ID.eq(42))
);

现在,如果您像这样查询发票表

create.select(INVOICE.ID, INVOICE.AMOUNT)
      .from(INVOICE)
      .fetch();

那么上面的策略将添加一个 INVOICE.customer().tenant().TENANT_ID.eq(42) 谓词,有效地向您的查询添加一个 隐式 JOIN

SELECT INVOICE.ID, INVOICE.AMOUNT
FROM (
  INVOICE
    JOIN (
      CUSTOMER
        JOIN (
          SELECT *
          FROM TENANT
          TENANT_ID = 42
        ) TENANT
          ON CUSTOMER.TENANT_ID = TENANT.TENANT_ID
    )
      ON INVOICE.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
  )

对于所有其他 DML 语句也是如此。例如,将无法从不同的 TENANT INSERTUPDATEDELETE 发票

引用此页

反馈

您对此页面有任何反馈吗? 我们很乐意听取您的意见!

The jOOQ Logo