为了账号安全,请及时绑定邮箱和手机立即绑定

使用一个接口抽象多个数据源供存储库使用

使用一个接口抽象多个数据源供存储库使用

Go
慕神8447489 2022-06-27 11:08:17
我正在尝试应用干净的架构,除此之外,我有一个数据源层和一个存储库层。存储库使用一个接口与底层数据源(只有一个 sql db atm)进行交互,但是数据源接口是为 sql 数据库量身定制的,如下所示:package datasourceimport "database/sql"type Source interface {  Open() error                                        // Open the connection  Close()                                             // Close the connection        Exec(string, ...interface{}) error                  // Execute a prepared query(e.g:insert)  Query(string, ...interface{}) (*sql.Rows, error)    // Retrieve rows with a prepared query}正如我想象的其他数据源将在稍后引入(如 nosql dbs 或外部 API ......),我如何将它们全部分组在一个通用接口下,以便存储库不需要知道源数据。谢谢你。PS:我知道有类似的问题,但从存储库的角度处理问题,我正在寻找数据源方面的解决方案(例如:通用接口),因为我不希望每个单独的存储库资源。
查看完整描述

1 回答

?
米脂

TA贡献1836条经验 获得超3个赞

您选择的抽象级别不支持与数据库无关的实现。您期待 SQL 查询,并且您正在返回*sql.Rows.


如果您想独立于数据库(包括关系数据库和 NoSQL 数据库),则需要使用更高的抽象级别,其中不存在 SQL 或 NoSQL 查询等术语。


例如,如果您打算查询、加载和保存用户,您界面的相关部分可能如下所示:


type User struct {

    ID string

    // other info about users

}


type Source interface {

    GetUser(id string) (*User, error)

    SaveUser(u *User) error

    FindUsersByFirstName(firstName string) ([]*User, error)

}

此接口不限制实现使用 SQL 查询和相关对象,但它表达了您需要的操作。您应用程序的其他部分应该(必须)仅通过此接口访问数据层。所有的细节(例如 SQL 查询)都属于实现。


此外,在您继续进行这种抽象之前,请检查其优势和所需的额外工作,因为人们通常会为极不可能的场景做计划。如果您从 SQL 数据库开始,您可能永远不会切换到 NoSQL 数据库。


你不能(不应该)有一个单一的数据源层来支持你想要的抽象级别的所有数据库。这将需要“开发”一种独立于数据库的查询语言及其解析器,然后您需要将其转换为特定的数据库查询。如果要支持所有数据库,最简单的方法是合并存储库和数据源层。或者放弃支持所有数据库,因为几乎 99% 的项目永远不会切换到根本不同的数据库。


查看完整回答
反对 回复 2022-06-27
  • 1 回答
  • 0 关注
  • 334 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号