学员管理系统0x04 数据库连接优化

Posted TreeSir

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学员管理系统0x04 数据库连接优化相关的知识,希望对你有一定的参考价值。

【学员管理系统】0x04  pymysql数据库连接优化

写在前面

项目详细需求参见Django项目之【学员管理系统】

优化实现

把操作封装成函数

我们之前使用pymysql操作数据库的操作都是写死在视图函数中的,并且很多都是重复的代码。

我们可以优化一下,把重复的代码提取出来,写成函数:

import pymysql

# 定义一个数据库相关的配置项
DB_CONFIG = {
    "host": "127.0.0.1",
    "port": 3306,
    "user": "root",
    "passwd": "root1234",
    "db": "mysite",
    "charset": "utf8"
}


# 查询多条数据函数
def get_list(sql, args=None):
    conn = pymysql.connect(
        host=DB_CONFIG["host"],
        port=DB_CONFIG["port"],
        user=DB_CONFIG["user"],
        passwd=DB_CONFIG["passwd"],
        db=DB_CONFIG["db"],
        charset=DB_CONFIG["charset"]
    )
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    cursor.execute(sql, args)
    result = cursor.fetchall()
    cursor.close()
    conn.close()
    return result


# 查询单挑数据函数
def get_one(sql, args=None):
    conn = pymysql.connect(
        host=DB_CONFIG["host"],
        port=DB_CONFIG["port"],
        user=DB_CONFIG["user"],
        passwd=DB_CONFIG["passwd"],
        db=DB_CONFIG["db"],
        charset=DB_CONFIG["charset"]
    )
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    cursor.execute(sql, args)
    result = cursor.fetchone()
    cursor.close()
    conn.close()
    return result


# 修改记录
def modify(sql, args=None):
    conn = pymysql.connect(
        host=DB_CONFIG["host"],
        port=DB_CONFIG["port"],
        user=DB_CONFIG["user"],
        passwd=DB_CONFIG["passwd"],
        db=DB_CONFIG["db"],
        charset=DB_CONFIG["charset"]
    )
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    cursor.execute(sql, args)
    conn.commit()
    cursor.close()
    conn.close()


# 创建记录
def create(sql, args=None):
    conn = pymysql.connect(
        host=DB_CONFIG["host"],
        port=DB_CONFIG["port"],
        user=DB_CONFIG["user"],
        passwd=DB_CONFIG["passwd"],
        db=DB_CONFIG["db"],
        charset=DB_CONFIG["charset"]
    )
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    cursor.execute(sql, args)
    conn.commit()
    # 返回刚才创建的那条数据的ID
    last_id = cursor.lastrowid
    cursor.close()
    conn.close()
    return last_id
code:优化 

这样只要在需要连接数据库做操作的时候,只需要调用我们上面定义好的函数就可以了。

重用数据库连接

但是这样还是有问题,当我要大批量创建数据的时候,就需要多次调用create方法了,相当于多次连接多次提交。

可以继续优化下,把数据库的连接重用,做到只需一次连接就可执行多次操作。

class SQLManager(object):

    # 初始化实例方法
    def __init__(self):
        self.conn = None
        self.cursor = None
        self.connect()

    # 连接数据库
    def connect(self):
        self.conn = pymysql.connect(
            host=DB_CONFIG["host"],
            port=DB_CONFIG["port"],
            user=DB_CONFIG["user"],
            passwd=DB_CONFIG["passwd"],
            db=DB_CONFIG["db"],
            charset=DB_CONFIG["charset"]
        )
        self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor)

    # 查询多条数据
    def get_list(self, sql, args=None):
        self.cursor.execute(sql, args)
        result = self.cursor.fetchall()
        return result

    # 查询单条数据
    def get_one(self, sql, args=None):
        self.cursor.execute(sql, args)
        result = self.cursor.fetchone()
        return result

    # 执行单条SQL语句
    def moddify(self, sql, args=None):
        self.cursor.execute(sql, args)
        self.conn.commit()

    # 创建单条记录的语句
    def create(self, sql, args=None):
        self.cursor.execute(sql, args)
        self.conn.commit()
        last_id = self.cursor.lastrowid
        return last_id

    # 关闭数据库cursor和连接
    def close(self):
        self.cursor.close()
        self.conn.close()
code:优化

把操作封装成类

我们把我们数据库的相关操作都封装成一个类,在用到的时候,只需要生成一个实例,并对实例调用相应的操作方法就可以了。

db = SQLManager()
class_list = db.get_list("select id, name from class")
teacher_info = db.get_list("SELECT teacher.id, teacher.name, teacher2class.class_id FROM teacher  LEFT JOIN teacher2class ON teacher.id = teacher2class.teacher_id WHERE teacher.id=%s;", [teacher_id])
db.close()

批量操作

但是,我如果要批量执行多个创建操作,虽然只建立了一次数据库连接但是还是会多次提交,可不可以改成一次连接,一次提交呢?

可以,只需要用上pymysql的executemany()方法就可以了。

给我们的 SQLManager类添加一个批量执行的 multi_modify()方法就可以了。

# 执行多条SQL语句
def multi_modify(self, sql, args=None):
    self.cursor.executemany(sql, args)
    self.conn.commit()

使用with语句操作

现在我们如果一次执行多个创建操作的话就可以使用multi_modify()方法,实现一次连接一次提交了。

最后,我们每次操作完数据库之后都要手动关闭,可不可以写成自动关闭的呢?

联想到我们之前学过的文件操作,使用with语句可以实现缩进结束自动关闭文件句柄的例子。

我们来把我们的数据库连接类SQLManager类再优化下,使其支持with语句操作。

class SQLManager(object):

    # 初始化实例方法
    def __init__(self):
        self.conn = None
        self.cursor = None
        self.connect()

    # 连接数据库
    def connect(self):
        self.conn = pymysql.connect(
            host=DB_CONFIG["host"],
            port=DB_CONFIG["port"],
            user=DB_CONFIG["user"],
            passwd=DB_CONFIG["passwd"],
            db=DB_CONFIG["db"],
            charset=DB_CONFIG["charset"]
        )
        self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor)

    # 查询多条数据
    def get_list(self, sql, args=None):
        self.cursor.execute(sql, args)
        result = self.cursor.fetchall()
        return result

    # 查询单条数据
    def get_one(self, sql, args=None):
        self.cursor.execute(sql, args)
        result = self.cursor.fetchone()
        return result

    # 执行单条SQL语句
    def moddify(self, sql, args=None):
        self.cursor.execute(sql, args)
        self.conn.commit()

    # 执行多条SQL语句
    def multi_modify(self, sql, args=None):
        self.cursor.executemany(sql, args)
        self.conn.commit()

    # 创建单条记录的语句
    def create(self, sql, args=None):
        self.cursor.execute(sql, args)
        self.conn.commit()
        last_id = self.cursor.lastrowid
        return last_id

    # 关闭数据库cursor和连接
    def close(self):
        self.cursor.close()
        self.conn.close()

    # 进入with语句自动执行
    def __enter__(self):
        return self
    
    # 退出with语句块自动执行
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()
Code:优化

 

以上是关于学员管理系统0x04 数据库连接优化的主要内容,如果未能解决你的问题,请参考以下文章

数据库连接池

数据库连接池

学员管理系统0x03 老师信息管理功能

JDBC数据库连接池

JDBC数据库连接池

优化 C# 代码片段、ObservableCollection 和 AddRange