0X00 为什么要用数据库连接池
一、mysql普通使用
平常可能习惯使用pymysql或者一些数据库连接包去跟数据库交互,代码可能是这样的:
import pymysql config = { ‘host‘: config_template[‘MYSQL‘][‘HOST‘], ‘port‘: config_template[‘MYSQL‘][‘PORT‘], ‘user‘: config_template[‘MYSQL‘][‘USER‘], ‘password‘: config_template[‘MYSQL‘][‘PASSWD‘], ‘db‘: config_template[‘MYSQL‘][‘DB‘], ‘charset‘: config_template[‘MYSQL‘][‘CHARSET‘], ‘cursorclass‘: pymysql.cursors.DictCursor } def db_conn(): conn = pymysql.connect(**config) cursor = conn.cursor() return conn,cursor
大概就是这么个意思,将连接数据库封装为一个方法,每次需要连接的时候调用该方法获取conn和cursor对象,但是这样会有损耗,因为每次都需要 建立连接->执行数据库操作->释放连接。
二、mysql连接池使用
而数据库连接池为维护一个保存有多个数据库连接的池子,每次需要连接数据库时,从连接池中取出一个连接进行使用即可,使用完毕后连接不会释放,而是归还给连接池进行管理,节省了不断建立连接和释放连接的过程。
import pymysql from g_conf.config import config_template from DBUtils.PooledDB import PooledDB class MysqlPool: config = { ‘creator‘: pymysql, ‘host‘: config_template[‘MYSQL‘][‘HOST‘], ‘port‘: config_template[‘MYSQL‘][‘PORT‘], ‘user‘: config_template[‘MYSQL‘][‘USER‘], ‘password‘: config_template[‘MYSQL‘][‘PASSWD‘], ‘db‘: config_template[‘MYSQL‘][‘DB‘], ‘charset‘: config_template[‘MYSQL‘][‘CHARSET‘], ‘maxconnections‘: 70, # 连接池最大连接数量 ‘cursorclass‘: pymysql.cursors.DictCursor } pool = PooledDB(**config) def __enter__(self): self.conn = MysqlPool.pool.connection() self.cursor = self.conn.cursor() return self def __exit__(self, type, value, trace): self.cursor.close() self.conn.close()
可以看到,通过DBUtils,实例化一个PooledDB对象作为MysqlPool类的类属性,通过重写__enter__和__exit__方法让我们在进入with语句时从连接池中获取到数据库连接,在with语句结束后,自动释放连接池,归还给连接池。
with语句用法:
def func(tar_id): with MysqlPool() as db: db.cursor.execute(‘YOUR_SQL‘) db.conn.commit()
装饰器用法:
def db_conn(func): def wrapper(*args, **kw): with MysqlPool() as db: result = func(db, *args, **kw) return result return wrapper @db_conn def update_info(db, *args, **kw): try: db.cursor.execute("YOUR_SQL") db.conn.commit() return 0 except Exception as e: db.conn.rollback() return 1
示例说明:
import pymysql from dbutils.pooled_db import PooledDB class MysqlPool: config = { ‘creator‘: pymysql, ‘host‘: "数据库地址", ‘port‘: 3306, ‘user‘: "testuser", ‘password‘: "test123", ‘db‘: "TESTDB", ‘charset‘: ‘utf8‘, ‘maxconnections‘: 70, # 连接池最大连接数量 ‘cursorclass‘: pymysql.cursors.DictCursor } pool = PooledDB(**config) def __enter__(self): self.conn = MysqlPool.pool.connection() self.cursor = self.conn.cursor() return self def __exit__(self, type, value, trace): self.cursor.close() self.conn.close() def db_conn(func): def wrapper(*args, **kw): with MysqlPool() as db: result = func(db, *args, **kw) return result return wrapper # 实际应用的地方 class Mysql_Db_Manage: """table: register_phone""" @staticmethod @db_conn def select_All_Register_Phone(db): q = "SELECT xxx FROM xxx" db.cursor.execute(q) result = db.cursor.fetchall() return result