阻抗不匹配:存储库模式+ Mapper + Cursor + SQLite

时间:2013-10-04 16:22:39

标签: sqlite orm repository-pattern datamapper

我正在基于存储库模式构建ORM。在存储库中,我创建了一些我称之为“数据源”的东西,用于从数据库中获取结果并将它们映射到实体对象。每个数据源都是使用查询创建的,负责获取第一行的单个结果或所有结果。 虽然数据源主要负责从(准备好的)查询中获取单个或所有对象,但它也可以作为创建数据源期间设置的“游标”的代理。我把光标放在引号中,因为它实际上是一个主键数组,后来用于使用这些ID从存储库中获取实体。这种类似游标的实现是由SQLite引起的,在游戏方面,它没有提供更好的东西。

因此数据源提供singleEntity(),allEntities(),firstEntity(),nextEntity(),previousEntity(),entityAtIndex()。如前所述,除了前两个之外的所有实际上都在使用光标。光标是从与数据源相同的查询创建的(但是自动优化以限制光标的选定字段)。

存储库本身提供CRUD功能(getById(),remove(),create(),update())。

这可能一切都很好,大部分只是常见的模式实现......但刚才我意识到以下问题:

即使应该用于通过ID获取实体的存储库本身,存储库中的数据源可能只是对数据使用不同的投影 - 或者只使用可用的子集。因此,它可以返回与默认存储库getEntityById()将返回的不同或仅一些替代映射。

如何改变设计? 1)禁止其他映射而不是默认的repo getter? =>可能是糟糕的设计。如何控制数据源等的查询 2)强制用户为光标设置自定义查询,以创建索引+提取器查询以通过id获取单个结果? =>比以前的想法更好,但也意味着在光标提取器设置与数据源结果映射不同的情况下可能存在不一致的地方。 3)希望我还没有考虑过的事情。我仍然可以轻松地重新设计完整的API

1 个答案:

答案 0 :(得分:0)

为了回答我自己的问题,我得出的结论是,处理它的唯一有效方法是要求用户使用fetch-query创建SQL游标,按照惯例,它必须能够使用fetch来获取单个实体数据源用于从db获取记录的相同投影。通过重用数据源的相同查询来创建游标索引(具有key,rowid对的数组)缓存。 为方便起见,实体数组是从原始数据源查询创建的,当用户使用其中一个游标方法时,将创建实体数组 - 创建优化的SQL游标。

这样它将始终在默认模式下具有正确的映射(如前所述,当没有创建特殊光标时使用数据源中的entites数组),以及sql光标模式中的映射,这是用户创建它的责任

假设有任何不同之处是没有意义的,因为SQLite中没有真正的游标。