我目前负责一个似乎与数据库非常亲密的过程.我的程序/脚本/框架的目标是从不同的数据源中实现统一.使用依赖注入的形式,我的进程在很高的水平上工作正常.每个数据源类型的实现都隐藏在最高级别的业务抽象中.大.我的问题是两个.
1)我有一个很长的段落(这是困扰我的长度),它在Perl空间中组装了一个如何将这些不同数据源转换为一个同类结束格式的SQL语句.所以SQL字符串总是取决于我正在使用的数据类型.WHERE子句依赖,FROM子句依赖,INSERT子句依赖,它全部依赖.这是高度依赖性让我感到困惑.如何以面向对象的方式对此过程进行建模?MagicObject-> buildSQL?这基本上就是我现在所拥有的,但感觉代码的所有部分都知道太多,因此它的长度.
2)如果我有一个能做某事的函数(构建SQL?),我是否将整个业务对象传入,然后在最后一分钟对它们进行字符串化?或者我是否尽早将它们串联起来,只让我的函数处理它需要的东西,而不是渲染对象本身?
编辑:虽然我不怀疑ORM的重要性,但我不认为我们还处于ORM领域.想象一下,美国,国家和虚构联盟的棒球数据都以不同的格式存储,具有不同的标准化水平.读取这些数据源并将它们放在一个统一的标准化池中是我的过程的工作.我觉得在我的过程之后发生了对这些物体采取行动的ORM空间.如果你愿意,我是一名数据看门人.由于缺少我创建的统一池,因此基本上没有业务对象可以采取行动.
编辑^ 2:引起我的注意,也许我没有详细描述问题空间.这是一个例子.
想象一下,你必须建立一个美国所有罪犯的主数据库.贵公司的服务是销售一种产品,该产品位于顶部并以干净,统一的格式提供对这些数据的访问.
这些数据由50个州公开提供,但格式完全不同.有些是一个数据文件,没有标准化.其他是CSV格式的规范化表格.有些是Excel文档.有些是TSV.甚至提供了一些在没有人工干预的情况下不完整的记录(其他,手动创建的数据源).
我的项目的目的是为50个州中的每个州制定一个"驱动程序",并确保该过程的最终产品是一个完美的关系模型中的犯罪分子的主数据库.一切都正确键入,架构完美,等等.
你想看看Fey.几个月前我开始在工作中使用它,虽然由于年龄的原因,实施仍然有严峻的角落,但它背后的想法是坚实的.F.ex.,从手册中略微改编一下查询:
my $user = $schema->table( 'user' ); my $q = Fey::SQL ->new_select ->select( $user->columns( 'user_id', 'username' ) ) ->from( $user );
现在你可以写一个这样的函数:
sub restrict_with_group { my ( $q, $table, @group_id ) = @_; my $group = $schema->table( 'group' )->alias; $q ->from( $table, $group ) ->where( $group->column( 'group_id' ), 'IN', @group_id ); }
这将增加从内部加入user
到group
还有一个WHERE
条件.瞧,您可以在主程序中编写以下内容:
restrict_with_group( $q, $user, qw( 1 2 3 ) );
但是这个restrict_with_group
函数适用于任何具有group
表的外键的查询!要使用它,请传递要限制的查询以及要应用限制的表,以及要将其限制到的组ID.
最后你会说,$q->sql( $dbh )
然后你会找到一串代表你在$q
对象中建立的查询的SQL .
因此,Fey基本上为您提供了原生SQL缺失的抽象功能.您可以从查询中提取可重用的方面,并将它们打包为单独的函数.
请不要编写自己的ORM.使用类似DBIx :: Class的东西.
您提到的所有这些问题都已解决,并且已在数千个其他应用程序中测试了该实现.坚持编写你的应用程序,而不是重新实现库.您可能实际上并未在应用程序中使用 DBIC,但您应该查看其实现方法; 特别是它如何逐步构建ResultSet(不是结果集,而是延迟查询).
如果你不想要一个ORM,但你想从没有直接字符串操作/连接的位组装SQL,请看看Fey,它可以做你想要的.
更新:亚里士多德Pagaltzis的答案要好得多.他实际上给出了Fey看起来像以及它如何帮助的例子.