什么是连接池?
在网上常常给出这样的解释:数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个。
更通俗一点就是,连接池维护着项目于数据库之间的联系,保证项目不会过于频繁的去连接数据库导致数据库压力过大。
为什么要使用连接池?
数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。一个数据库连接对象均对应一个物理数据库连接,每次操作都打开一个物理连接,使用完都关闭连接,这样造成系统的性能低下。如果连接池存在,操作只需要把任务丢给连接池,至于对数据库操作的进程等一系列问题,全权交给连接池来进行操作,由连接池自己控制与数据库的访问与操作。在没有连接池的情况下,连接数据库通常需要以下步骤:  
- TCP建立连接的三次握手  
 
- MySQL认证的三次握手  
 
- 真正的SQL执行  
 
- MySQL的关闭  
 
- TCP的四次握手关闭  
 
这样操作在代码上实现起来是很简单的,但是连接过程太耗时,连接过多容易出现内存泄漏,对于数据库访问大的项目来说这是十分致命的。
连接池的实现
基于别人的工具
实际上连接池的问题由来已久,因此早有人考虑到连接池的问题并为此写好了工具,在python语言中,提供一个库:sqlalchemy ,这个库可以维护一个连接,让操作者不必担心在项目执行过程中断掉与数据库的联系。
使用案例如下:
1 2 3 4 5
   | engine = create_engine("mysql://user:password@hostname/dbname?charset=utf8",                        echo=True,                        pool_size=8,                        pool_recycle=60*30                        )
  | 
 
自己写一个
如果自己写一个也是可以的,自己写连接池需要注意以下几点:
- 最小连接数:是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费.
 
- 最大连接数:是连接池能申请的最大连接数,如果数据库连接请求超过次数,后面的数据库连接请求将被加入到等待队列中,这会影响以后的数据库操作
 
- 最大空闲时间
 
- 获取连接超时时间
 
- 超时重试连接次数
 
在网上也有不少人写出来了一些自己的连接池
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
   | import pymysql from tools.setting import config
  DB_CONFIG = config.mysql_info()
 
  class SQLManager(object):
  	 	def __init__(self): 		self.conn = None 		self.cursor = None 		self.connect()
  	 	def connect(self): 		try:  			self.conn.ping() 		except: 			self.conn = pymysql.connect( 				host=DB_CONFIG["HOST"], 				port=int(DB_CONFIG["PORT"]), 				user=DB_CONFIG["USER"], 				passwd=DB_CONFIG["PASSWORD"], 				db=DB_CONFIG["DBNAME"], 				charset=DB_CONFIG["CHARSET"] 			) 			self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor)
  	 	def get_list(self, sql, args=None): 		self.connect() 		self.cursor.execute(sql.encode('utf8'), args) 		result = self.cursor.fetchall() 		return result
  	 	def get_one(self, sql, args=None): 		self.connect() 		self.cursor.execute(sql.encode('utf8'), args) 		result = self.cursor.fetchone() 		return result
  	 	def moddify(self, sql, args=None): 		self.connect() 		self.cursor.execute(sql, args) 		self.conn.commit()
  	 	 	 	 	 	def multi_modify(self, sql, args=None): 		self.connect() 		self.cursor.executemany(sql.encode('utf8'), args) 		self.conn.commit()
  	 	def create(self, sql, args=None): 		self.connect() 		self.cursor.execute(sql.encode('utf8'), args) 		self.conn.commit() 		last_id = self.cursor.lastrowid 		return last_id
  	 	def close(self): 		self.connect() 		self.cursor.close() 		self.conn.close()
  	 	 	 	 	def __enter__(self): 		return self
  	 	def __exit__(self, exc_type, exc_val, exc_tb): 		self.close()
 
  db = SQLManager()
  if __name__ == "__main__":      	 	 	      	 	sql_str = "SELECT * FROM articles ORDER BY create_time DESC LIMIT {},2;".format(2*2) 	result = db.get_list(sql_str) 	print(result)
   |