zoukankan      html  css  js  c++  java
  • 数据库的优化

    之前在使用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

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

    但是这样还是有问题,当我要大批量创建数据的时候,就需要多次调用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()

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

    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的executermany()方法就可以了。

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

    现在我们如果一次执行多个创建操作的话就可以使用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()
  • 相关阅读:
    mode
    Jmeter获取不到cookie(备注:前面和后面的几个步骤都可以获取到cookie)
    [BAT]批处理脚本双击可运行,但在定时计划任务中无法执行(当前工作路径不对导致的)
    匹配数字、字母和?%&=-_这几个符号的正则表达式
    在jmeter的beanshell中用java获取系统当前时间
    Jmeter中正则表达式不区分大小写进行匹配
    通过BeanShell获取UUID并将参数传递给Jmeter
    JAVA Get UUID
    Jmeter报文体包含过大附件导致请求报文发送失败的解决办法
    [BAT]操作系统定时任务调用批处理忽略error继续运行的方法
  • 原文地址:https://www.cnblogs.com/yangmingxianshen/p/8297710.html
Copyright © 2011-2022 走看看