数据库连接池与SQL工具类

1.数据库连接池

  • 依赖包

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

  • 使用多线程进行测试
    # 使用连接池
    def task():
    # 连接池获取连接
    conn=MYSQL_DB_POOL.connection()
    cursor=conn.cursor()
    cursor.execute("select * from student where sname='逻辑'")
    result=cursor.fetchall()
    print(result)
    conn.close()#将连接还给连接池
    # task() '''使用多线程进行测试'''
    def run():
    for i in range(10):
    t=threading.Thread(target=task)
    t.start() if __name__ == '__main__':
    # 开启10个线程进行测试
    run()

2.SQL工具类

2.1 单利模式的方式实现

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

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

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

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

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

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

2.2上下文管理

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

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

    • 基本语法

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

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

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

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

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

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

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

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

    • 理解并使用 contextlib#

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

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

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

      import contextlib
      
      @contextlib.contextmanager
      def open_func(file_name):
      # __enter__方法
      print('open file:', file_name, 'in __enter__')
      file_handler = open(file_name, 'r') # 【重点】:yield
      yield file_handler # __exit__方法
      print('close file:', file_name, 'in __exit__')
      file_handler.close()
      return with open_func('/Users/MING/mytest.txt') as file_in:
      for line in file_in:
      print(line)

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

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

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

      import contextlib
      
      @contextlib.contextmanager
      def open_func(file_name):
      # __enter__方法
      print('open file:', file_name, 'in __enter__')
      file_handler = open(file_name, 'r') try:
      yield file_handler
      except Exception as exc:
      # deal with exception
      print('the exception was thrown')
      finally:
      print('close file:', file_name, 'in __exit__')
      file_handler.close() return with open_func('/Users/MING/mytest.txt') as file_in:
      for line in file_in:
      1/0
      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. linux用户密码过期导致命令执行失败

    背景介绍: 使用zabbix调用系统命令,检查时间同步,发现一直在报错,root 用户执行无异常,问题还是出现zabbix用户上面. [zabbix@test-10-12 ~]$ sudo ntpda ...

  2. iGear 用了这个小魔法,模型训练速度提升 300%

    一个高精度AI模型离不开大量的优质数据集,这些数据集往往由标注结果文件和海量的图片组成.在数据量比较大的情况下,模型训练周期也会相应加长.那么有什么加快训练速度的好方法呢? 壕气的老板第一时间想到的通 ...

  3. Java线上问题排查神器Arthas实战分析

    概述 背景 是不是在实际开发工作当中经常碰到自己写的代码在开发.测试环境行云流水稳得一笔,可一到线上就经常不是缺这个就是少那个反正就是一顿报错抽风似的,线上调试代码又很麻烦,让人头疼得抓狂:而且deb ...

  4. LeetCode673

    LeetCode每日一题2021.9.20 LeetCode673. 最长递增子序列的个数 思路 在最长上升子序列的转移时,维护一个 cnt 数组,表示 以 i 结尾的最长上升子序列个数 f[i] 表 ...

  5. ApacheCN 深度学习译文集 20201229 更新

    新增了七个教程: TensorFlow 和 Keras 应用开发入门 零.前言 一.神经网络和深度学习简介 二.模型架构 三.模型评估和优化 四.产品化 TensorFlow 图像深度学习实用指南 零 ...

  6. Programiz 中文系列教程·翻译完成

    原文:Programiz 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远. 在线阅读 ApacheCN 学习资源 目录 Programiz C ...

  7. 在Android中用纯Java代码布局

    感谢大佬:https://www.jianshu.com/p/7aedea560f16 在Android中用纯Java代码布局 本文的完成了参考了一篇国外的教程,在此表示感谢. Android中的界面 ...

  8. java基础之抽象类的介绍

    抽象类的特点: 1.当方法只有声明没有具体实现的时候,需要用abstract修饰符修饰.抽象方法必须定义在抽象类当中,所以抽象类也需要用abstract修饰 2.抽象类不可以被实例化,为什么呢?   ...

  9. JSP页面重定向与页面内容转发

    重定向:属于两次请求+响应,客户端浏览器地址栏会改变. 转发:属于一次请求+一次响应,客户端浏览器地址栏不会改变. 重定向: response.setHeader("action" ...

  10. NSArray 遍历

    1.NSArray的下标遍历 NSArray *arr = @[p1, p2, p3, p4, p5]; for (int i = 0; i < arr.count; ++i) { Person ...