Python封裝數(shù)據(jù)庫連接池詳解_第1頁
Python封裝數(shù)據(jù)庫連接池詳解_第2頁
Python封裝數(shù)據(jù)庫連接池詳解_第3頁
Python封裝數(shù)據(jù)庫連接池詳解_第4頁
Python封裝數(shù)據(jù)庫連接池詳解_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第Python封裝數(shù)據(jù)庫連接池詳解#ret=db.selectone(sql=sql1,param=args)

#print(ret)#(None,b'python',b'123456',b'0')

#TODO增加單條

#sql2='insertintohotel_urls(cname,hname,cid,hid,url)values(%s,%s,%s,%s,%s)'

#ret=db.insertone(sql2,('1','2','1','2','2'))

#print(ret)

#TODO增加多條

#sql3='insertintouserinfo(name,password)VALUES(%s,%s)'

#li=li=[

#('分省','123'),

#('到達(dá)','456')

#ret=db.insertmany(sql3,li)

#print(ret)

#TODO刪除

#sql4='deletefromuserinfoWHEREname=%s'

#args='xxxx'

#ret=db.delete(sql4,args)

#print(ret)

#TODO更新

#sql5=r'updateuserinfosetpassword=%sWHEREnameLIKE%s'

#args=('993333993','%old%')

#ret=db.update(sql5,args)

#print(ret)

二、連接池測試

修改db_dbutils_init.py文件,在創(chuàng)建連接池def__getconn(self):方法下,加一個打印隨機(jī)數(shù),方便將來我們定位是否時單例的線程池。

修改后的db_dbutils_init.py文件:

fromdbutils.pooled_dbimportPooledDB

importdb_configasconfig

importrandom

fromsingletonimportsingleton

@功能:創(chuàng)建數(shù)據(jù)庫連接池

classMyConnectionPool(object):

#私有屬性

#能通過對象直接訪問,但是可以在本類內(nèi)部訪問;

__pool=None

#def__init__(self):

#self.conn=self.__getConn()

#self.cursor=self.conn.cursor()

#創(chuàng)建數(shù)據(jù)庫連接conn和游標(biāo)cursor

def__enter__(self):

self.conn=self.__getconn()

self.cursor=self.conn.cursor()

#創(chuàng)建數(shù)據(jù)庫連接池

def__getconn(self):

ifself.__poolisNone:

i=random.randint(1,100)

print("線程池的隨機(jī)數(shù)"+str(i))

self.__pool=PooledDB(

creator=config.DB_CREATOR,

mincached=config.DB_MIN_CACHED,

maxcached=config.DB_MAX_CACHED,

maxshared=config.DB_MAX_SHARED,

maxconnections=config.DB_MAX_CONNECYIONS,

blocking=config.DB_BLOCKING,

maxusage=config.DB_MAX_USAGE,

setsession=config.DB_SET_SESSION,

host=config.DB_TEST_HOST,

port=config.DB_TEST_PORT,

user=config.DB_TEST_USER,

passwd=config.DB_TEST_PASSWORD,

db=config.DB_TEST_DBNAME,

use_unicode=False,

charset=config.DB_CHARSET

returnself.__pool.connection()

#釋放連接池資源

def__exit__(self,exc_type,exc_val,exc_tb):

self.cursor.close()

self.conn.close()

#關(guān)閉連接歸還給鏈接池

#defclose(self):

#self.cursor.close()

#self.conn.close()

#從連接池中取出一個連接

defgetconn(self):

conn=self.__getconn()

cursor=conn.cursor()

returncursor,conn

#獲取連接池,實例化

@singleton

defget_my_connection():

returnMyConnectionPool()

開始測試:

場景一:同一個實例,執(zhí)行2次sql

frommysqlhelperimportMySqLHelper

importtime

if__name__=='__main__':

sql="SELECTSLEEP(10)"

sql1="SELECTSLEEP(15)"

db=MySqLHelper()

db.execute(sql)

db.execute(sql1)

time.sleep(20)

在數(shù)據(jù)庫中,使用showprocesslist;

showprocesslist;

當(dāng)執(zhí)行第一個sql時。數(shù)據(jù)庫連接顯示。

當(dāng)執(zhí)行第二個sql時。數(shù)據(jù)庫連接顯示:

當(dāng)執(zhí)行完sql,程序sleep時。數(shù)據(jù)庫連接顯示:

程序打印結(jié)果:

線程池的隨機(jī)數(shù)43

由以上可以得出結(jié)論:

線程池啟動后,生成了5個連接。執(zhí)行第一個sql時,使用了1個連接。執(zhí)行完第一個sql后,使用了另外1個連接。這是一個線性的,線程池中一共5個連接,但是每次執(zhí)行,只使用了其中一個。

有個疑問,連接池如果不支持并發(fā)是不是就毫無意義?

如上,雖然開了線程池5個連接,但是每次執(zhí)行sql,只用到了一個連接。那為何不設(shè)置線程池大小為1呢?設(shè)置線程池大小的意義何在呢?(如果在非并發(fā)的場景下,是不是設(shè)置大小無意義?)

相比于不用線程池的優(yōu)點:

如果不用線程池,則每次執(zhí)行一個sql都要創(chuàng)建、斷開連接。像我們這樣使用連接池,不用反復(fù)創(chuàng)建、斷開連接,拿現(xiàn)成的連接直接用就好了。

場景二:依次創(chuàng)建2個實例,各自執(zhí)行sql

frommysqlhelperimportMySqLHelper

importtime

if__name__=='__main__':

db=MySqLHelper()

db1=MySqLHelper()

sql="SELECTSLEEP(10)"

sql1="SELECTSLEEP(15)"

db.execute(sql)

db1.execute(sql1)

time.sleep(20)

第一個實例db,執(zhí)行sql。線程池啟動了5個連接

第二個實例db1,執(zhí)行sql:

程序睡眠時,一共5個線程池:

打印結(jié)果:

結(jié)果證明:

雖然我們依次創(chuàng)建了2個實例,但是(1)創(chuàng)建線程池的打印結(jié)果,只打印1次,且從始至終,線程池一共只啟動了5個連接,且連接的id沒有發(fā)生改變,說明一直是這5個連接。

證明,我們雖然創(chuàng)建了2個實例,但是這2個實例其實是一個實例。(單例模式是生效的)

場景三:啟動2個線程,但是線程在創(chuàng)建連接池實例時,有時間間隔

importthreading

frommysqlhelperimportMySqLHelper

importtime

defsl1():

time.sleep(2)

db=MySqLHelper()

sql="SELECTSLEEP(6)"

db.execute(sql)

defsl2():

time.sleep(4)

db=MySqLHelper()

sql="SELECTSLEEP(15)"

db.execute(sql)

if__name__=='__main__':

threads=[]

t1=threading.Thread(target=sl1)

threads.append(t1)

t2=threading.Thread(target=sl2)

threads.append(t2)

fortinthreads:

t.setDaemon(True)

t.start()

time.sleep(20)

2個線程間隔了2秒。

觀察數(shù)據(jù)庫的連接數(shù)量:

打印結(jié)果:

在并發(fā)執(zhí)行2個sql時,共用了這5個連接,且打印結(jié)果只打印了一次,說明雖然并發(fā)創(chuàng)建了2次實例,但真正只創(chuàng)建了一個連接池。

場景四:啟動2個線程,線程在創(chuàng)建連接池實例時,沒有時間間隔

importthreading

frommysqlhelperimportMySqLHelper

importtime

if__name__=='__main__':

db=MySqLHelper()

sql="SELECTSLEEP(6)"

sql1="SELECTSLEEP(15)"

threads=[]

t1=threading.Thread(target=db.execute,args=(sql,))

threads.append(t1)

t2=t

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論