zoukankan      html  css  js  c++  java
  • 谈下mysql预处理基础

    传统的操作数据库方法有两种:

    1. 先写一条sql语句,然后通过mysqli->query($sql)去操作数据库(此处使用的是mysqli扩展库)。这样操作并不会有什么大的错误,但是当要插入上千条上万条数据呢?难道也还是要这样写一条sql语句然后再操作一下数据库?这里我说下mysqli自带的操作多条sql语句的方法,即第二种方法。
    2. mysqli->multi_query($sql),这是操作多条sql语句的方法,如下:
      insert into student(name,age,sex,studentNo,grade) values('马特','14','','20170809','六年级'),('凯文','15','','20170810','七年级')

      如果你认为这样就可以完全解决问题,那么你就错了,接下来让我们来看一看MySQL数据库执行sql语句的原理!

      从上图可以看出,无论我们是发送一条sql语句还是发送多条sql语句,数据库都要对其一一的进行编译,那么当数据达到一定量之后,数据库的开销就必然很大。那究竟怎样解决这个问题呢?此时就引入了预处理技术的概念。

      下面我们来看一段预处理技术的代码:
      student表结构如下:

      CREATE TABLE `student` (
        `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
        `age` int(11) DEFAULT NULL COMMENT '年龄',
        `name` varchar(20) CHARACTER SET utf8 DEFAULT NULL COMMENT '姓名',
        `sex` varchar(2) CHARACTER SET utf8 DEFAULT NULL COMMENT '性别',
        `studentNo` varchar(20) DEFAULT NULL,
        `grade` varchar(20) CHARACTER SET utf8 DEFAULT NULL COMMENT '班级',
        PRIMARY KEY (`id`)
      ) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
      <?php
      /**
       * Created by PhpStorm.
       * User: Administrator
       * Date: 2017/7/22
       * Time: 10:52
       */
      $mysqli = new mysqli("localhost", "root", "root", "test");
      if ($mysqli->connect_error) {
          die("连接失败" . $mysqli->error);
      }
      $mysqli->query("set names utf8");//设置编码格式为utf-8,这样数据库展示中文的时候才不会出错
      $sql = "insert into student(name,age,sex,studentNo,grade) values (?,?,?,?,?)";
      //向数据库发送sql语句,让数据库对该sql语句先进行编译
      $mysqli_stmt = $mysqli->prepare($sql);
      if( !$mysqli_stmt ) {
          die( $mysqli->error );
      }
      //绑定参数
      $name = "珀利";
      $age = 13;
      $sex = '男';
      $stuNo = "201501225";
      $grade = '四年级';
      
      $mysqli_stmt->bind_param("siisd", $name, $age, $sex, $stuNo, $grade);
      $mysqli_stmt->execute();//执行
      $mysqli->close();//关闭连接

      首先我们来看

      $sql = "insert into student(name,age,sex,studentNo,grade) values (?,?,?,?,?)";
      ?这里的问号相当于一个占位符,之后只要向数据库发送数据就能够自动把数据对应的填充进去
      
      这就是预编译技术的精髓之处,我们通过$mysqli_stmt = $mysqli->prepare($sql);向数据库发送sql语句,然后数据库对该sql语句进行编译,
      并且数据库不会立即释放掉编译的结果。 $mysqli_stmt
      ->bind_param("siisd", $name, $age, $sex, $stuNo, $grade);bind_param,顾名思义,就是绑定参数的意思,那么,它给谁绑定参数呢?
      看看上面的values (?,?,?,?,?),bind_param里面的参数一一对应着values的每一个参数。那么bind_param里面的siisd又是什么意思呢?别急,请看下方:

      参数有以下四种类型: 
        i - integer(整型) 
        d - double(双精度浮点型) 
        s - string(字符串) 
        b - BLOB(布尔值) 
        每个参数都需要指定类型。 
        通过告诉数据库参数的数据类型,可以降低 SQL 注入的风险.
        $mysqli_stmt->execute();这句代码就是将数据传递给数据库了。

      我们来用预处理查询数据库:

      <?php
      
      $mysqli = new mysqli("localhost","root","root","test");
      if($mysqli->connect_error){
          die("连接失败".$mysqli->error);
      }
      $mysqli->query("set names utf8");
      
      $sql="select name,sex,age from student where id>?";
      
      $mysqli_stmt=$mysqli->prepare($sql);
      if( !$mysqli_stmt ) {
          die( $mysqli->error );
      }
      $id=1;
      $mysqli_stmt->bind_param("i",$id);
      $mysqli_stmt->execute();
      
      $mysqli_stmt->bind_result($name,$sex,$age);//绑定结果集,传递的是引用
      while($mysqli_stmt->fetch()){
          echo "$name:$sex:$age"."<br>";
      }
      
      $mysqli_stmt->free_result();//关闭资源
      $mysqli_stmt->close();//关闭预编译语句,否则数据库会一直保存
      $mysqli->close();//关闭连接
      输出:
      马特:男:14
      凯文:女:15 

      我们看到有这么一句:

      $sql="select name,sex,age from student where id>?";

      看看这句sql语句,你会发现bind_result里面的参数一一对应于sql语句当中你要查询的字段(name,sex,age),当然,bind_result里面的参数可以不与sql语句的字段名字相同,但是通常推荐这样做。

  • 相关阅读:
    hdu5608 function
    Codeforces Round #535 (Div. 3) 解题报告
    HDU4746 Mophues
    HDU5663 Hillan and the girl
    AtCoder Beginner Contest 117 解题报告
    GDOI2018D2T1 谈笑风生
    BZOJ4018: 小Q的幻想之乡
    牛客寒假算法基础集训营6 解题报告
    win32拖拽编程
    项目开发中的贝塞尔曲线
  • 原文地址:https://www.cnblogs.com/phpper/p/7220849.html
Copyright © 2011-2022 走看看