数据库连接池与SQL工具类

1.数据库连接池

  • 依赖包

    • pymysql
    • dbutils
    1. # -*- coding: utf-8 -*-
    2. '''
    3. @Time : 2021/11/19 16:45
    4. @Author : ziqingbaojian
    5. @File : MySql.py
    6. '''
    7. # 依赖第三发包:pymysql,dbutils
    8. import pymysql
    9. from dbutils.pooled_db import PooledDB
    10. MYSQL_DB_POOL=PooledDB(
    11. creator=pymysql,
    12. maxconnections=50,
    13. mincached=2,
    14. maxcached=3,
    15. blocking=True,
    16. setsession=[],
    17. ping=0,
    18. host='127.0.0.1',
    19. port=3306,
    20. user='root',
    21. password='1234567',
    22. database='testlearn',
    23. charset='utf8'
    24. )
  • 源码解释
  • 使用连接池

  • 使用多线程进行测试
    1. # 使用连接池
    2. def task():
    3. # 连接池获取连接
    4. conn=MYSQL_DB_POOL.connection()
    5. cursor=conn.cursor()
    6. cursor.execute("select * from student where sname='逻辑'")
    7. result=cursor.fetchall()
    8. print(result)
    9. conn.close()#将连接还给连接池
    10. # task()
    11. '''使用多线程进行测试'''
    12. def run():
    13. for i in range(10):
    14. t=threading.Thread(target=task)
    15. t.start()
    16. if __name__ == '__main__':
    17. # 开启10个线程进行测试
    18. run()

2.SQL工具类

2.1 单利模式的方式实现

  • 注意:本单利模式并未封装异常处理的功能,各位可以根据情况在封装中添加,也可以在使用时直接将对象进行异常的检测处理;

    1. # -*- coding: utf-8 -*-
    2. '''
    3. @Time : 2021/11/19 17:11
    4. @Author : ziqingbaojian
    5. @File : db.py
    6. '''
    7. import pymysql
    8. from dbutils.pooled_db import PooledDB
    9. class DBHelper(object):
    10. def __init__(self):
    11. self.pool=PooledDB(
    12. creator=pymysql,
    13. maxconnections=50,
    14. mincached=2,
    15. maxcached=3,
    16. blocking=True,
    17. setsession=[],
    18. ping=0,
    19. host='127.0.0.1',
    20. port=3306,
    21. user='root',
    22. password='1234567',
    23. database='testlearn',
    24. charset='utf8'
    25. )
    26. def get_conn_cursor(self):
    27. conn=self.pool.connection()
    28. cursor=conn.cursor(pymysql.cursors.DictCursor)
    29. return conn,cursor
    30. def get_conn_cursor_nodict(self):
    31. conn=self.pool.connection()#向连接池中请求连接
    32. cursor=conn.cursor()#不写入字典的 参数
    33. return conn,cursor
    34. def close_conn_cursor(self,*args):
    35. for item in args:
    36. item.close()
    37. # 由于插入,删除,修改的语句一样因此,不在分开编写,增加简洁程度;
    38. def exec(self,sql,**kwargs):
    39. # 获取连接与游标
    40. conn,cursor=self.get_conn_cursor()
    41. cursor.execute(sql,kwargs)
    42. conn.commit()# 提交事务,只有增删改才需要提交事务,可能与对应的排它锁有关系
    43. self.close_conn_cursor(conn,cursor)
    44. def fetch_one(self,sql,**kwargs):
    45. conn,cursor=self.get_conn_cursor()
    46. cursor.execute(sql,kwargs)
    47. result =cursor.fetchone()
    48. self.close_conn_cursor()
    49. return result
    50. def fetch_all(self,sql,**kwargs):
    51. conn,cursor=self.get_conn_cursor()
    52. cursor.execute(sql,kwargs)
    53. reusult=cursor.fetchall()
    54. return reusult
    55. def fetch_one_nodict(self,sql,**kwargs):
    56. conn,cursor=self.get_conn_cursor_nodict()
    57. cursor.execute(sql, kwargs)
    58. result = cursor.fetchone()
    59. self.close_conn_cursor()
    60. return result
    61. def fetch_all_nodict(self,sql,**kwargs):
    62. conn,cursor=self.get_conn_cursor()
    63. cursor.execute(sql, kwargs)
    64. reusult = cursor.fetchall()
    65. return reusult
    66. db=DBHelper()
  • 补充:什么是单利模式
    • 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。
  • 实现单利模式的方式
    • Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。如果我们真的想要一个单例类,可以像上述类一样,使用时直接导入文件中的对象,这个对象就是单利模式的对象
  • 使用
    1. # -*- coding: utf-8 -*-
    2. '''
    3. @Time : 2021/11/20 8:24
    4. @Author : ziqingbaojian
    5. @File : testpy.py
    6. '''
    7. from db import db
    8. '''使用单利模式进行操作'''
    9. res=db.fetch_one("select * from student where sname='%s'"%("逻辑"))
    10. print(res)
    11. ''''''
  • 单利模式使用效果

  • 补充:Python其他实现单利模式的方法
    • 参考文献:https://blog.csdn.net/weixin_44239343/article/details/89376796

    • 1.使用装饰器
      1. def Singleton(cls):
      2. _instance = {}
      3. def _singleton(*args, **kargs):
      4. if cls not in _instance:
      5. _instance[cls] = cls(*args, **kargs)
      6. return _instance[cls]
      7. return _singleton
      8. @Singleton
      9. class A(object):
      10. a = 1
      11. def __init__(self, x=0):
      12. self.x = x
      13. a1 = A(2)
      14. a2 = A(3)
    • 基于__new__方法实现(推荐使用,方便)

      当我们实例化一个对象时,是先执行了类的__new__方法(我们没写时,默认调用object.new),实例化对象;然后再执行类的__init__方法,对这个对象进行初始化,所有我们可以基于这个,实现单例模式

      1. import threading
      2. class Singleton(object):
      3. _instance_lock = threading.Lock()
      4. def __init__(self):
      5. pass
      6. def __new__(cls, *args, **kwargs):
      7. if not hasattr(Singleton, "_instance"):
      8. with Singleton._instance_lock:
      9. if not hasattr(Singleton, "_instance"):
      10. Singleton._instance = object.__new__(cls)
      11. return Singleton._instance
    • 还可以基于或者metaclass方式实现,此处不在逐个详细解释,请参考参考文献深度学习;

2.2上下文管理

  • 让类支持with 语句的格式,进行使用

    1. with 获取连接() as obj:
    2. # 执行语句
  • 代码
    1. # -*- coding: utf-8 -*-
    2. '''
    3. @Time : 2021/11/20 8:07
    4. @Author : ziqingbaojian
    5. @File : db_context.py
    6. '''
    7. import pymysql
    8. from dbutils.pooled_db import PooledDB
    9. POOL=PooledDB(
    10. creator=pymysql,
    11. maxconnections=50,
    12. mincached=2,
    13. maxcached=3,
    14. blocking=True,
    15. setsession=[],
    16. ping=0,
    17. host='127.0.0.1',
    18. port=3306,
    19. user='XXXXX',
    20. password='XXXXXX',
    21. database='testlearn',
    22. charset='utf8'
    23. )
    24. class Connect(object):
    25. def __init__(self):
    26. self.conn=conn=POOL.connection()#获取连接
    27. self.cursor=conn.cursor(pymysql.cursors.DictCursor)#字典游标,此处不在创键非字典游标,本人使用非字典游标较少,如有需要时可以将字典单参数删除即可
    28. def __enter__(self):
    29. return self
    30. def __exit__(self, exc_type, exc_val, exc_tb):
    31. self.cursor.close()
    32. self.conn.close()#通常都是先关游标再关闭连接,此处是将连接归还连接池
    33. def exec(self,sql,**kwargs):
    34. self.cursor.execute(sql,kwargs)
    35. self.conn.commit()
    36. def fetch_one(self,sql,**kwargs):
    37. self.cursor.execute(sql,kwargs)
    38. result=self.cursor.fetchone()
    39. return result
    40. def fetch_all(self,sql,**kwargs):
    41. self.cursor.execute(sql,kwargs)
    42. result=self.cursor.fetchall()
    43. return result
  • 使用效果
  • 补充上下文管理器
    • 参考文献:https://www.cnblogs.com/wongbingming/p/10519553.html

    • 基本语法

      1. with EXPR as VAR:
      2. BLOCK
      1. 上下文表达式:with open('test.txt') as f:
      2. 上下文管理器:open('test.txt')
      3. f 不是上下文管理器,应该是资源对象。
    • 编写上下文管理器

      要自己实现这样一个上下文管理,要先知道上下文管理协议。

      简单点说,就是在一个类里,实现了__enter____exit__的方法,这个类的实例就是一个上下文管理器。

      例如上述的类就采取了这种方式;

      在编写代码时,可以将资源的连接或者获取放在__enter__中,而将资源的关闭写在__exit__ 中。

      在 写__exit__ 函数时,需要注意的事,它必须要有这三个参数:

      • exc_type:异常类型
      • exc_val:异常值
      • exc_tb:异常的错误栈信息

      当主逻辑代码没有报异常时,这三个参数将都为None。

    • 理解并使用 contextlib#

      在上面的例子中,我们只是为了构建一个上下文管理器,却写了一个类。如果只是要实现一个简单的功能,写一个类未免有点过于繁杂。这时候,我们就想,如果只写一个函数就可以实现上下文管理器就好了。

      这个点Python早就想到了。它给我们提供了一个装饰器,你只要按照它的代码协议来实现函数内容,就可以将这个函数对象变成一个上下文管理器。

      我们按照 contextlib 的协议来自己实现一个打开文件(with open)的上下文管理器。

      1. import contextlib
      2. @contextlib.contextmanager
      3. def open_func(file_name):
      4. # __enter__方法
      5. print('open file:', file_name, 'in __enter__')
      6. file_handler = open(file_name, 'r')
      7. # 【重点】:yield
      8. yield file_handler
      9. # __exit__方法
      10. print('close file:', file_name, 'in __exit__')
      11. file_handler.close()
      12. return
      13. with open_func('/Users/MING/mytest.txt') as file_in:
      14. for line in file_in:
      15. print(line)

      在被装饰函数里,必须是一个生成器(带有yield),而yield之前的代码,就相当于__enter__里的内容。yield 之后的代码,就相当于__exit__ 里的内容。

      上面这段代码只能实现上下文管理器的第一个目的(管理资源),并不能实现第二个目的(处理异常)。

      如果要处理异常,可以改成下面这个样子。

      1. import contextlib
      2. @contextlib.contextmanager
      3. def open_func(file_name):
      4. # __enter__方法
      5. print('open file:', file_name, 'in __enter__')
      6. file_handler = open(file_name, 'r')
      7. try:
      8. yield file_handler
      9. except Exception as exc:
      10. # deal with exception
      11. print('the exception was thrown')
      12. finally:
      13. print('close file:', file_name, 'in __exit__')
      14. file_handler.close()
      15. return
      16. with open_func('/Users/MING/mytest.txt') as file_in:
      17. for line in file_in:
      18. 1/0
      19. print(line)
    • 复制知识点的参考文献较多,主要是为了解释编写的数据库使用的工具类中的知识点;

  • 手敲不易,转载请指明出处

数据库连接池与SQL工具类的更多相关文章

  1. 基于Druid数据库连接池的DBUtil工具类

    工具类 DruidUtil.java package com.zzuli.util; import com.alibaba.druid.pool.DruidDataSourceFactory; imp ...

  2. PHP文件上传,下载,Sql工具类!

    PHP文件上传,下载,Sql工具类! 对文件大小,文件类型 同名覆盖 中文转码的操作,可直接使用 前台 upload.html <!DOCTYPE html> <html> & ...

  3. 【知了堂学习心得】浅谈c3p0连接池和dbutils工具类的使用

    1. C3P0概述 C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展.目前使用它的开源项目有Hibernate,Spring等. 2. C3P ...

  4. spring boot:配置druid数据库连接池(开启sql防火墙/使用log4j2做异步日志/spring boot 2.3.2)

    一,druid数据库连接池的功能? 1,Druid是阿里巴巴开发的号称为监控而生的数据库连接池 它的优点包括: 可以监控数据库访问性能 SQL执行日志 SQL防火墙 2,druid的官方站: http ...

  5. Excel生成Oracle数据库表sql工具类

    1.解决问题: 开发文档中字段比较多的时候,建表sql(Oracle下划线命名规范)比较麻烦,容易出错~~ (主要是懒) 特意手写一个工具,根据excel字段,生成建表的sql语句. ~~~末尾附Gi ...

  6. mysql连接池的使用工具类代码示例

    mysql连接池代码工具示例(scala): import java.sql.{Connection,PreparedStatement,ResultSet} import org.apache.co ...

  7. java学习笔记37(sql工具类:JDBCUtils)

    在之前的内容中,我们发现,当我们执行一条语句时,每新建一个方法,就要重新连接一次数据库,代码重复率很高,那么能不能把这些重复代码封装成一个类呢,我们学习方法时,就学习到方法就是为了提高代码的利用率,所 ...

  8. SQL工具类

    package com.ebizwindow.crm.utils; import java.util.List; import com.ebizwindow.crm.constants.SqlCons ...

  9. sql 工具类function

    --判断是否为整数 create or replace function is_number(param VARCHAR2) return NUMBER is v_num NUMBER; begin ...

随机推荐

  1. K8S配置多集群访问

    中文官档: http://docs.kubernetes.org.cn/823.html 背景:我们通过会有多个k8s集群,例如集群(cn-k8s)和集群(jp-k8s),那个就需要有一台服务器可以同 ...

  2. 文本图Tranformer在文本分类中的应用

    原创作者 | 苏菲 论文来源: https://aclanthology.org/2020.emnlp-main.668/ 论文题目: Text Graph Transformer for Docum ...

  3. ideal 创建maven 项目

    一 准备工作,已经配置好了maven 环境 .没有的话,参考我的上一篇笔记. 二,ideal相关配置 打开ideal  找到设置. file  ------->setting  .     点击 ...

  4. 利用application在页面中显示访问次数

    在jsp页面中实现. <%@ page language="java" contentType="text/html; charset=UTF-8" pa ...

  5. JavaWeb基本概念及web服务器

    1.基本概念 1.1.前言 web开发: web,网页的意思,www.baidu.com 静态web html,css 提供给所有人看的数据始终不会发生变化! 动态web 淘宝,几乎是所有的网站: 提 ...

  6. NumPy 初学者指南中文第三版·翻译完成

    原文:NumPy: Beginner's Guide - Third Edition 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远. 在线阅 ...

  7. AT2699 [ARC081D] Flip and Rectangles

    以下是简要题解: 首先思考如何判定一个矩形是否能通过操作变成全黑. 首先从简单而又特殊的 \(2 \times 2\) 的矩形开始,不难发现只要其中黑色数量不为奇数即可. 近一步拓展可以发现,一个矩形 ...

  8. java getSource()和 getActionCommand()区别

    感谢大佬:https://blog.csdn.net/LIU_YANZHAO/article/details/72740011?utm_source=blogxgwz1 比如说 按纽的事件,同一个JF ...

  9. Java与网页JSP文件编码的小总结

    感谢大佬: https://www.cnblogs.com/yangguoe/p/8467672.html(编码发展史) https://blog.csdn.net/seabiscuityj/arti ...

  10. 如何使PreparedStatement支持命名参数

    http://m.blog.csdn.net/wallimn/article/details/3734242