我知道这个问题已经被问过很多次了,但我没有为我的情况找到一个好的答案。我正在使用 SQLC 生成用于查询数据库的方法。使用开始时初始化的一个连接时,一切正常。现在,我需要在多租户环境中进行设置,其中每个租户将具有单独的数据库。现在,我想从连接映射(映射[字符串]*sql。DB) 将租户与数据库连接连接起来。我的问题是关于在运行时覆盖/选择连接。使用一个连接,存储库被初始化为:type Repository interface { GetCustomerById(ctx context.Context, id int64) (Customer, error) ListCustomers(ctx context.Context) ([]Customer, error)}type repoSvc struct { *Queries db *sql.DB}func NewRepository(dbconn *sql.DB) Repository { return &repoSvc{ Queries: New(dbconn), db: dbconn, }}customerRepo := customerRepo.NewRepository(conn)GetCustomerById 是 SQLC 生成的方法,连接是数据库连接如何根据参数(从 Cookie 或上下文)建立连接?
1 回答
冉冉说
TA贡献1877条经验 获得超1个赞
假设您使用的是单独的数据库,最简单的方法是维护 ,其中是区分租户(例如,包含租户 ID 的 或)的方式。map[tenantID]Repository
tenantID
string
uint
这样,您就可以在运行时执行所有操作:
当您需要添加租户时,只需实例化该租户并将其添加到地图中
Repository
当您需要删除租户时,只需将其从映射中删除并关闭数据库连接
Repository
当您需要对租户执行查询时,请在映射中查找相应的,并使用它来执行该租户的查询
Repository
如果上述操作可能同时发生,请确保使用某种同步机制来避免访问映射时的数据争用(例如 、或 )。sync.Map
sync.RWMutex
如果您有一个存储租户及其数据库连接 URI 的数据库表,您仍然可以使用此方法:当您需要执行查询检查时,如果 缺少 :,则查询租户表并将该租户的 添加到映射中。然后,您可以定期扫描 并删除任何一段时间未使用的内容。Repository
map
Repository
map
Repository
为了使所有这些更容易,您还可以将整个机器包装到一个接口中,该接口与接口相同,但每个方法上都接受一个附加参数:MultitenantRepository
Repository
tenantID
type MultitenantRepository interface { GetCustomerById(ctx context.Context, tenant tenantID, id int64) (Customer, error) ListCustomers(ctx context.Context, tenant tenantID) ([]Customer, error) }
这将避免将多租户设置的所有复杂性暴露给业务逻辑。
- 1 回答
- 0 关注
- 61 浏览
添加回答
举报
0/150
提交
取消