如何抽象数据库访问层



所以我是软件开发的初学者,每次我必须对从数据库中获取数据的东西进行编程时,我都会在构建该层时遇到问题,我想知道我是不是想得太多了。

我知道我们应该让我们的系统易于更改,我认为数据库供应商是可能更改的因素之一。SQL数据库通常保持不变,或者该语言已经提供了某种形式的抽象,如JDBC。

但是,如果新的数据源是另一种类型的数据库,我应该提供一个DataSource抽象吗?我也在想,要做到这一点,我需要某种对象来解析数据,类似于Java中的ResultSet,甚至像String Map这样简单的对象,并解析为我在其他地方需要的类型。但我也认为这样做可能会降低复杂性,将一个数据结构的数据传递给另一个更通用的数据结构。

我还没有使用ORM,所以我不知道它们是否提供了我所想的抽象,它们是否有助于解决这个问题?

那么,通常是如何处理的呢?还是不需要不同类型数据库之间的抽象?

您熟悉Repository模式吗?看见https://martinfowler.com/eaaCatalog/repository.html和https://www.baeldung.com/java-dao-vs-repository.

我会在心理上区分数据源(例如文件、数据库、API等(和数据集(例如一堆特定记录,如订单(。

举个例子,假设我有一个非常简单的电子商务系统,其中有两个不同的数据源:一个存储用户配置文件的NoSQL数据库(比如Mongo(和一个存储订单信息的关系型SQL数据库(比方说Postgres(。考虑到你提到的是ORM,我正在用Java或C#这样的OO范式来处理这个问题。因此,我创建了两个域类——UserProfileOrder。此外,我还创建了两个存储库接口——UserProfileRepositoryOrderRepository。所有对订单或用户配置文件进行操作的代码都将通过存储库进行操作,如persistOrder()getOrders()等。

然后我创建了两个接口实现——一个MongoUserProfileRepository和一个PostgresOrderRepository。所有使用这些存储库的代码都只依赖于抽象(接口(。我的MongoUserProfileRepository使用Mongo数据源,知道如何从Mongo中读取并将结果映射到我的其他代码可以使用的对象。这同样适用于我的PostgresOrderRepository——它只是使用了一个Postgres数据源。

如果我也想将我的用户配置文件移动到Postgres,我只需要创建一个PostgresUserProfileRepository,并将其传递给所有依赖于UserProfileRepository接口的代码。所有这些变化都存在于一个地方——只存在于我的存储库层中。只要数据模型看起来仍然相同,其他任何东西都不会受到更改的影响。

为了回答您的另一个问题——是的,从一个数据结构(SQL表(映射到另一个(对象(会有一些开销,但我从未经历过这是一个主要问题(请参阅https://www.techopedia.com/definition/32462/impedance-mismatch)。

最新更新