P6Spy源码分析,理解跟踪SQL的工作原理

2024-02-22 17:32

本文主要是介绍P6Spy源码分析,理解跟踪SQL的工作原理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

P6Spy是记录JDBC调用日志信息的一个工具,既然记录了JDBC调用,当然就可以监听到SQL,是开发人员必备的开发利器.可以让开发人员非常方便的知道当前应用程序执行了那些sql

P6Spy官方网站http://www.p6spy.com/index.html

在介绍P6Spy工作原理之前先回忆下传统jdbc的取得连接的方法
Class.forName("oracle.jdbc.driver.OracleDriver");//动态加载oracle.jdbc.driver.OracleDriver类,有关类加载这里就不做介绍了.
conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);//加载驱动后就可以取得连接了

多么经典的一段代码啊,通俗的说sun定义了一套jdbc接口,由各个数据库厂商去实现,其中java.sql.Driver是一个核心接口,该接口核心方法 boolean acceptsURL(String url) ,以OracleDriver为例,oracle.jdbc.driver.OracleDriver类实现了Driver接口,当显示的调用 Class.forName("oracle.jdbc.driver.OracleDriver");时,OracleDriver会被加载,执行static{}块内的代码,做些初始化工作.当然一个应用往往有时会连接多个数据库,所以衍生了DriverManager类,这个类负责管理多个数据库驱动,也就是多个driver对象,这也是为什么Driver接口有个方法叫acceptsURL的原因,因为当DriverManager管理多个driver对象的时候,调用DriverManager.getConnection(URL, USERNAME, PASSWORD);时,DriverManager必须知道当前Url请求的是那个数据库,最直接的实现想法就是循环遍历每个驱动调用驱动的acceptsURL方法,如果返回true的话,则返回该驱动的连接,所以每个数据库驱动定义的URL格式都不同,因为必须每个驱动都能识别多自己的URL. 同时DriverManager还提供registerDriver和deregisterDriver方法,前者将驱动实例添加到DriverManager类的容器中,后者将驱动从容器中删除,就是所谓的注册驱动和反注册驱动.


上面介绍了JDBC的基本工作原理,下面介绍下P6Spy的配置,首先要改驱动,例如把应用中写com.microsoft.jdbc.sqlserver.SQLServerDriver的地方改为com.p6spy.engine.spy.P6SpyDriver,无论是连接池还是经典的jdbc.然后在spy.properties驱动中配置realDriver,这里是真正的驱动com.microsoft.jdbc.sqlserver.SQLServerDriver,然后将p6spy.jar放到classpath中即可.至于其他输出形式的配置就不介绍了,例如sqlprofiler等.

了解了P6Spy的配置,下面来看P6Spy的源码,首先声明源码已经被我改过了,只保留了最最核心的东西,所以下面的源码和真实的P6Spy源码有些不同,但核心的方法和思想都是一样的,原来的方法中大量的辅助功能和配置参数判断,代码过长不便于贴出来分析. 由于本人文采不佳所以决定通过在代码上面添加注释的方式来讲解代码.

package  com.p6spy.engine.spy;

import  java.util.ArrayList;
import  java.util.Enumeration;
import  java.util.List;
import  java.util.ResourceBundle;

public   class  P6SpyDriver  extends  P6SpyDriverCore {

    
static  { //  Class.forName("com.p6spy.engine.spy.P6SpyDriver");当加载这个类时会触发此程序块
        init();
    }

    
/**
     * 初始化过程,本方法原名initMethod,由于父类也有此名称static方法不能重载为了避免引起奇异改为init
     
*/
    
public   static   void  init() {
        List driverNames 
=   new  ArrayList(); //  存放真实驱动的驱动名容器
         try  {
            loadDriverNames(driverNames);
//  从配置文件加载真实驱动的驱动名
             if  (driverNames  ==   null   ||  driverNames.size()  ==   0 )
                
return ;
            P6SpyDriverCore.initMethod(driverNames);
//  核心方法
        }  catch  (Throwable e) {
            e.printStackTrace();
        }
    }

    
private   static   void  loadDriverNames(List driverNames) {
        
try  {
            ResourceBundle resources 
=  ResourceBundle.getBundle( " spy-drivers " );
            Enumeration keys 
=  resources.getKeys();
            
while  (keys.hasMoreElements()) {
                driverNames.add(resources.getString(keys.nextElement()
                        .toString().trim()));
            }
        } 
catch  (Throwable e) {
            e.printStackTrace();
            driverNames.add(
" oracle.jdbc.driver.OracleDriver " );
            driverNames.add(
" com.microsoft.jdbc.sqlserver.SQLServerDriver " );
            driverNames.add(
" com.mysql.jdbc.Driver " );
            driverNames.add(
" COM.ibm.db2.jdbc.net.DB2Driver " );
            driverNames.add(
" com.informix.jdbc.IfxDriver " );
            driverNames.add(
" org.hsqldb.jdbcDriver " );
        }
    }

 
}
 

这篇关于P6Spy源码分析,理解跟踪SQL的工作原理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/735990

相关文章

SpringBoot集成P6Spy的实现示例

《SpringBoot集成P6Spy的实现示例》本文主要介绍了SpringBoot集成P6Spy的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录本节目标P6Spy简介抛出问题集成P6Spy1. SpringBoot三板斧之加入依赖2. 修改

redis和redission分布式锁原理及区别说明

《redis和redission分布式锁原理及区别说明》文章对比了synchronized、乐观锁、Redis分布式锁及Redission锁的原理与区别,指出在集群环境下synchronized失效,... 目录Redis和redission分布式锁原理及区别1、有的同伴想到了synchronized关键字

MySQL 临时表创建与使用详细说明

《MySQL临时表创建与使用详细说明》MySQL临时表是存储在内存或磁盘的临时数据表,会话结束时自动销毁,适合存储中间计算结果或临时数据集,其名称以#开头(如#TempTable),本文给大家介绍M... 目录mysql 临时表详细说明1.定义2.核心特性3.创建与使用4.典型应用场景5.生命周期管理6.注

MySQL磁盘空间不足问题解决

《MySQL磁盘空间不足问题解决》本文介绍查看空间使用情况的方式,以及各种空间问题的原因和解决方案,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录查看空间使用情况Binlog日志文件占用过多表上的索引太多导致空间不足大字段导致空间不足表空间碎片太多导致空间不足临时表空间

MySQL进行分片合并的实现步骤

《MySQL进行分片合并的实现步骤》分片合并是指在分布式数据库系统中,将不同分片上的查询结果进行整合,以获得完整的查询结果,下面就来具体介绍一下,感兴趣的可以了解一下... 目录环境准备项目依赖数据源配置分片上下文分片查询和合并代码实现1. 查询单条记录2. 跨分片查询和合并测试结论分片合并(Shardin

MySQL配置多主复制的实现步骤

《MySQL配置多主复制的实现步骤》多主复制是一种允许多个MySQL服务器同时接受写操作的复制方式,本文就来介绍一下MySQL配置多主复制的实现步骤,具有一定的参考价值,感兴趣的可以了解一下... 目录1. 环境准备2. 配置每台服务器2.1 修改每台服务器的配置文件3. 安装和配置插件4. 启动组复制4.

MySQL数据脱敏的实现方法

《MySQL数据脱敏的实现方法》本文主要介绍了MySQL数据脱敏的实现方法,包括字符替换、加密等方法,通过工具类和数据库服务整合,确保敏感信息在查询结果中被掩码处理,感兴趣的可以了解一下... 目录一. 数据脱敏的方法二. 字符替换脱敏1. 创建数据脱敏工具类三. 整合到数据库操作1. 创建服务类进行数据库

MySQL慢查询工具的使用小结

《MySQL慢查询工具的使用小结》使用MySQL的慢查询工具可以帮助开发者识别和优化性能不佳的SQL查询,本文就来介绍一下MySQL的慢查询工具,具有一定的参考价值,感兴趣的可以了解一下... 目录一、启用慢查询日志1.1 编辑mysql配置文件1.2 重启MySQL服务二、配置动态参数(可选)三、分析慢查

MYSQL中information_schema的使用

《MYSQL中information_schema的使用》information_schema是MySQL中的一个虚拟数据库,用于提供关于MySQL服务器及其数据库的元数,这些元数据包括数据库名称、表... 目录关键要点什么是information_schema?主要功能使用示例mysql 中informa

MySQL容灾备份的实现方案

《MySQL容灾备份的实现方案》进行MySQL的容灾备份是确保数据安全和业务连续性的关键步骤,容灾备份可以分为本地备份和远程备份,主要包括逻辑备份和物理备份两种方式,下面就来具体介绍一下... 目录一、逻辑备份1. 使用mysqldump进行逻辑备份1.1 全库备份1.2 单库备份1.3 单表备份2. 恢复