6

目前我将 CodeIgniter 与常规查询一起使用,即:

$sql = "
    SELECT *
    FROM my_table
    WHERE item_id > 1
";    
$q = $this->db->query($sql);

我已经开始研究 ActiveRecord,它看起来确实不错,并且无论使用哪个数据库驱动程序都具有构建查询的优势 - 但是,我通常每个项目都严格使用单个数据库类型,所以这并不是真正的对我有利。

我发现常规查询(正如我在我的示例中所做的那样)在我看来更具可读性和更容易维护,因此我目前正在考虑保持常规查询。

除了上面提到的原因,我应该选择哪个,以及出于什么原因?

谢谢

4

7 回答 7

9

对我来说,我更喜欢运行常规查询,CI 的活动记录会消耗大量内存。因为它会将所有结果加载到内存中。如果你明白我的意思。至于复杂性,最好使用常规查询而不是坚持 CI 的活动记录语法。

于 2013-01-25T15:02:39.483 回答
7

在大多数情况下,我倾向于更喜欢 ActiveRecord。我发现它更具可读性,并且它使构建动态查询变得更加容易,因为您不必费力地将原始 SQL 块显式连接在一起。这意味着我可以毫不费力地将各种条件添加到我的查询构建器中,并得出一些非常容易阅读的东西。

在某些情况下,ActiveRecord 的 CodeIgniter 实现非常不适合(这让我想念 Doctrine),我为此使用直接 SQL,但这种情况并不经常发生。

于 2013-01-28T02:08:59.617 回答
5

好吧,对于您厌倦了编写 SELECT blah blah 的简单查询,您可以使用活动记录稍微改变您的样式,因为在编写常规查询时,您很可能会出现语法错误。活动记录就是为此目的而设计的,除非您是专家,否则您不需要编写通常出错的可能性很高的语法。活动记录也提供了逃生设施。您不熟悉活动记录,它们(简单时)也是可读的。看看这个例子

$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();    
于 2013-01-25T14:21:19.303 回答
5

差不多两年后,我发现了这个问题。我的一些同事已经回答了几个优点或缺点,我只是想根据我的个人经验补充一点意见:

正如有人所说,我也混合了使用活动记录和纯直接 sql 用于非常复杂的查询,原因是当您需要一个接收大量操作系统参数并相应更改查询的方法时使用它非常简单。例如,我有一个方法可以接收一个名为“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 语句将影响整个 where 子句。所以,一旦你习惯了 activerecord,它可以提供很多帮助,并且仍然可以进行快速且可读的查询。

于 2014-11-09T14:46:51.220 回答
4

好吧,我的主要原因是它运行快速且安全。因为它会自动转义值等。但是当涉及到复杂的查询时,我建议使用普通的查询字符串。

(不是在谈论连接等。因为 codeigniter 支持它并且可读性很好)更像是枢轴查询,或者按行号选择(如下所示)

$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();
于 2013-01-25T13:59:55.577 回答
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 将它移动到查询的中间,我得到的结果不准确。

于 2013-05-07T08:55:30.907 回答
2

使用对象模型进行查询有很大的好处。虽然您可以执行字符串解析和连接以针对多个函数构建查询,但这非常耗时且极易出错。使用对象模型,您可以传递引用并继续构建查询或在执行前将其传递给预处理器。

一个人为的示例可能是自动将日期过滤器添加到具有 creation_date 字段的表的所有查询中。

CI 还允许您将原始 SQL 与对象模型很好地混合。基本上,您构建了一个自定义查询,该查询将结果返回给水合物对象。

于 2013-07-15T17:23:24.390 回答