目前我使用CodeIgniter进行常规查询,即:
$sql = "
SELECT *
FROM my_table
WHERE item_id > 1
";
$q = $this->db->query($sql);
我已经开始研究ActiveRecord,它确实看起来不错,并且无论使用哪个数据库驱动程序都具有构建查询的优势 - 但是,我通常严格按照每个项目使用一个数据库类型,所以这是对我来说并没有什么好处。
我发现常规查询(正如我在我的示例中所示)在我看来更易读,更容易维护,因此我目前正在考虑保持常规查询。
除了上面提到的原因,我应该选择哪个,以及出于什么原因?
谢谢
答案 0 :(得分:8)
对我来说,我更喜欢运行常规查询,CI的活动记录消耗大量内存。因为它会将所有结果加载到内存中。如果你明白我的意思。至于复杂性,最好采用常规查询而不是CI的主动记录sytax。
答案 1 :(得分:7)
我倾向于更喜欢ActiveRecord。我发现它更具可读性,并且它使得构建动态查询变得更加容易,因为您不必将明显地连接原始SQL块。这意味着我可以向我的查询构建器添加各种条件,而不用大惊小怪,并提供一些非常容易阅读的内容。
ActiveRecord的CodeIgniter实现有一些非常适合的东西(并且让我想念Doctrine)并且我使用直接SQL,但它不会经常发生。
答案 2 :(得分:5)
对于简单的问题,你厌倦了编写SELECT blah blah,你可以使用活动记录稍微改变你的风格,因为在编写常规查询时,很可能会产生syntex错误。活动记录是为此目的而设计的,除非您是专家,否则您不需要编写使用语法,其中出错的可能性很高。活动记录也提供逃避设施。您不熟悉它们(简单)可读的活动记录。看一下这个例子
$array = array(
'user.username',
'user.email',
'user.password',
'other.blah',
'other.blah'
);
$where = array(
'active' => 1,
'other' => 'blahblah'
);
return $this->db
->select($array)
->from('user')
->join('other','other.user_id = user.id','left')
->where($where)
->get()
->result();
答案 3 :(得分:5)
差不多两年后,我发现了这个问题。我的一些同事已经回答了几个优点或缺点,我只想根据个人经验添加一个观点:
正如一些人所说,我也混合使用有效记录一些时间和纯直sql用于非常复杂的查询,原因是当你需要一个接收大量os参数的方法并相应地更改查询时,使用它非常简单。例如,我有一个接收名为'options'的参数数组的方法:
if(!empty($options['login']))
{
$this->db->where('tl.login', $options['login']);
}
if(!empty($options['ip']))
{
$this->db->where('tl.ip', $options['ip']);
}
if(!empty($options['sucesso']))
{
$this->db->where('tl.sucesso', $options['sucesso']);
}
if(isset($options['usuarios_existentes']) && $options['usuarios_existentes'])
{
$this->db->join('usuario u', 'tl.login = u.login');
}
else
{
$this->db->join('usuario u', 'tl.login = u.login', 'LEFT');
}
if(!empty($options['limit']))
{
$this->db->limit($options['limit']);
}
else
{
$this->db->limit(50);
}
return $this->db->select('tl.id_tentativa_login, tl.login, DATE_FORMAT(tl.data, "%d/%m/%Y %H:%i:%s") as data, tl.ip, tl.sucesso', FALSE)
->from('logs.tentativa_login tl')
->order_by('tl.data', 'DESC')
->get()->result();
当然这只是一个简单的例子,但是我已经构建了数百个可以改变通用'get'方法的行和条件的方法,而且活动记录使它非常好并且非常易读,因为你不需要编写代码在它的中间正确格式化查询。
你甚至可以有连接和其他有条件的东西。所以你可以使用通用的集中式方法,这样可以避免重写大部分代码并复制它的一部分(对于维护来说很糟糕),它不仅可读,但它可以快速查询您的查询,因为只加载您需要的内容:
if(!empty($opcoes['com_maquina']))
{
if(strtoupper($opcoes['com_maquina'])=='SIM')
{
$this->db->join('maquina m', 'm.id_local = l.id_local');
}
elseif(strtoupper($opcoes['com_maquina'])=='NAO')
{
$this->db->join('maquina m', 'm.id_local = l.id_local', 'LEFT');
$this->db->where('m.id_maquina IS NULL');
}
}
activerecord的另一个好处是它在语句中接受纯SQL,比如子查询和其他东西,所以你可以随意使用它。
我说的是优点,但很明显,纯SQL总是会更快地执行,并且不会有调用函数的开销。但说实话,在大多数情况下,php解析器会这么快就会以一种富有表现力的方式影响最终结果,如果你必须制作大量的手动条件,你的代码可能和activerecord一样慢解析器无论如何。
请注意,有时activerecord查询将无法按预期方式工作,因为它尝试以编程方式执行的逻辑方式构建查询,因此在使用“OR”语句时要小心,例如,大多数时候你必须隔离它(和):
$this->db->where('(m.ultimo_status < DATE_ADD(NOW(), INTERVAL -2 HOUR) OR m.ultimo_status IS NULL)');
如果你没有添加(),OR statament将影响整个where子句。 因此,一旦你习惯了activerecord,它可以帮助很多并且仍然可以快速和可读的查询。
答案 4 :(得分:4)
嗯,我的主要原因是它快速而安全。因为它会自动转义值等。但是当谈到复杂查询时,我建议使用普通的查询字符串。
(不是谈论联接等等因为codeigniter支持它非常好并且可读)更像是数据库查询,或者通过rownumber选择(如下所示)
$query = $this->db->query('SELECT * FROM
(SELECT @row := @row + 1 as row, t.*
FROM `default_red_albums` t, (SELECT @row := 0) r) AS view
WHERE `row` IN(' . $in . ')');
return $query->result();
答案 5 :(得分:2)
ActiveRecord并不总是按您希望的顺序生成查询,这可能会导致不可预测的结果。例如,这个模型:
$this->db->select('page, content');
$this->db->from('table');
$array = array('title' => $searchq, 'content' => $searchq);
$this->db->or_like($array, 'both');
$this->db->where('showsearch', 'Yes');
return $this->db->count_all_results();
生成此查询:
SELECT COUNT(*) AS `numrows`
FROM (`table`)
WHERE `showsearch` = 'Yes'
AND `title` LIKE '%term%'
OR `content` LIKE '%term%'
但是我希望在查询结束时检查showsearch
,这就是我把它放在首位的原因。但ActiveRecord将其移动到查询的中间,我得到的结果不准确。
答案 6 :(得分:2)
使用对象模型进行查询有很大好处。虽然您可以执行字符串解析和连接以在多个函数上构建查询,但这非常耗时并且极易出错。使用对象模型,您可以传递引用并继续构建查询或在执行之前将其传递给预处理器。
一个人为的例子可能是自动为带有creation_date字段的表的所有查询添加日期过滤器。
CI还允许您将原始SQL与对象模型相当好地混合。基本上,您构造一个自定义查询,返回结果以水合对象。