zoukankan      html  css  js  c++  java
  • 【辅导】Task17 查询数据 主要知识点

    本任务以示例数据库Sakila为例,介绍如何使用面向对象mysqli,实现对数据库的参数化查询,重点是掌握PHP预处理语句的使用。

    1、面向对象mysqli

    Task16已经介绍了PHP访问数据库的三种方式:面向过程mysqli面向对象mysqliPDO。建议大家使用面向对象mysqli访问MySQL数据库。在需要访问其它类型数据库的时候,建议使用PDO。

    使用面向对象mysqli访问(查询)数据库的基本过程如下:

     

     

    2query()方法

    Mysqli类的query()方法,第2个参数默认值是MYSQLI_STORE_RESULT,另一个可选值是MYSQLI_USE_RESULT

    MYSQLI_STORE_RESULT:到数据库执行查询,并将结果保存到mysqli_result类对象。之后fetch时相当于在本地取数据。

    MYSQLI_USE_RESULT:启动逐行检索,实际上本次并没有查询,直到fetch时,每次向数据库请求一个结果行。

    总结:MYSQLI_STORE_RESULT 将查询结果缓存,处理效率较高,但内存开销比较大;MYSQLI_USE_RESULT有较低内存需求,但处理过程中需保留数据库连接。建议,使用MYSQLI_STORE_RESULT时优化SQL查询返回尽量少的数据;在需要返回大量数据时使用MYSQLI_USE_RESULT

    参阅:mysql中的MYSQLI_USE_RESULT和MYSQLI_STORE_RESULT模式分析

    2SQL查询

    对数据库的任何操作,不管是DQL(SELECT),还是DML(INSERT,UPDATE,DELETE),或者DDL(CREATE),只要写成SQL语句,交给mysqli类对象的query()方法就可以。因此:

    可以执行简单的SELECT的查询,如查询Customer表某些列;

    可以执行较为复杂的查询,如多表连接查询;

    可以查询视图(因为可以把视图看成是单表);

    可以执行存储过程;参看《PHP调用MYSQL存储过程实例》

    也可以对数据库进行添加、更新、删除操作,下个任务会讲;

    还可以建表、删表、增加或删除数据表列,等等。

    只要能描述成SQL语句,都可以交给query()函数去执行。

    3SQL查询时,遇到特殊列,如何处理?

    本任务教学视频中提到,当有如下SQL查询时:

     

    对于带有空格的列名,使用$row = $result->fetch_assoc();方法提取记录时,没有问题,可以使用$row['zip code']获取该列值。但使用$row = $result->fetch_object();方法提取记录时,使用$row->zip code或$row->zip_code都是错误的。解决办法有二:

    (1)如上图所示,给列名`zip code`起别名zip_code,可以使用$row->zip_code获取该列值。

    (2)直接使用$row->{'zip code'}。

    4、有参数的SQL语句(参数化查询)

    为什么SQL语句需要有参数?

    例如:我需要查询Customer表中id号为15的客户信息,SQL语句是:$sql='SELECT first_name,last_name FROM customer WHERE customer_id=15';

    但这里的客户ID号一般是由用户在网页表单上输入的,如:

    $id = $_POST['id'];

    这时你就要把用户输入的$id拼接在原来sql语句字符串里面,写成这样:

    $sql='SELECT first_name,last_name FROM customer WHERE customer_id='.$id;

    虽然PHP支持字符串里面变量转义,但在原理上是与字符串拼接是一回事的:

    $sql="SELECT first_name,last_name FROM customer WHERE customer_id={$id}";

    字符串拼接带来的最主要的问题是SQL注入漏洞,造成你的网站存在很大的安全问题。比如,在输入id号的文本框中用户输入的是这样的内容:

    20;insert into staff(`username`,`password`) values('hacker', 'cracked')

    这样,他就很轻松地在你的数据库里面增加了一个店员(管理员)了。如果你是用MySQL数据库的root账户来建立查询的,他简直就可以为所欲为了(添加一个管理员账户?改root账户密码?)

    所有我们必须使用有参数的SQL语句。因为参数限定了用户输入值只能与参数对应列匹配,从而避免了SQL注入。

    Mysqli的SQL语句的参数只能使用?, 对参数赋值只能按先后顺序进行赋值。PDO可以使用命名参数。

     

     

    5、有参数的SQL语句,使用prepare()函数来建立预处理语句

     

    注意几点:

    (1)使用mysqli时,bind_param()方法绑定参数的顺序与类型一定要与sql语句中?的顺序与类型保持严格一致;

    s-string, i-integer, d-double, b-blob

    (2)执行Select查询时,需要使用bind_result()方法绑定结果变量,结果变量顺序与SQL语句中列名顺序一致。

    (3)使用execute()方法执行查询后,要使用store_result()方法将结果缓存,保存到mysqli_stmt对象,之后使用fetch()方法才能提取到每行记录的数据。

    6、掌握mysqli_stmt对象的以下方法

    bind_param():绑定参数变量。

    bind_result():绑定结果变量,对select查询需要。

    execute():执行预处理语句定义的查询。

    store_result():保存查询结果,对select查询必须。

    fetch():从结果中提取记录到绑定的结果变量

    7、课后练习

    先参照课件,完成对Sakila数据库Customer表的参数化查询。不懂的地方再回顾视频,或者QQ上问我。

    有基础以后,试试自己编写检索程序,按特定条件查询Sakila数据库其它表的数据(如查询有什么名字的影片,查询xxx主演电影有哪些,顾客中有哪些是中国的)

    也可以使用自己创建的数据库,或你前期上其它课程建立的数据库,练习下PHP条件查询的实现。

    考虑到大家线下练习比较困难,最近基本上没有布置实验作业,有条件的请根据上述要求做下练习。返校后,将把一些本应布置的实验作业内容整合到实训中去练习。

  • 相关阅读:
    Juniper路由器
    Juniper交换机维护
    [转载]让你瞬间开悟的图片
    [转载]生命科学-人体生物磁场及特异作用
    NAS与SAN有什么区别?
    使用串口终端安装AIX操作系统
    xml与java代码相互装换的工具类
    mybatis思维导图(二)
    mybatis思维导图(一)
    Spring思维导图(AOP篇)
  • 原文地址:https://www.cnblogs.com/whitewin/p/12926748.html
Copyright © 2011-2022 走看看