CodeIgniter Active Record与常规查询

Kob*_*rgh 7 database activerecord codeigniter

目前我使用CodeIgniter进行常规查询,即:

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

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

我发现在我看来,常规查询(正如我在我的示例中所示)更易读,更容易维护,因此我目前正在考虑保持常规查询.

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

谢谢

tom*_*ans 9

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

  • 对不起,已经超过一年,但我不明白为什么常规查询的结果没有加载到内存中...查询的结果保存在变量中然后返回...我不明白为什么是没有加载,如果它是一个常规查询,你能解释一下吗? (2认同)

Fre*_*out 7

我倾向于在大多数情况下更喜欢ActiveRecord.我发现它更具可读性,并且它使得构建动态查询变得更加容易,因为您不必将明显地连接原始SQL块.这意味着我可以向我的查询构建器添加各种条件,而不用大惊小怪,并提供一些非常容易阅读的东西.

有些东西,ActiveRecord的CodeIgniter实现非常不适合(并且让我想念Doctrine)并且我使用直接SQL,但它不会经常发生.


Muh*_*eel 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();    
Run Code Online (Sandbox Code Playgroud)


小智 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();
Run Code Online (Sandbox Code Playgroud)

当然这只是一个简单的例子,但是我已经构建了具有数百个行和条件的方法,可以改变通用的'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');
    }
}
Run Code Online (Sandbox Code Playgroud)

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)');
Run Code Online (Sandbox Code Playgroud)

如果你点不添加(),OR statament将影响整个where子句.所以,一旦你习惯了activerecord,它可以帮助很多,并且仍然可以快速和可读的查询.