zoukankan      html  css  js  c++  java
  • mysql数据库

    1、概念

    概念:按照数据结构来组织、存储、管理数据的仓库。

    计算机的发明是为了做科学计算,科学计算需要大量的数据输入和输出。

    早期使用打孔卡片机、灯泡的亮灭来表示数据输入、输出。

    后来,数据存储在磁带上,顺序的读取,写入磁带。

    1956年IBM发明了磁盘驱动器,支持随机访问。

    信息化时代的到来,有了硬件存储技术的发展,有大量的数据需要存储和管理,数据库管理系统DBMS就诞生了。

    不管是什么存储介质,数据库的数据模型才是其核心和基础。

    2、分类

    按照数据模型分类:网状数据库、层次数据库、关系型数据库

    层次数据库:以树形结构表示实体及其之间的关系,关系只支持一对多,代表数据库IBM IMS。

    网状数据库:通用电气最早1964加加开发出网状数据库IDS,只能运行在ge自家的主机上。

    结点描述,结点的联系就是数据的关系。

    能够直接描述客观世界,可以表示实体间多种复杂关系,而这时层次数据库模型无法做到的,一个节点可以有多个父节点,节点之间支持多以多对多关联。

    (mysql安装和简单命令,1)开源协议的选型,gpl。)

    关系数据库:DBMS:

    使用行、列组成的二维表来组织数据和关系,表中行(纪录)即可以描述数据实体,也可以描述实体间的关系。

    关系模型比网状模型、层次模型更简单,不需要关系数存储的物理细节,专心于数据的逻辑构建,而且关系模型有论文的严格的数学理论基础支撑。

    基于关系模型构建的数据库系统成为RDBMS(relational  database system)

    Oracle发展:

    MySQL发展:

    去IOE概念:

    阿里巴巴造成的概念,本意中,在阿里巴巴的IT架构中,去掉IBM的小型机,oracle数据库。

    Nosql:对非SQL、非传统关系型数据库的统称。

    MongoDB:json类型的数据库。   nosql

    Redis:内存性的key-value性数据库。缓存数据库。nosql

    SQLite:关系型数据库,文件型的,不启动数据库的话,就在本地启动缓存数据库。

    Solr:搜索引擎。

    Elasticsearch:分布式,搜索引擎。搜索压力较大的时候利用此引擎。

    Cassandra:列存数据库。

    Hbase:国内用的较多。海量数据,想存多少都可以。

    MySQL:基于tcp协议通信的。是一种关系型数据库管理软件,支持网络访问,默认服务端口3306。Mysql通信使用mysql协议。

    3、安装

    1)导入Per文件,test.sql文件,解压文件,yum install 安装文件。

    2)Service mysql start 启动服务。Mysql_secure_installation设置服务。

    3)Mysql -uroot -p < test.sql 导入库。

    4)mysql> grant all on *.*  to 'wang'@'%' identified by 'wang';   增加权限,什么库上什么表中哪些文件给哪个用户在哪个主机端登录,密码是什么。%表示主机端。

    5)选择可视化软件登录

    4、SQL语句

    SQL是结构化查询语言structured query language。所有主流的关系型数据库都支持SQL,nosql也有很大一部分支持SQL。

    SQL语句分为:

    DDL数据定义语言,负责对数据库定义、数据库对象定义,有create、alter与drop三个语法所组成。

    DML数据操作语言,负责对数据库对象的操作,crud增删改查。

    DCL数据控制语言,负责数据库权限访问控制,由grant和revoke两个指令组成。

    TCL事务控制语言,负责处理acid事务,支持commit、rollback指令。

    SQL语句大小写不敏感。

    SQL语句末尾应该使用分号分开。

    5、DCL操作

    grant授权、revoke撤销。

    grant all on *.*  to 'wang'@'%' identified by 'wang';

    Revoke all on *.* from wang;

    6、DDL操作

    1)删除用户

    Drop user xxx;

    2)创建数据库

    库是数据的集合,所有数据按照数据模型组织在数据库中。

    Create database if not exists gogs  character set utf8mb4 collate utf8mb4_general_ci;

    Character set 指定字符集,utf8mb4是utf8的扩展,支持4字节utf8mb4,需要mysql5.5.3+。

    Collate指定字符集的校对规则,用来做字符串比较的,例如a和A谁大。

    3)删除数据库

    Drop databases if exists gogs;

    4)创建表

    表分为行和列,mysql是行存数据库,数据是一行行存的,列必须固定多少列。

    7、Primary key 主键:

    表中一列或者多列组成唯一的key,也就是通过这一个或者多个功能能唯一的标识符。

    行row,也成为记录record,元组。

    列column,也成为字段field。

    主键的列不能包含空值null,主键往往设置为整形,长整形,且自增auto_increment.

    表中可以没有主键,但是一般设计表的时候,往往都会有主键。

    反引号标注的名字,被成为是非关键字。

    Desc查看列信息。

    8、索引index

    可以看做是资本字典的目录,为了快速检索用的,空间换时间,显著提高查询效率。K

    可以对一列或者多列字段设置索引。

    索引只是为了查看方便,不是为了插入这些等。

    可以对一列或者多列字节设定索引。

    主键索引,主键会自动建立主键索引,主键本身就是为了快速定位唯一记录的。

    唯一索引,表中的索引列组成的索引必须唯一,但可以为空,非空值必须唯一。

    普通索引,没有唯一性的要求,就是建立一个字典的目录而已。

    (删除改动是需要更改索引的)读写索引。

    数据库是唯一的资源,争抢的模式。

    9、约束constraint

    唯一键约束(unique)

    定义了唯一键索引,就是定义了唯一键约束

    Primary key约束

    定义了主键,就是定义了主键约束。

    外键约束foreign key

    外键,在表B中的列,关联表A中的主键,表B中的列就是外键。

    10、视图

    视图、虚拟表(虚表),看起来像表是由查询语句生成的,可以通过视图进行crud操作。

    视图的作用:

    简化操作,将复杂查询的SQL语句定义为视图,可以简化查询。

    数据安全,视图可以只显示真是表的部分列,或计算后的结果从而隐藏真是表的数据。

    不明确情况下不通过视图来调整的,只是用来查询的。(不建议增删改)

    空间换时间的概念。

    11、数据类型

    Mysql中的数据类型

    类型

    含义

    Tinyint

    1字节,带符号的范围是-128到127,无符号的范围是0到255,bool或Boolean,就是tinyint,0表示假,非0表示真。

    Smallint

    2字节,带符号的范围是-32768到32767,无符号的范围是65536

    Int

    整型,同integer,带符号的范围是-21147483648到2147483647,无符号的范围是0到4294967295

    Bigint

    长整型,8字节,带符号的范围是

    Float

    单精度浮点数精确到大约7位小数位

    Double

    双精度浮点数精确到大约15位小数位

    Date

    日期,支持的范围为1000-01-01到9999-12-31

    Datatime

    支持的范围是1000-01-01 00:00:00 到9999-12-31 00:00:00

    Timestamp

    时间戳,范围是1970-01-01 00:00:00到2037年

    Char(M)

    固定长度,右边填充空格达到长度要求,M为长度,范围为0-255,M指的是字符个数。

    Varchar(M)

    变长字符串,M表示最大列长度,M为航都,范围为0-255,M指的是字符个数

    Text

    大文本,最大长度为65535(2^16-1)个字符

    Dlob

    大字节,最大长度为65535(2^16-1)字节的blob列

    Length函数返回字节数,而char和varchar定义的是M是字符数限制。

    12、关系操作

    关系,在关系数据库中,关系就是二维表。

    关系操作就是对表的操作。

    选择(selection):又称为限制,是从关系汇总选择出满足给定条件的元组。

    投影(projection)在关系上投影就是从选择出若干属性列组成新的关系。

    连接(join)将不同的两个关系连接成一个关系。

    13、DML ---CRUD 增删改查

    Insert:主键冲突的问题一定要解决的。可以利用ignore等信息。解决,忽略错误,返货一个警告。Insert into tables_name(col_name,...)values(values,...);

    向表中插入一行数据,自增字段。缺省值字段,可为空字段可不写。

    Insert into tables_name select...;

    将select查询的结果插入到表中。

    Insert into table_name(col_name1,...)values(values1,...) on duplicate key update col_name1=value1,...;

    如果主键冲突、唯一键冲突就执行update后的设置,主键不在新增记录,主键在就更新部分字段。

    Insert ignore into table_name(col_name,...)values(valuse1,...);

    14、Update语句

    Update[ignore]tal_name

    Set col_name1=expr1[,col_name2=expr2..]

    [where where_definition]

    Igonre 意义同insert语句。

    Updata reg set name=‘xxx’where id=5.

    15、delete语句

    Delete【ignore】from tbl_name

    [where where_definition]

    删除符合条件的记录。

    16、Select语句

    查语句。

    SELECT emp_no, CONCAT(first_name,' ',last_name) FROM employees

    字符串拼接等。

    1)BETWEEN  

    15 and 19  是前后都包的

    SELECT

             emp_no

    FROM

             employees

    WHERE

             emp_no BETWEEN 10002 and 10012;

     

    2)字符串拼接

    SELECT emp_no,first_name + last_name FROM employees;     直接成了加法了,显示的是0.

    SELECT emp_no,CONCAT(first_name,'',last_name) FROM employees;  名字拼接

    3)as别名

    SELECT

             emp.emp_no,

             CONCAT(first_name,' ',last_name)

    FROM

             employees as emp

    WHERE

             (emp_no BETWEEN 10005 and 10019) and last_name LIKE 'B%';

    4)limit and offset

    Limit选择显示多少条,offset偏移多少个就是从几开始;做分页用。

    SELECT * FROM employees emp LIMIT 1 OFFSET 8;

    SELECT

             emp.emp_no,

             CONCAT(first_name,' ',last_name)

    FROM

             employees as emp

    LIMIT 5

    OFFSET 18;

     

    5)Where子句

    运算符

    描述

    =

    等于

    <> 

    不等于

    >,<,>=,<=

    大于,小于,大于等于,小于等于

    BETWEEN

    任意区间,在某个范围之间,between a and b等价于[a,b]

    Like(少用)效率低

    字符串模式匹配,%表示任意多个字符,_表示一个字符。

    In

    指定针对某个列的多个可能值。

    Or

    And

    In (主键)

    6)ORDER BY

    排序,对查询结果进行排序,可以升序asc,降序desc。

    SELECT

             emp.emp_no no,

             CONCAT(first_name,' ',last_name)

    FROM

             employees as emp

    ORDER BY no DESC

    7)Distinct

    不返回重复记录。

    去重:两个合起来去重。

    SELECT DISTINCT

             emp_no

    FROM

             salaries

    ORDER BY emp_no desc

    8)聚合函数

    sum min max  count  avg平均值 

    函数

    描述

    Count(expr)

    返回记录中记录的数目,如果指定列,则返回非null值得行数

    Count(distinct)

    返回不重复的非null值得行数

    Avg(distinct)

    返回平均值

    Min(expr)

    最小值

    Sum([distinct]expr)

    求和,distinct返回不同值求和

    Max

    最大值

    ①SELECT

             COUNT(*)

    FROM

             Salaries

    ②SELECT

             COUNT(DISTINCT emp_no)

    FROM

             salaries

    ③SELECT

             COUNT(emp_no)

             #AVG(salary)

             #SUM(salary)

             #MIN(salary)

             #MAX(salary)

    FROM

             Salaries

    9)分组查询

    有条件的话使用having子句过滤分组,聚合过的结果。

    Group by xxx

    分组加条件然后才是投影的。

    聚合运算是和运算是相生相伴的。

    Where的作用更早的。

    SELECT

             emp_no,

             SUM(salary),

             MIN(salary)

    FROM

             salaries

    WHERE

             emp_no < 10013

    GROUP BY

             emp_no

    SELECT

             emp_no,

             SUM(salary) s,

             MIN(salary) m,

             AVG(salary) a

    FROM

             salaries

    #

    GROUP BY

             emp_no

    HAVING

             a > 45000

    ORDER BY

             A

    10)子查询

    查询语句可以嵌套,内部查询就是子查询。

    子查询必须在一组小括号内。

    子查询中不能使用order by

    会带来好多效率问题。

    SELECT

             *

    FROM

             employees

    WHERE

             emp_no in (SELECT emp_no FROM employees WHERE emp_no> 10015)

    ORDER BY

             emp_no DESC  #降序排序

    SELECT

             emp.emp_no,

             emp.first_name,

             gender

    FROM

             (SELECT * from employees WHERE emp_no > 10015)AS emp

    WHERE

             emp.emp_no < 10019

    ORDER BY

             emp_no DESC

    having的时候用到了分组了。尽量使用主键查找

    17、Join连接

    不做什么特殊说明,直接就是行和列相乘的。

    1)Cross join交叉连接

    笛卡尔乘积,全部交叉

    在mysql中,cross join从语法上说与inner join等同。

    SELECT * FROM employees cross JOIN salaries     (出现的是800 行)

    也就是A表多少行直接和B表中多少行直接相乘。

    2)Inner join内连接

    等值连接,只是选择某field相等的元组)行,使用on限定关联的结果。

    Natural join:自然连接,把等值字段的省略一个。特殊的等值连接,去掉重复的列。

    SELECT * FROM employees INNER JOIN salaries;

    SELECT * FROM employees join salaries on employees.emp_no = salaries.emp_no;  等值连接,利用on。

    SELECT * FROM employees NATURAL JOIN salaries ;

    3)Outer join 外连接

    Left join:左表和右表。从左往右看。 左表有多少行,右表就要配对多少行,右表没有的话配置null。

    Right join:右表向左表看。

    SELECT * FROM employees LEFT   JOIN salaries on employees.emp_no = salaries.emp_no;

    SELECT * FROM employees RIGHT JOIN  salaries on employees.emp_no = salaries.emp_no;

    谁是主表,谁的数据全部显示。

    4)自连接

    表自己和自己连接

    父和子的关系,省市县这些等。

    例如员工表:

    Id

    Name

    Leader

    1

    A

    2

    2

    B

    3

    3

    Boss

    Null

    SELECT * from emp emp1 INNER  JOIN emp emp2 on emp1.emp_no=emp2.manager;

    SELECT  * from emp emp1 INNER  JOIN emp emp2 on emp1.emp_no=emp2.manager WHERE emp1.emp_no=2;只是显示对照的。

    18、事务transaction

    InnoDB引擎,支持事务。

    事务由如干条语句组成的,指的是要做的一系列操作。

    关系型数据库中支持事务,必须支持四个属性(acid)

    特性

    描述

    原子性(atomicity)

    一个事务是不可分割的工作单位,事务总包括所有的操作要么全部做完,要么什么都不做。

    一致性(consistency)

    事务必须是使数据库从一个一致性状态编导另一个一致性状态,一致性与原子性是密切相关的。

    隔离性isolation

    一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发 其他事务是隔离的,并发执行的各个事务之间互不干扰

    持久性durability

    也称为永久性,指的是一个事务一旦提交,他对数据库中数据的改变就应该是永久的,接下来的操作或者故障不应该对其有任何影响。

    原子性,要求事务中的所有操作,不可分割,不能做了一部分操作,还剩下一部分操作。

    一致性,多个事务并行执行的结果,应该和事务排队执行的结果一致。如果事务的并行执行和多线程读写共享资源一样不可预期,就不能保证一致性。

    隔离性:多个事务访问共同的数据,应该互不干扰,隔离性,指的是在一个事务处理期间,其他的事务不能访问的问题。

    持久性:事务提交后,数据永久保存,数据不能丢失。

    Mysql隔离级别:隔离性不好,事务的操作就会互相影响,带来不同严重程度的后果。

    1)更新丢失:a和b事务更新同一个数据,a数据提交后,b改变数据,改变后a的数据更新丢失了。

    还没有提交到数据库的数据。脏数据。

    2)脏读,读到了脏数据,读取到了数据的改变,但是还未提交的。

    3)不可以重复读,读到了提交的,不可以利用相同的语句读到了不同数据。

    4)幻读:相同的语句读到了不同的数据,数据的增加或减少。

    隔离级别

    描述

    Read uncommitted

    读取未提交的数据

    Read committed

    读已经提交的数据,Oracle默认隔离级别

    Repeatable read

    可以重复读,mysql默认隔离级别

    Serializable

    可串行化,事物间完全隔离。

    隔离级别越高,串行化越高,数据库执行效率低,隔离级别低,并行度高,性能越高。

    隔离级别越高,当前事务处理的中间结果对其他事务不可见程度越高。

    查询隔离级别:

    select @@tx_isolation; 

    select @@global.tx_isolation;   查询隔离级别。

    设置隔离级别:

     set session transaction isolation level repeatable read;

    set session transaction isolation level read committed;

    SERIALIZABLE, 串行了,解决所有问题

    REPEATABLE READ,事务A中同一条查询语句返回同样的结果,就是可以重复读数据了。例如语句为(select * from user)o解决的办法有

    1、 对se丨ect的数据加锁,不允许其它事务删除、修改的操作

    2、 第一次select的时候,对最后一次确切提交的事务的结果做快照

    解决了不可以重复读,但是有可能出现幻读。因为另一个事务可以增删数据。

    READ CO M M ITTED在事务中,每次se | ect可以读取到别的事务刚提交成功的新的数据。因为读到的是提交后的数据,解决了脏读,但是不能解决不可重复读和幻读的问题。因为其他事务前后修改了数据或增删了数据。

    READ U N CO M M ITTED,能读取到别的事务还没有提交的数据,完全没有隔离性可言,出现了脏读,当前其他问题都可能出现。

    事务语法

    START TRANSACTION或BEGIN开始一个事务,START TRANSACTION是标准SQL的语法。

    使用CO M M丨T提交事务后,变更成为永久变更。

    RO LLBACK可以在提交事务之前,回滚变更,事务中的操作就如同没有发生过一样(原子性)。

    SET AUTOCOMMIT语句可以禁用或启用默认的autocommit模式,用于当前连接。SET AUTOCOMMIT:0禁用自动提交事务。如果开启自动提交,如果有一个修改表的语句执行后,会立即把更新存储到磁盘。

    Select @@tx_isolation;连接数据库就是建立相同的会话。

    读已经提交。Commit提交。

    19、数据仓库和数据库的区别

    本质上没有什么区别,都是存放数据的地方。

    数据库关注数据的持久化、数据的关系,为业务系统提供支持,事务支持。

    数据仓库存储数据是为了分析或者挖掘而设计的表的结构,可以存储海量数据。

    数据库存储在线交易数据OLTP(联机事务处理OLTP)

    数据仓库存储历史数据用于Olap(在线分析处理数据)

    数据库是支持在线业务,支持增删改查。

    数据库仓库是为了做数据分析的。数据是用来查的。

    20、游标:cursor

    操作查询的结果集的一种方法。可以将游标当做一个指针,指向结果集中的某一行。

    21、存储过程、触发器

    存储过程(stored procedure),数据库系统中,一段完成特定功能的SQL语句,编写类似函数的方式,可以传参调用,支持流程控制语句。

    触发器(trigger),由事件触发的特殊的存储过程,例如insert数据式触发。

    这两种技术,虽然是数据库高级内容,但基本很少使用。

    二、数据库开发

    1、驱动

    Mysql基于tcp协议智商开发,网络连接后,传输的数据必须遵守mysql的协议。

    Mysql的驱动:

    Mysqldb:有名的苦,对mysql的c client封装实现,不支持Python3.基于Python2开发的。

    Pymysql:语法兼容mysqldb,支持Python3.

    2、pymysql使用

    1)安装pip install pymysql

    2)创建数据库和表。

    3)connect连接

            建立一个传输数据通道—连接。

             Pymysql.connect()方法返回的是connections模块下的connection类实例,connect方法传参就是connection类的__init__提供参数。

    Connection初始化常用参数

    说明

    Host

    主机

    User

    用户名

    Password

    密码

    Database

    数据库

    Port

    端口

    Connection.ping()方法,测试数据库服务器是否或者,有一个参数reconnect表示断开与服务器连接是否重连。

    import pymysql

    conn =None
    try:
        conn = pymysql.connect('192.168.118.145','wang','wang','school') 创建连接,指定ip地址,用户名密码和数据库。
        print(conn)
        print(conn.ping())
    except Exception as e:
        print(e)

    finally:
        if conn:  最后关闭连接
            conn.close()

    3、游标

     import pymysql


    conn = None
    try:管的是连接的问题
        conn = pymysql.connect('192.168.118.145','wang','wang','school')
        print(conn)
        a = conn.ping(False)
        print(a)
        cursor = conn.cursor()
        try:  管的是事务的问题
            name = 'tom'
            age = 20
            inser_sql = "insert into student(name,age) values('{}',{})".format(name,age)
            row = cursor.execute(inser_sql)
            print(row)
            conn.commit()   写入的数据必须持久化下来

        except Exception as e:
            print(e)
            conn.rollback() 更改的时候出现的任何问题都必须回滚回来

    finally:
        if conn:
            conn.close()

    事务管理:

    Connection类有三个方法:

    Begin开始事务;

    Commit将变更事务

    Rollback回滚事务

    批量添加数据:

    import pymysql


    conn = None
    try:
        conn = pymysql.connect('192.168.118.145','wang','wang','school')
        print(conn)
        a = conn.ping(False)
        print(a)
        cursor = conn.cursor()
        try:
            for i in range(10):
                inser_sql = "insert into student(name,age) values('tom{0}',20+{0})".format(i)
                rows = cursor.execute(inser_sql)
                print(rows)
            conn.commit()

        except Exception as e:
            print(e)
            conn.rollback()

    finally:
        if conn:
            conn.close()
        if cursor:
            cursor.close()

    4、编程流程

    建立连接

    获取游标

    执行sql

    提交事务

    释放资源

    5、查询

    Cursor类的获取查询方法有fetchone()获取集的下一行。

    Cursor.fetchall()拿出游标以后的。

    Cursor.fetchmany(size=None)指定宽度查找几个,返回的记录就是一个元组

    Rowcount获取总的行数

    Rownnumber 返回当前行数

    带列名查询dictcursor:cursor类有一个mixin的子类dictcursor。方式是cursor=conn.cursor(dictcursor)。导入方式

    from pymysql.cursors import DictCursor
    cursor = conn.cursor(cursor=DictCursor)
     
     

    {'name': 'tom0', 'id': 1, 'age': 20}

    {'name': 'tom1', 'id': 2, 'age': 21}

    import pymysql


    conn = None
    try:
        conn = pymysql.connect('192.168.118.145','wang','wang','school')
        cursor = conn.cursor()

        sql = 'select * from student'
        rows = cursor.execute(sql)
        print(cursor.fetchone())
        print(cursor.fetchone())
        print(cursor.fetchmany(2))
        print(cursor.fetchmany(2))
        print(cursor.fetchall())
       print(cursor.rowcount)
    print(cursor.rownumber)


    finally:
        if conn:
            conn.close()
        if cursor:
            cursor.close()

    (1, 'tom0', 20)

    (2, 'tom1', 21)

    ((3, 'tom2', 22), (4, 'tom3', 23))

    ((5, 'tom4', 24), (6, 'tom5', 25))

    ((7, 'tom6', 26), (8, 'tom7', 27), (9, 'tom8', 28), (10, 'tom9', 29), (11, 'tom10', 30), (12, 'tom11', 31), (13, 'tom12', 32), (14, 'tom13', 33), (15, 'tom14', 34), (16, 'tom15', 35), (17, 'tom16', 36), (18, 'tom17', 37), (19, 'tom18', 38), (20, 'tom19', 39))

     20

    20

    6、SQL注入攻击

     SELECT * FROM student WHERE id = 5 OR 1=1;

    可以查找到所有的数据。

    import pymysql
    from pymysql.cursors import DictCursor

    conn = None
    try:
        conn = pymysql.connect('192.168.118.145','wang','wang','school')
        cursor = conn.cursor(DictCursor)
        usid = "tom' or '1'='1"
        sql = "select * from student where name='{}'".format(usid)
        rows = cursor.execute(sql)
        print(cursor.fetchone())
        print(cursor.fetchone())
        # print(cursor.fetchmany(2))
        # print(cursor.fetchmany(2))
        # print(cursor.fetchall())
        # print(cursor.rowcount)
        # print(cursor.rownumber)

    finally:
        if conn:
            conn.close()

    直接拼接到查询字符串中,猜测后台数据库的查询语句使用拼接字符串的方式,从而经过设计为服务端传参,令其拼接处特殊的字符,返回用户想要的结果。

    Sql语句严禁使用字符串拼接,容易造成注入攻击。

    7、解决注入攻击

    参数化查询。有效防止注入攻击,并提高查询效率。

    利用二元组。

    参数化查询的效率会提高的:

    SQL语句的缓存:

    Cursor.execute(sql,(userid,))

    sql = "select * from student where name like %(name)s and age > %(age)s"
    rows = cursor.execute(sql,{'name':'tom%','age':25})

    操作数据库,连接,注入攻击,cursor。

    import pymysql
    from pymysql.cursors import DictCursor

    conn = None
    try:
        conn = pymysql.connect('192.168.118.145','wang','wang','school')
        cursor = conn.cursor(DictCursor)
        usid = "tom' or '1'='1"
        sql = "select * from student where id = %s"
        rows = cursor.execute(sql,(usid,))
        print(cursor.fetchone())
        print(cursor.fetchone())
        print(cursor.fetchmany(2))
        print(cursor.fetchmany(2))
        print(cursor.fetchall())
        print(cursor.rowcount)
        print(cursor.rownumber)

    finally:
        if conn:
            conn.close()
        # if cursor:
        #     cursor.close()

    这种情况下,不会查找到结果的,有效的防止了注入攻击。


    import pymysql
    from pymysql.cursors import DictCursor

    conn = None
    try:
        conn = pymysql.connect('192.168.118.145','wang','wang','school')
        cursor = conn.cursor(DictCursor)
        usid = "tom' or '1'='1"
        sql = "select * from student where name like %(name)s and age > %(age)s"
        rows = cursor.execute(sql,{'name':'tom%','age':25}) 参数化查询
        print(cursor.fetchone())
        print(cursor.fetchone())
        print(cursor.fetchmany(2))
        print(cursor.fetchmany(2))
        print(cursor.fetchall())
        print(cursor.rowcount)
        print(cursor.rownumber)

    finally:
        if conn:
            conn.close()
        # if cursor:
        #     cursor.close()

    按照要求进行了查找。

    8、上下文支持

    #连接类

    class Connection(object):
    def __enter__(self):
        """Context manager that returns a Cursor"""
       
    return self.cursor()

    def __exit__(self, exc, value, traceback):
        """On successful exit, commit. On exception, rollback"""
       
    if exc:
            self.rollback()
        else:
            self.commit()

    #游标列

    class Cursor(object):
    def __enter__(self):
    return self

    def __exit__(self, *exc_info):
    del exc_info
    self.close()

    连接类进入上下文的时候会返回一个游标对象,退出时如果没有异常会提交更新。

    游标也使用上下文,在退出时候关闭游标对象。

    import pymysql


    conn = pymysql.connect('192.168.118.145','wang','wang','school')
    try:
        with conn.cursor() as cursor:
            for i in range(3):
                insert_sql = "insert into student(name,age) values('tom{0}',20+{0})".format(i)
                rows = cursor.execute(insert_sql)
        conn.commit()

    except Exception as e:
        print(e)
        conn.rollback()
    finally:
        conn.close()
    import pymysql

    conn = pymysql.connect('192.168.118.145','wang','wang','school')
    with conn as cursor:
        for i in range(3):
            insert_sql = "insert into student(name,age)values('tom{0}',20+{0})".format(i)
            cursor.execute(insert_sql)

    sql = 'select * from student'
    cursor.execute(sql)
    print(cursor.fetchall())

    cursor.close()
    conn.close()
  • 相关阅读:
    XML的学习
    使用WEB应用时后台发生的事
    企业级应用与互联网应用的区别
    学习JAVA EE的目标
    关于AngularJS的学习报告
    在线进销存软件
    Gridview 实现列表全选、自动选择下级item的功能
    python 计算roc程序报错ValueError: bad input shape (5313, 2)
    pandas保存为hdf格式更高效
    Linux 安装
  • 原文地址:https://www.cnblogs.com/wangchunli-blogs/p/9949917.html
Copyright © 2011-2022 走看看