小编典典

在PostgreSQL中使用架构的休眠和多租户数据库

hibernate

背景

我正在开发将来的多租户Web应用程序,它将需要支持数千个用户。该应用程序是在基于Java的Play之上构建的!使用JPA /
Hibernate和postgreSQL的MVC框架。

我看了盖伊·纳尔(Guy
Naor)关于在Rails编写多租户应用程序的演讲,其中他谈到了几种多租户方法(数据隔离度随着列表的增加而降低):

  1. 每个客户都有一个单独的数据库
  2. 一个为每个客户提供单独的架构和表(表命名空间)的数据库。
  3. 一个数据库,其中包含一组具有客户ID列的表。

我选择了方法2,从请求中解析出某种用户ID,然后将其用于访问该用户的表空间。SET search_path TO customer_schema,public在进行任何查询之前,都会发出一个postgres 命令,以确保客户的表是查询的目标。使用
Play!@Before中控制器方法中的控制器注释可以轻松完成此操作 (这是Guy在他的rails示例中使用的方法)。postgres中的
search_path 的行为与$PATH操作系统中的行为完全相同。太棒了!

所有这些听起来都很棒,但是在JDBC / Hibernate / JPA堆栈之上实现它时,我立即遇到了困难,因为似乎没有一种在运行时动态切换模式的方法。

问题

如何获取JDBC或Hibernate以在运行时支持动态切换Postgres模式?

似乎数据库连接是由连接工厂静态配置的(请参阅:如何使用hibernate在一个数据库上管理许多模式)。我发现类似的问题,每个用户使用多个SessionFactory的答案类似,但是由于我了解SessionFactory是重量级的对象,因此您不能支持数百个用户,更不用说数千个用户了。

我还没有完全致力于上面的方法2,但是我也没有完全放弃它来使用方法3。


阅读 667

收藏
2020-06-20

共1个答案

小编典典

您可以执行命令

SET search_path TO customer_schema,public

在相同的连接/会话/事务内,根据需要进行操作。这只是的另一个命令SELECT 1;。在手册中有更多信息

当然,您也可以预设search_path每个用户。

ALTER ROLE foo SET search_path=foo, public;

如果每个用户或其中许多用户都有与其用户名匹配的架构,则可以简单地使用postgresql.conf中默认设置

search_path="$user",public;

设置search_path此处的更多方法:
search_path如何影响标识符解析和“当前模式”

2020-06-20