我确信我不是唯一一个在看到一页充满SQL查询的代码时感到沮丧的人。ActiveRecord和其他ORM模式有助于减少项目中使用的大量SQL,但是在许多复杂查询的情况下,SQL的使用似乎不可避免。
我正在寻找有关如何与其余代码(或外部代码)一起组织SQL查询的意见,以防止其散布到各处?一个明显的想法是使用视图,但是在处理多个大型索引表等时,视图通常会成为性能问题的源头。
编辑1-我假设您已经将其分离到模型层中
我确信我不是唯一一个在看到一页充满SQL查询的代码时感到沮丧的人。ActiveRecord和其他ORM模式有助于减少项目中使用的大量SQL,但是在许多复杂查询的情况下,SQL的使用似乎不可避免。
我正在寻找有关如何与其余代码(或外部代码)一起组织SQL查询的意见,以防止其散布到各处?一个明显的想法是使用视图,但是在处理多个大型索引表等时,视图通常会成为性能问题的源头。
编辑1-我假设您已经将其分离到模型层中
Answers:
对我来说,SQL是业务逻辑代码的基本部分(在很多情况下,是大多数)。如果尝试将其与对返回的数据进行操作的代码分开,则更容易使代码的可理解性和可维护性失去平衡。
在我看来,读取数据,处理数据,写入数据,搜索数据...它们都是相似的操作,最好放在同一位置。
如果您开始感觉到查询的重复工作,那么您可能需要一个数据库视图或一个可以封装数据库访问方面的对象。
另一个技巧是实际上拥有一个好的数据库查询方法。在我编写的软件(PostgreSQL,MySQL,SQL Server)中,我确保大部分查询操作可以作为单个代码语句进行。
GetValue(SQL, [transaction], [array_of_params])
GetRow(SQL, [transaction], [array_of_params])
GetRowList(SQL, [transaction], [array_of_params])
GetValueList(SQL, [transaction], [array_of_params])
Execute(SQL, [transaction], [array_of_params])
这些(大致)是我确定的主要函数调用,它们是我的“连接对象”的一部分。这取决于语言以及您实际实现的语言,但是我的意思是保持它非常非常简单而轻松。
总之,将SQL视为编程的本机部分,并且不要为了抽象而抽象。
通常,最好有一个单独的模型层。有许多企业设计模式为构建此模型提供了方法。
最好将模型层分为3个子层-“实体”,“存储库”和“服务”。这将使您分离关注点,并从业务逻辑中将SQL集中在一个地方。
在这种情况下,所有数据检索代码(包括复杂的SQL)都将位于存储库中。因此,存储库的目标是将复杂的SQL语句隐藏在诸如这样的自解释方法之后getUsersWithActiveSubscription()
。
实体使用getter和setter抽象实际的DB表字段名称,可以在DB字段类型和您的应用程序/编程语言中可用的类型之间提供某种数据转换。如果您的ORM支持-实体可以处理关联。
服务层是业务逻辑的地方。服务使用存储库检索实体,对其进行操作并将其存储回去。