baiyuxiong 发表于 2015-3-18 14:48:12

如何避免在一次请求中,数据的多次查询?

对于同一个数据查询,比如当前登录用户个人信息,有可能会存在一次请求中多个地方都需要,比如控制器中,需要根据用户角色做权限判断,view中需要显示用户信息,model中需要使用这个用户的ID来查询关联数据,类库中要使用这个用户的邮箱来发邮件。

如果每次使用这个用户信息时,都去查库,对性能有比较大的影响,但是要实现一次查询到处可用的话,CI框架本身并没有特别的支持。如果是通过参数传递,比如controller调model的方法时,把用户信息传给model方法,这个函数就会显得很奇怪,通用性降低,不利于后期维护。

大家在项目中是怎么避免重复查询的?求指点。

gxcnvip 发表于 2015-3-18 15:26:57

session或者缓存文件,个人观点

yuzhigang5460 发表于 2015-3-19 09:39:14

本帖最后由 yuzhigang5460 于 2015-3-19 09:45 编辑

不像你问的问题,或者没看懂你问题的本质。:lol:lol

在一个请求里公用的数据,Controller是入口, 客户端首先会发送一些如查询参数或者post过来的数据,控制器用这些数据做入输入,通过使用model来获得更多的视图数据加载视图。 整个过程中,数据一旦加载后,利用已有的数据可以去加载更多数据。不能说已经查询了一次用户信息,现在要加载该用户发表的帖子,model又去加载一次用户信息和帖子信息,这显然不合理。

在一个Session里公用的数据, 一般会扩展一个Controller, 如:

class MY_Controller extends CI_Controller {
   
      protected $_data = array();
      protected $_user = array();
      protected $_is_login = false;
      public function __construct()
      {
                parent::__construct();
                $this->_pre_controller();
                $this->_fill_common_data();
      }
      private function _fill_common_data()
      {
                $this->_data['is_login'] = $this->_is_login;
                $this->load->model('setting_model', 'setting');
                //……
      }
      
      protected function _pre_controller()
      {
                $this->_user = $this->nsession->userdata('user');
                $this->_is_login = !empty($this->_user);
                if($this->_is_login){
                        $this->_data['user'] = $this->_user;
                }
               //……
      }


每次都可用user信息了,不用自己再多次加载。

另外如楼上所说,可以缓存一些数据库的数据,CI中已经提供了很多缓存驱动,但本质还是那个流程。

yuzhigang5460 发表于 2015-3-19 09:51:12

又看了一遍的你的问题。细粒度的方法要好于粗粒度的方法,通用性会高,而不是低,当然不能太细,难以维护。这是个权衡。

57sy.com(隐身中 发表于 2015-3-19 23:18:38

yuzhigang5460 发表于 2015-3-19 09:39
不像你问的问题,或者没看懂你问题的本质。

在一个请求里公用的数据,Controller是入口, 客户端 ...

你这个也是解决办法哈。。所有的控制器可以继承这个基类。。
调用用户的信息直接 $this->_user 把你的方法改进下 ,属性定义为public , 模版中 model都可以进行调用的!!!!{:soso_e100:}{:soso_e113:}

<?php
class MY_Controller extends CI_Controller {

      public $_data = array();
      public $_user = array();
      public $_is_login = false;
      public function __construct()
      {
                parent::__construct();
                $this->_pre_controller();
                $this->_fill_common_data();
      }
      private function _fill_common_data()
      {
                $this->_data['is_login'] = $this->_is_login;
                $this->load->model('setting_model', 'setting');
                //……
      }

      protected function _pre_controller()
      {
                $this->_user = $this->nsession->userdata('user');
                $this->_is_login = !empty($this->_user);
                if($this->_is_login){
                        $this->_data['user'] = $this->_user;
                }
               //……
      }


yuzhigang5460 发表于 2015-3-20 16:11:51

57sy.com(隐身中 发表于 2015-3-19 23:18
你这个也是解决办法哈。。所有的控制器可以继承这个基类。。
调用用户的信息直接 $this->_user 把你的方 ...

protected修饰符,子类一样可以直接用的。

baiyuxiong 发表于 2015-3-31 16:18:06

57sy.com(隐身中 发表于 2015-3-19 23:18
你这个也是解决办法哈。。所有的控制器可以继承这个基类。。
调用用户的信息直接 $this->_user 把你的方 ...

如果我调用了library,也需要这个用户的信息,那么是在library里自己再取一次还是在函数上添加用户信息的参数,由controller传进去?

57sy.com(隐身中 发表于 2015-3-31 17:22:34

baiyuxiong 发表于 2015-3-31 16:18
如果我调用了library,也需要这个用户的信息,那么是在library里自己再取一次还是在函数上添加用户信息的 ...

你在library里面完全可以获取到

57sy.com(隐身中 发表于 2015-3-31 17:23:16

baiyuxiong 发表于 2015-3-31 16:18
如果我调用了library,也需要这个用户的信息,那么是在library里自己再取一次还是在函数上添加用户信息的 ...

library 一般只是功能的实现, 一般不在里面进行其他的判断的

yuzhigang5460 发表于 2015-3-31 17:33:52

baiyuxiong 发表于 2015-3-31 16:18
如果我调用了library,也需要这个用户的信息,那么是在library里自己再取一次还是在函数上添加用户信息的 ...

controller传过去。
页: [1]
查看完整版本: 如何避免在一次请求中,数据的多次查询?