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)