事务操作流程(重点)
\1. 创建连接
\2. 获取游标
\3. 执行sql
\1. 查询操作(select)
\2. 非查询操作(insert/update/delete)
\1. 事务提交(连接对象.commit())2. 事务回滚(连接对象.rollback())
\4. 关闭游标
\5. 关闭连接
游标及使用
我们可以将“ 游标 ”简单的看成是结果集的一个指针,可以根据需要在结果集上面来回滚动,
浏览我需要的数据。
``
import pymysql
conn = pymysql.connect(host="localhost",
port=3306,
user="root",
password="123456",
database="books")
cursor = conn.cursor()
sql = "select id, title, `read`, `comment` from t_book"
cursor.execute(sql)
# cursor.rowcount获取查询结果的总记录数
print("获取的查询结果记录行数为:", cursor.rowcount)
# cursor.fetchone()获取查询结果的第一条数据
print("查询结果的第一条数据为:", cursor.fetchone())
# cursor.fetchall()获取全部的查询结果
# 先重置游标位置
cursor.rownumber = 0
print("全部的查询结果为:", cursor.fetchall())
cursor.close()
conn.close()
查询与非查询(插入、更新、删除)操作小结:
相同点(可封装复用去冗余):基本操作流程是一样
创建连接--获取游标--执行sql--关闭游标--关闭连接
不同点
要执行sql语句不一样
非查询操作需要手动开启事务(在创建连接时,指定参数autocommit=True)
数据库事务操作
案例——事务操作的必要性
1).连接到数据库(host:localhost user:root password:root database:books),
并开启自动提交事务
2).新增一条图书数据(id:4 title:西游记 pub_date:1986-01-01 )
3).故意抛出一个异常(模拟代码出现异常)
4).新增一条英雄人物数据(name:孙悟空 gender:1 book_id:4)
解决方法
用函数实现
1.导包
try:
程序前期,需要执行的代码2.创建连接对象
3.获取游标对象
4.执行sql
\+ 在图书表中插入一行数据
\+ 主动抛出异常
\+ 在英雄人物表中插入一行数据
调用提交事务:conn.commit()
except:
程序出现异常后,处理代码
调用事务回滚:conn.rollback()
finally:
程序结束时,需要执行的代码
5.关闭游标
6.关闭连接
数据库工具封装
# 导包
import pymysql
# 创建工具类
class DBUtil():
# 初始化
__conn = None
__cursor = None
# 创建连接
@classmethod
def __get_conn(cls):
if cls.__conn is None:
cls.__conn = pymysql.connect(host="localhost",
port=3306,
user="root",
password="root",
database="books")
return cls.__conn
# 获取游标
@classmethod
def __get_cursor(cls):
if cls.__cursor is None:
cls.__cursor = cls.__get_conn().cursor()
return cls.__cursor
# 执行sql
@classmethod
def exe_sql(cls, sql):
try:
# 获取游标对象
cursor = cls.__get_cursor()
# 调用游标对象的execute方法,执行sql
cursor.execute(sql)
# 如果是查询
if sql.split()[0].lower() == "select":
# 返回所有数据
return cursor.fetchall()
# 否则:
else:
# 提交事务
cls.__conn.commit()
# 返回受影响的行数
return cursor.rowcount
except Exception as e:
# 事务回滚
cls.__conn.rollback()
# 打印异常信息
print(e)
finally:
# 关闭游标
cls.__close_cursor()
# 关闭连接
cls.__close_conn()
# 关闭游标
@classmethod
def __close_cursor(cls):
if cls.__cursor:
cls.__cursor.close()
cls.__cursor = None
# 关闭连接
@classmethod
def __close_conn(cls):
if cls.__conn:
cls.__conn.close()
cls.__conn = None