python仿java DBUtils工具类

python的orm太难用, 然后就想找一下有没有类似java的DBUtils工具类, 没找到, 自己手写一个仿制一个, 基于pymysql驱动

  1 # coding:UTF-8
  2 
  3 import threading
  4 import types
  5 
  6 from pymysql import Connection
  7 from pymysql.cursors import Cursor, DictCursor
  8 
  9 
 10 class ConnectionException(Exception):
 11     pass
 12 
 13 
 14 # 连接池
 15 class DataSource(object):
 16     def __init__(self, host, port, user, password, database, maxPoolSize=10, minPoolSize=2):
 17         # 数据库信息
 18         self.host = host
 19         self.port = port
 20         self.user = user
 21         self.password = password
 22         self.database = database
 23         # 连接池信息
 24         self.__pool = []
 25         self.maxPoolSize = maxPoolSize
 26         self.minPoolSize = minPoolSize
 27         self.__existSize = 0
 28         # 初始化连接池
 29         self.__initPool()
 30         # 互斥锁,获取连接时保证线程安全
 31         self.__lock1 = threading.RLock()
 32         self.__lock2 = threading.RLock()
 33 
 34     # 初始化连接池
 35     def __initPool(self):
 36         for i in range(self.minPoolSize):
 37             self.__pool.append(self.__createConnection())
 38 
 39     # 创建连接
 40     def __createConnection(self):
 41         self.__existSize += 1
 42         conn = Connection(host=self.host, port=self.port, user=self.user, password=self.password,
 43                           database=self.database)
 44 
 45         # 重写close方法,关闭连接时加入连接池
 46         def close(connection):
 47             self.__pool.append(connection)
 48 
 49         conn.close = types.MethodType(close, conn)
 50         return conn
 51 
 52     # 获取连接,保证线程安全
 53     def getConnection(self):
 54         if len(self.__pool) > 0:
 55             # 如果池中还有连接则直接返回池中的连接
 56             self.__lock1.acquire()
 57             if len(self.__pool) > 0:
 58                 return self.__pool.pop()
 59             self.__lock1.release()
 60         if self.__existSize < self.maxPoolSize:
 61             # 如果池中没有连接了,但是创建的连接数还没有达到最大,则创建新的连接并返回
 62             self.__lock2.acquire()
 63             if self.__existSize < self.maxPoolSize:
 64                 return self.__createConnection()
 65             self.__lock2.release()
 66         # 已经达到最大连接数了,抛出异常
 67         raise ConnectionException("没有空闲连接了")
 68 
 69 
 70 # QueryRunner工具类
 71 class QueryRunner(object):
 72     def __init__(self, dataSource):
 73         self.dataSource = dataSource
 74 
 75     # 通用方法
 76     def common(self, handler, sql, *args, **kwargs):
 77         conn = None
 78         cursor = None
 79         try:
 80             conn = self.dataSource.getConnection()
 81             if handler.cursorType:
 82                 cursor = conn.cursor(cursor=handler.cursorType)
 83             else:
 84                 cursor = conn.cursor(cursor=Cursor)
 85             rows = cursor.execute(sql, *args, **kwargs)
 86             if handler:
 87                 return handler.handle(cursor)
 88             cursor.commit()
 89             return rows
 90         finally:
 91             close(cursor, conn)
 92 
 93     # 查询方法
 94     def query(self, handler, sql, *args, **kwargs):
 95         return self.common(handler, sql, *args, **kwargs)
 96 
 97     # 更新方法
 98     def update(self, sql, *args, **kwargs):
 99         return self.common(None, sql, *args, **kwargs)
100 
101 
102 # 释放资源
103 def close(*args):
104     try:
105         for obj in args:
106             if obj:
107                 obj.close()
108     except Exception as e:
109         pass
110 
111 
112 # 异常处理装饰器,用于装饰handle方法
113 def noException(handler):
114     def wrap(*args, **kwargs):
115         try:
116             return handler(*args, **kwargs)
117         except Exception as e:
118             pass
119 
120     return wrap
121 
122 
123 # 从字典中给对象设置属性
124 def populate(obj, d):
125     for key, value in d.items():
126         setattr(obj, key, value)
127 
128 
129 # ResultSetHandler根接口
130 class Handler(object):
131     cursorType = Cursor
132 
133 
134 # 将结果集第一行封装成一个tuple并返回
135 class ArrayHandler(Handler):
136     def handle(self, cursor):
137         return cursor.fetchone()
138 
139 
140 # 将结果集每一行封装成一个tuple,返回一个大tuple
141 class ArrayListHandler(Handler):
142     def handle(self, cursor):
143         return cursor.fetchall()
144 
145 
146 # 将结果集第1行,封装成一个bean对象
147 class BeanHandler(Handler):
148     cursorType = DictCursor
149 
150     def __init__(self, clazz):
151         self.clazz = clazz
152 
153     def handle(self, cursor):
154         obj = self.clazz()
155         populate(object, cursor.fetchone)
156         return obj
157 
158 
159 # 将结果集每一行封装成一个bean对象,返回一个list包含所有bean对象
160 class BeanListHandler(Handler):
161     cursorType = DictCursor
162 
163     def __init__(self, clazz):
164         self.clazz = clazz
165 
166     def handle(self, cursor):
167         list = []
168         for d in cursor.fetchall():
169             obj = self.clazz()
170             populate(obj, d)
171             list.append(obj)
172         return list
173 
174 
175 # 将结果集每一行封装成一个bean对象作为value,再指定某一列作为key,返回一个大dict
176 class BeanMapHandler(Handler):
177     cursorType = DictCursor
178 
179     def __init__(self, clazz, key):
180         self.clazz = clazz
181         self.key = key
182 
183     def handle(self, cursor):
184         m = {}
185         for d in cursor.fetchall():
186             obj = self.clazz()
187             populate(obj, d)
188             m[d[self.key]] = obj
189         return m
190 
191 
192 # 将结果集每一行封装成一个dict作为value,再指定某一列作为key,返回一个双层dict
193 class KeyedHandler(Handler):
194     cursorType = DictCursor
195 
196     def __init__(self, clazz, key):
197         self.clazz = clazz
198         self.key = key
199 
200     def handle(self, cursor):
201         m = {}
202         for d in cursor.fetchall():
203             m[d[self.key]] = d
204         return m
205 
206 
207 # 将结果集第1行,封装成一个dict,其中key为查询出来的字段名,value为查询出来的值
208 class MapHandler(Handler):
209     cursorType = DictCursor
210 
211     def handle(self, cursor):
212         return cursor.fetchone()
213 
214 
215 # 将结果集每一行封装成一个map,返回一个list包含所有map
216 class MapListHandler(Handler):
217     cursorType = DictCursor
218 
219     def handle(self, cursor):
220         return cursor.fetchall()
221 
222 
223 # 返回结果集中第1行,某一列的值
224 class ScalarHandler(Handler):
225     def __init__(self, index):
226         self.index = index
227 
228     def handle(self, cursor):
229         return cursor.fetchone()[self.index - 1]
230 
231 
232 # 将结果集每一行的某一列封装成一个list,ScalarHandler加强版
233 class ColumnListHandler(Handler):
234     def __init__(self, index):
235         self.index = index
236 
237     def handle(self, cursor):
238         list = []
239         for row in cursor:
240             list.append(row[self.index - 1])
241         return list
242 
243 
244 # 测试
245 if __name__ == '__main__':
246     dataSource = DataSource(host="192.168.137.101", port=3306, user="root", password="12345678", database="test")
247     queryRunner = QueryRunner(dataSource)
248     sql = "select id, name from user"
249 
250 
251     class User(object):
252         def __str__(self):
253             return "id: %s name: %s" % (self.id, self.name)
254 
255 
256     userList = queryRunner.query(BeanListHandler(User), sql)
257     for user in userList:
258         print(user)

猜你喜欢

转载自www.cnblogs.com/alonly/p/12938215.html