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()