Xeo*_*oss 11 php mysql sql postgresql activerecord
那里有几个ActiveRecord样式的查询构建器库.有些是独立的,有些是内置于框架中的.但是,当涉及到复杂的SQL时,它们确实遇到了WHERE和HAVING子句的问题.将其他数据库放在一边 - 我试图想出一个MySQL和PostgreSQL兼容的WHERE()方法,可以解决这些当前方法的垮台.
接下来是一长串的想法和例子,展示了迄今为止我能想到的最好的想法和例子.但是,我似乎无法解决所有用例,我觉得我的部分解决方案很草率.任何可以用解决所有这些问题的方法回答的人不仅会回答这个问题 - 而且还会负责解决几年来一直困扰着PHP实施的问题.
共同运营商
= Equal
<> Not Equal
> Greater Than
< Less Than
>= Greater Than Or Equal
<= Less Than Or Equal
BETWEEN between values on right
NOT logical NOT
AND logical AND
OR logical OR
Run Code Online (Sandbox Code Playgroud)
示例where子句
SELECT ... FROM table...
WHERE column = 5
WHERE column > 5
WHERE column IS NULL
WHERE column IN (1, 2, 3)
WHERE column NOT IN (1, 2, 3)
WHERE column IN (SELECT column FROM t2)
WHERE column IN (SELECT c3 FROM t2 WHERE c2 = table.column + 10)
WHERE column BETWEEN 32 AND 34
WHERE column BETWEEN (SELECT c3 FROM t2 WHERE c2 = table.column + 10) AND 100
WHERE EXISTS (SELECT column FROM t2 WHERE c2 > table.column)
Run Code Online (Sandbox Code Playgroud)
where()子句在不同的当前库中使用了许多常见的ActiveRecord格式.
$this->db->where(array('session_id' => '?', 'username' => '?'));
$this->db->fetch(array($id, $username));
// vs with is_int($key)
$this->db->where(array('session_id', 'username'));
$this->db->fetch(array($id, $username));
// vs with is_string($where)
$this->db->where('session_id', '?');
$this->db->where('username');
$this->db->fetch(array($id, $username));
// vs with is_array($value)
$this->db->where('session_id', '?');
$this->db->where('username', array('Sam', 'Bob'));
$this->db->fetch(array($id));
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止的最终格式.它应该处理分组(...) AND (...)以及准备语句绑定参数("?"和":name").
function where($column, $op = '=', $value = '?', $group = FALSE){}
// Single line
$this->db->where('column > 5');
$this->db->where('column IS NULL');
// Column + condition
$this->db->where('column', '=');
// WHERE column = ? (prepared statement)
$this->db->where('column', '<>');
// WHERE column <> ? (prepared statement)
// Column + condition + values
$this->db->where('column', '=', 5);
// // WHERE column = 5
$this->db->where('column', 'IN', '(SELECT column FROM t2)');
// WHERE column IN (SELECT column FROM t2)
$this->db->where('column', 'IN', array(1,2,3));
// WHERE column IN (1, 2, 3)
$this->db->where('column', 'NOT IN', array(1,2,3));
// WHERE column NOT IN (1, 2, 3)
// column + condition + values + group
$this->db->where(
array(
array('column', '<', 20),
array('column', '>', 10)
),
NULL,
NULL,
$group = TRUE
);
// WHERE (column < 20 AND column > 10)
Run Code Online (Sandbox Code Playgroud)
:更新时间:
在我的问题过程中,我逐渐意识到,在你走得更深的时候,WHERE和HAVING条件只会越来越复杂.试图抽象甚至80%的功能将导致一个庞大的库只为WHERE和HAVING.比尔指出,对于像PHP这样的脚本语言来说,这是不合理的.
解决方案只是手工制作查询的WHERE部分.只要您"在列中使用,就可以在Postgre,SQLite和MySQL中使用相同的WHERE查询,因为它们使用几乎相同的SQL语法.(对于MySQL,你必须str_replace()勾选它们).
有一点,抽象伤害的程度超过了它的帮助,条件就是这样一个地方.
我在Zend_Db库上工作了很多,其中包括一个用于构造SQL查询的PHP 类.我决定试图处理所有可以想象的SQL语法WHERE和HAVING子句,原因如下:
PHP是一种脚本语言,可以在每个请求中解析和编译代码(除非您使用字节码缓存).所以PHP环境对庞大的代码库很敏感 - 比Java或C#或Python更重要,或者你有什么.因此,尽可能保持图书馆的精益是我们的首要任务.
Zend_Db我工作的所有库都是大约2,000行PHP代码.相比之下,Java Hibernate大约有118K行代码.但这并不是一个问题,因为Java库是预编译的,不需要在每个请求上加载.
SQL表达式遵循生成语法,这种语法比您展示的任何基于PHP的构造更紧凑,更易于阅读和维护.学习SQL表达式语法比学习可以模拟它的API要容易得多.你最终支持"简化语法".或者你从那个方式开始,发现自己被用户社区强迫进入Feature Creep,直到你的API变得非常复杂.
要调试使用这种API的应用程序,您不可避免地需要访问最终的SQL表达式,因此它是关于您可以拥有的最漏洞的抽象.
为SQL表达式使用基于PHP的接口的唯一好处是它可以帮助智能编辑器和IDE中的代码完成.但是当许多运算符和操作数使用字符串常量时'>=',你会破坏任何代码完成情报.
更新:我刚读了一篇很好的博客文章" 告别ORM".作者Aldo Cortesi建议在Python的SQLAlchemy中使用SQL表达式语言.Python中标准的语法糖和运算符重载(但PHP不支持)使这成为一种非常有效的查询生成解决方案.
你可能也会看看Perl的DBIx :: Class,但它最终会非常难看.
| 归档时间: |
|
| 查看次数: |
5234 次 |
| 最近记录: |