日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

用 p6spy 來觀察 Java 程序中執(zhí)行的所有 SQL 語句

 guolijiegg 2012-02-14

既然提到 p6spy 的輸出,那就有必要說明一下 p6spy 輸出日志的格式了。從上一篇 用 p6spy 來觀察 Java 程序中執(zhí)行的所有 SQL 語句(二. Tomcat 下的配置) 中把輸出的一段內(nèi)容拿過來,如下:

03-16-09 15:12:06:656|16|4|statement|SELECT * FROM OM_CUSTOMERS  WHERE CUSTOMER_ID=? ORDER BY CUSTOMER_ID ASC|SELECT * FROM OM_CUSTOMERS  WHERE CUSTOMER_ID=2194 ORDER BY CUSTOMER_ID ASC
03-16-09 15:12:06:671|15|3|statement|SELECT * FROM OM_ORDER_TYPE WHERE TYPE_ID=?|SELECT * FROM OM_ORDER_TYPE WHERE TYPE_ID=25
03-16-09 15:12:06:687|16|1|statement|select * from sys_lookups where lookup_type=?  and lookup_code=? |select * from sys_lookups where lookup_type='OM_ORDER_STATUS'  and lookup_code='70'
03-16-09 15:12:06:812|-1||resultset|select * from sys_lookups where lookup_type='OM_ORDER_STATUS'  and lookup_code='70' |meaning = 已安排生產(chǎn)

  再看 p6spy 官方文檔的關(guān)于日志文件(控制臺輸出/Log4J也一樣)格式的說明 -- http://www./documentation/other.htm#log。日志格式是:

current time|execution time|category|statement SQL string|effective SQL string

  current time -- 當前時間

  execution time -- 執(zhí)行時長,包括執(zhí)行 SQL 和處理結(jié)果集的時間(可以參考來調(diào)優(yōu))

  category  -- 語句分類,statement、resultset 等

  statement SQL string -- 查詢語句。可能是 prepared statement,表現(xiàn)為 select * from table1 where c1=?,問號參數(shù)形式
effective SQL string -- 代入?yún)?shù)值的查詢語句,如 select * from from table1 where c1=7

  看到上面的日志輸出,我們可能會有如下需求:

  1) 對于 category 為 resultset 的輸出你可能并不關(guān)心,查詢了什么字段,取哪個字段或許早心理有數(shù)。上面例子中的 resultset 是 select *,然而只取了 meaning 一個字段,這是不推薦的。(不輸出 resultset 語句)

  2) 你可能不想被那些帶問號參數(shù)的 prepared statement 干擾,而想直接看最終被執(zhí)行的語句。(statement SQL string 不顯示)

  3) 你可能會想把控制臺或日志文件中的一連串幾個語句直接復制,貼到數(shù)據(jù)庫客戶端就能執(zhí)行。(只輸出 effective SQL string,并以分號隔開)

  對于第一個要求,我們可以利用 p6spy 的顯示過濾功能,可在 p6spy.properties 中配置。p6spy 有 resultset 這樣一個 category,卻未完善對其的過濾控制,為此我們需要修改源代碼 com.p6spy.engine.spy.P6ResultSet.Java,找到 152 行的

P6LogQuery.log("resultset", query, buffer.toString());

  把其改為

//P6LogQuery.log("resultset", query, buffer.toString());  
P6Connection p6connection = (P6Connection)this.statement.getConnection();  
P6LogQuery.logElapsed(p6connection.getId(), System.currentTimeMillis(),"resultset", preparedQuery, query); 

  編譯(最好用 1.4 或 1.5 的JDK 來編譯,因為 JDK 1.6 的 ResultSet 多了些要實現(xiàn)的方法,修改起來要麻煩很多),把該類替換掉原來 p6spy.jar 中的相應 class。編譯好的 FormattedLogger 在附件 changed_p6spy_classes.rar 中有,是 P6ResultSet.class 文件。
然后修改 p6spy.properties 文件,找到

excludecategories=info,debug,result,batch

  加上對 resultset 的排除,改為

excludecategories=info,debug,result,batch,resultset

  這樣,在輸出的語句中就沒有眼花繚亂的 resultset 語句了,清爽了許多。

  對于第二個要求,我們還要修改的是源代碼 com.p6spy.engine.logging.appender.FormattedLogger,在 72 行找到

String logEntry = now + "|"+ elapsed + "|"+(connectionId==-1 ? "" : String.valueOf(connectionId))+"|"+category+"|"+prepared+"|"+sql;

  我們不希望輸出 prepared,所以把它改為

String logEntry = now + "|"+ elapsed + "|"+(connectionId==-1 ? "" : String.valueOf(connectionId))+"|"+category+"|"+sql;

  編譯,替換掉原 p6spy.jar 中相應類,編譯好的 FormattedLogger 是附件 changed_p6spy_classes.rar 中有,是 FormattedLogger.class 文件。

  要滿足第三個條件,還是修改 com.p6spy.engine.logging.appender.FormattedLogger 的同一行代碼,改為

String logEntry = sql + ";";

  編譯,替換掉原 p6spy.jar 中相應類,編譯好的 FormattedLogger 是附件 changed_p6spy_classes.rar 中有,是 FormattedLogger1.class 文件,替換的時候請更名。那么由它指示輸出的 SQL 語句就是以分號分隔的一條條了,基本是連續(xù)幾條一起復制出來,放到 SQL 客戶端工具中就能執(zhí)行了。當然字符串的參數(shù)還是要稍加處理的。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多