当前位置: 首页 > 知识库问答 >
问题:

jOOQ中动态运行时PostgreSQL模式选择

骆雅昶
2023-03-14
CREATE TABLE foo (id INT PRIMARY KEY);
CREATE FUNCTION bar(_id INT) RETURNS INT AS $$
    INSERT INTO foo (id) VALUES (_id) RETURNING id;
$$ LANGUAGE SQL;

Dave使用Flyway为Alice和Bob初始化模式,因此他们都有foo table和bar函数。Dave使用jOOQ生成java api,并在运行时将开发模式映射到用户模式。戴夫以前和他的任何一个客户都没有关系,突然发现自己是鲍勃的侄子。

但是爱丽丝和鲍勃后来都回来找戴夫,让他为他们写一些自动化。因此,Dave决定创建一个机器用户Rob,他可以访问Alice和Bob的模式。他可以重用所有相同的jOOQ生成的代码,并且所有使用foo的代码都可以完美无缺地直接工作,直到自动化试图执行bar函数-error:关系“foo”不存在。运行时模式映射对函数栏中对foo的无模式引用没有影响。

简单的答案是将search_path设置为Rob应该伪装成的用户。这可以在每组jOOQ调用之前手动设置,但这感觉就像是jOOQ通常使我们与编写隔离的那种容易出错、乏味的代码。Dave可以创建两个用户Rolice和Robob,每个用户都被单独配置为访问各自的客户端。但这显然伸缩性很差,尤其是在使用连接池时。Dave选择了自定义的ConnectionProvider来设置search_path,但是这可能会带来很大的开销,因为search_path查询必须在返回连接之前返回一个结果。

如果有关系的话,我使用的是PostgreSQL 9.3和jOOQ 3.5。戴夫是你想让他成为什么样的人,因为半小时前我编造了他。

ConnectionProvider解决方案的相关部分:

@Override
public Connection acquire() throws DataAccessException {
    Connection c = dataSource.getConnection();
    try(Statement s = c.createStatement()){
        s.execute("SET search_path = '"+schema+"'");
    }catch(SQLException e){
        throw new DataAccessException("Could not initialize connection", e);
    }
    return c;
}

共有1个答案

越望
2023-03-14

至少就目前而言,设置search_path似乎超出了Jooq的范围。理论上,我们可以在Flyway中使用Java迁移,并强制函数中的所有引用都具有显式模式,但这听起来相当痛苦。这使得我们要么手动设置搜索路径,潜在地将其添加到事务管理中,要么编写一个更智能的ConnectionProvider。

我们的应用程序中有一个非常严格的每个事务一个查询的模型,因此实际上没有任何事务管理可以添加“set search_path=...”查询。ConnectionProvider解决方案似乎是我们的最佳选择。

我们已经有了一个用于连接池的自定义ConnectionProvider实现,因此添加设置search_path的逻辑(在问题的末尾给出)并不太麻烦。我们可以通过使用记住当前search_path被设置为什么的东西来装饰连接,并在前缀“set search_path=...;”来使其性能更好如果需要的话,在任何声明出门前。我们已经看到在每个请求中设置search_path会对性能产生影响,所以这只是时间问题。好吧,这还是回到我们旧的专有数据库访问层的痛苦。

 类似资料:
  • 我有下面同样的问题,但我想知道答案。Spring Boot:如何使用多个模式,并在运行时为每个请求动态选择使用哪一个模式 请帮助我找到答案 如何拥有一个数据库连接并为每个请求指定不同的模式? 提前谢谢你。

  • 我在构建过程中使用org.jooq.util.DefaultGenerator来生成jOOQ类来表示我的数据库模式。 当应用程序运行时,模式可能会在应用程序不知道的情况下更改。此类更改可能与已生成的代码兼容,也可能与已生成的代码不兼容。 如何在运行时检测生成的代码是否对特定模式仍然有效? 我正在寻找类似于布尔值stillValid=new SchemaValidator(存在的GeneratedC

  • 描述 (Description) 您还可以使用HTML到App方法创建动态选择器模式。 它使用两个参数 - pickerHTML - 它包含pickerHTML模态的字符串元素。 removeOnClose - 它包含布尔值,当您关闭Picker时,它将从DOM中删除。 默认情况下,它包含真值。 例子 (Example) 以下示例演示了在Framework7中使用动态选择器模式 - <!DOCTY

  • 问题内容: 我在构建过程中使用来生成jOOQ类来表示我的数据库模式。 当应用程序运行时,架构可能会在应用程序不知道的情况下发生更改。这样的更改可能与已经生成的代码兼容,也可能与之不兼容。 如何在运行时中检测生成的代码是否仍然在特定模式下有效? 我正在寻找类似的东西 问题答案: 使用org.jooq.Meta的jOOQ 3.0解决方案 在即将到来的jOOQ 3.0中,可以通过新对象(通过功能请求#1

  • 我需要在应用程序启动时检查当前在数据库中的数据库模式和以前用于JOOQ生成模型的模式是相同的。我试图使用这里建议的解决方案,发现了一些问题: 查询所有表的技巧:这种解决方案不检查列类型,只检查表名和字段名,但我也需要检查类型 :此处仅检查架构和名称,不再检查列类型 我试图使用中可用的信息并手动进行比较,但遇到了另一个问题。在某些情况下,生成字段的数据类型和运行时从检索的字段不匹配。 例如,无时区默