本学习课程以学习为目的一周三篇持续更新,学习代码更新在码云公开仓库,不足之处欢迎朋友们前来指导,写作不易请多多支持,本人创作新手写的不好,不喜勿喷,谢谢大家。

学习目标

  1. 单条数据查询
  2. 查询数据集
  3. 值和列查询
  4. 海量数据优化查询
  5. 查询规则
  6. 查询对象保存调用(相当于单例)

一.单条数据查询

码云提交编号:10921f8cd191d1caa45c03e53af52a472845ad0a

  1. 首先贴一下数据库表以便配套代码(不需要可以忽略),当然大家也可以自己创建啊
    CREATE DATABASE `tp60-learning` ;USE `tp60-learning`;DROP TABLE IF EXISTS `tp_user`;CREATE TABLE `tp_user` (
      `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT COMMENT '自动编号',
      `username` varchar(20) NOT NULL COMMENT '用户名',
      `password` char(40) NOT NULL COMMENT '密码',
      `gender` char(1) NOT NULL DEFAULT '1' COMMENT '性别',
      `email` varchar(50) DEFAULT NULL COMMENT '邮箱',
      `remarks` text NOT NULL COMMENT '备注',
      `status` tinyint(3) NOT NULL DEFAULT '0' COMMENT '状态',
      `delete_time` datetime DEFAULT NULL,
      `create_time` datetime NOT NULL COMMENT '创建时间',
      `update_time` datetime NOT NULL COMMENT '修改时间',
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
    LOCK TABLES `tp_user` WRITE;insert  into `tp_user`(`id`,`username`,`password`,`gender`,`email`,`remarks`,`status`,`delete_time`,`create_time`,`update_time`) values (1,'反贼唐三','e10adc3949ba59abbe56e057f20f883e','1','123@qq.com','老铁66',0,NULL,'2022-03-23 20:09:27','2022-03-23 20:09:27'),(2,'张三','e10adc3949ba59abbe56e057f20f883e','1','123@qq.com','老铁66',0,NULL,'2022-03-23 20:09:27','2022-03-23 20:09:27'),(3,'李四','e10adc3949ba59abbe56e057f20f883e','1','123@qq.com','老铁66',0,NULL,'2022-03-23 20:09:27','2022-03-23 20:09:27'),(4,'王二','e10adc3949ba59abbe56e057f20f883e','1','123@qq.com','老铁66',0,NULL,'2022-03-23 20:09:27','2022-03-23 20:09:27'),(5,'码字','e10adc3949ba59abbe56e057f20f883e','1','123@qq.com','老铁66',0,NULL,'2022-03-23 20:09:27','2022-03-23 20:09:27'),(6,'赵六','e10adc3949ba59abbe56e057f20f883e','1','123@qq.com','老铁66',0,NULL,'2022-03-23 20:09:27','2022-03-23 20:09:27');UNLOCK TABLES;
    
  2. Db::table()table 必须指定完整数据表(包括前缀)
  3. 如果希望只查询一条数据,可以使用 find() 方法,需指定 where 条件
    <?phpnamespace app\controller;use think\facade\Db;class DatabaseSite
    {
        public function index(){
            $user = Db::table('tp_user')->where('id',1)->find();
            return json($user);
        }}

  4. Db::getLastSql() 方法,可以得到最近一条 SQL 查询的原生语句,没有查询到结果会返回null
            $user = Db::table('tp_user')->where('id',1)->find();
    //      return json($user);
            return Db::getLastSql();
    //      得到的结果是
    //      SELECT * FROM `tp_user` WHERE `id` = 1 LIMIT 1
            

  5. 使用 findOrFail() 方法同样可以查询一条数据,在没有数据时抛出一个异常
            $user = Db::table('tp_user')->where('id',100)->findOrFail();
            return json($user);

  6. 使用 findOrEmpty()方法也可以查询一条数据,但在没有数据时返回一个空数组
            $user = Db::table('tp_user')->where('id',100)->findOrEmpty();
            return json($user);
    

二.查询数据集

  1. 想要获取多列数据,可以使用 select()方法,获取所有数据
            $user = Db::table('tp_user')->select();
            return json($user);

  2. 多列数据在查询不到任何数据时返回空数组,使用 selectOrFail()抛出异常
            $user = Db::table('tp_user')->where('gender',2)->selectOrFail();
            return json($user);
    

  3. select()方法后再使用 toArray()方法,可以将数据集对象转化为数组
           $user = Db::table('tp_user')->select()->toArray();
            dump($user);
    

  4. 当在数据库配置文件中设置了前缀,那么我们可以使用 name()方法忽略前缀
            $user = Db::name('user')->select();
            return json($user);

 三.值和列查询

  1. 通过 value() 方法,可以查询指定字段的值(单个),没有数据返回 null
            $user = Db::name('user')->where('id', 1)->value('username');
            return $user;
    

  2. 通过 colunm()方法,可以查询指定列的值(多个),没有数据返回空数组,可以指定 id 作为列值的索引
            $user =Db::name('user')->column('username','id');
            return json($user);

 四.海量数据优化查询 

  1. 如果处理的数据量巨大,成千上万那种,一次性读取有可能会导致内存开销过大,为了避免内存处理太多数据出错,可以使用 chunk() 方法分批处理数据
  2. 该方法一次获取结果集的一小块,然后填充每一小块数据到要处理的闭包,该方法在编写处理大量数据库记录的时候非常有用
  3. 这里配置一个数据库mysql3并用连接connect('mysql3'),分批处理goods表前100000条数据,每次处理1000条,
  4. 为了验证他真的是每次只处理1000条数据 ,我们用echo "每处理1000数据后,输出标记点"
    Db::connect('mysql3')->table('goods')->where('id','<',100000)->chunk(1000, function($users) {
        foreach ($users as $user) {
            echo $user['id']."**";
        }
        echo "每处理10000数据后,输出标记点";
    });

  5. 接下来验证他是否真的能节省内存开销,我们以相同的条件和操作,写一个select查询,
    //chunk测试
    Db::connect('mysql3')->table('goods')->where('id','<',100000)->chunk(1000, function($users) {
        foreach ($users as $user) {
            echo $user['id']."**";
        }});//select测试
    $users = Db::connect('mysql3')->table('goods')->where('id','<',100000)->select();
        foreach ($users as $user) {
            echo $user['id']."**";
        }
    

  6. 你可以通过从闭包函数中返回 false来中止对后续数据集的处理
    Db::connect('mysql3')->table('goods')->where('id','<',100000)->chunk(1000, function($users) {
    foreach ($users as $user) {
        if($user['id']==1003){
            return false;
        }
        echo $user['id']."--";
        echo $user['name']."<br>";
    }
    echo "每处理10000数据后,输出标记点";
    });
  7. chunk方法的处理默认是根据主键查询,支持指定字段,并且支持指定处理数据的顺序
    Db::connect('mysql3')->table('goods')->where('id','<',1000)->chunk(10, function($users) {
    foreach ($users as $user) {
        if($user['id']==15){
            return false;
        }
    //    echo $user['id']."--";
    //    echo $user['name']."<br>";
        dump($user);
    }
    echo "每处理10000数据后,输出标记点";
    },'id', 'desc');
  8. 果你需要处理大量的数据,可以使用新版提供的游标查询功能,该查询方式利用了PHP的生成器特性,可以大幅减少大量数据查询的内存开销问题。
  9. 它每次查询只读取一行数据,然后再读取时,自动定位到下一行继续读取,
    $cursor = Db::table('user')->where('status', 1)->cursor();
    foreach($cursor as $user){
    	echo $user['name'];
    }
  10. 那我们测试一下他的内存占用情况,写一个select查询和cursor查询,和相同的遍历输出操作
    //select查询
    $users = Db::connect('mysql3')->table('goods')->where('id','<',100000)->select();
        foreach ($users as $user) {
            echo $user['id']."**<br>";
        }
    //游标查询
    $users = Db::connect('mysql3')->table('goods')->where('id','<',100000)->cursor();
        foreach ($users as $user) {
        echo $user['id']."**<br>";
        }

五.查询规则

码云提交编号:b5beec6d4b35649ac274d7d5e71bd72b7f2ccb6f

  1. 前面课程中我们通过指向符号“ -> ”多次连续调用方法称为:链式查询
  2. Db::name('user') 时,返回查询对象 (Query) ,即可连缀数据库对应的方法
    $users = Db::connect('mysql3')->table('goods');
    dump($users);
    ^ think\db\Query {#52 ▼
      #connection: think\db\connector\Mysql {#50 ▶}
      #name: ""
      #pk: null
      #autoinc: null
      #prefix: "tp_"
      #options: array:1 [▼
        "table" => "goods"
      ]
      #timeRule: array:8 [▼
        "today" => array:2 [▶]
        "yesterday" => array:2 [▶]
        "week" => array:2 [▶]
        "last week" => array:2 [▶]
        "month" => array:2 [▶]
        "last month" => array:2 [▶]
        "year" => array:2 [▶]
        "last year" => array:2 [▶]
      ]
      #model: null
      #bind: []
    }
  3. 而每次执行一个数据库查询方法时,比如 where() ,还将返回查询对象 (Query)
    $users = Db::connect('mysql3')->table('goods')->where('id','<',3);
    dump($users);
    ^ think\db\Query {#52 ▼
      #connection: think\db\connector\Mysql {#50 ▶}
      #name: ""
      #pk: null
      #autoinc: null
      #prefix: "tp_"
      #options: array:2 [▼
        "table" => "goods"
        "where" => array:1 [▼
          "AND" => array:1 [▼
            0 => array:4 [▼
              0 => "id"
              1 => "<"
              2 => 100000
              3 => null
            ]
          ]
        ]
      ]
      #timeRule: array:8 [▶]
      #model: null
      #bind: []
    }
  4. 只要还是数据库对象,那么就可以一直使用指向符号进行链式查询
  5. 再利用 find() select() 等方法返回数组 (Array) 或数据集对象 (Colletion)
    $users = Db::connect('mysql3')->table('goods')->where('id','<',3)->select();
    dump($users);
    ^ think\Collection {#53 ▼
      #items: array:2 [▼
        0 => array:14 [▶]
        1 => array:14 [▼
          "id" => 2
          "name" => "将很快"
          "category_id" => 2
          "store_id" => 2
          "status" => 0
          "use_flag" => 0
          "create_time" => "2020-12-12 00:00:00"
          "update_time" => "2021-12-13 00:00:00"
          "up_time" => "2022-12-12 00:00:00"
          "down_time" => "0000-00-00 00:00:00"
          "description" => "12321"
          "keywords" => "121"
          "min_price" => "121"
          "max_price" => "2121"
        ]
      ]
    }
    $users = Db::connect('mysql3')->table('goods')->where('id','<',3)->find();
    dump($users);
    ^ array:14 [▼
      "id" => 1
      "name" => "12"
      "category_id" => 2
      "store_id" => null
      "status" => null
      "use_flag" => null
      "create_time" => null
      "update_time" => null
      "up_time" => null
      "down_time" => null
      "description" => null
      "keywords" => null
      "min_price" => null
      "max_price" => null
    ]

六.查询对象保存调用(相当于单例)

  1. 如果多次使用数据库查询,那么每次静态创建都会生成一个实例,造成浪费,但我们可以把对象实例保存下来,再进行反复调用即可;
    $sqlquery = Db::name('user');
    $dataFind = $sqlquery->where('id', '<',5)->find();
    $dataSelect = $sqlquery->select();
  2. 但是,当同一个对象实例第二次查询后,会保留第一次查询的值,我们
    $sqlquery = Db::name('user');
    $dataFind = $sqlquery->where('id', '<',5)->find();
    $dataSelect = $sqlquery->select();
    return Db::getlastSql();

    SELECT * FROM `tp_user` WHERE `id` < 5

    这里有一个where条件,但是我们进行select查询时并没有执行where操作

  3. 使用 removeOption()方法,可以清理掉上一次查询保留的值
    $sqlquery = Db::name('user');
    $dataFind = $sqlquery->where('id', '<',5)->find();
    $dataSelect = $sqlquery->removeOption('where')->select();
    return Db::getlastSql();

    SELECT * FROM `tp_user`

  4. removeOption()方法,
    /**
     * 去除查询参数
     * @access public
     * @param string $option 参数名 留空去除所有参数
     * @return $this
     */

点赞(3) 打赏

评论列表 共有 0 条评论

暂无评论

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部