得到PrepareStatement最終執行的sql語句的方法(轉)
?
在CSDN的JAVA基礎版,常常有人問及如何得到PreparedStatement最終執行的SQL語句;或者如何在控制臺輸出占位符的真實值.....
原因就是PreparedStatement執行的sql語句有大量的占位符?....
問題諸如JDBC中:
亦或Hibernate中
無它,無論JDBC還是Hiberante都不提供默認解決方案,但是參數是設置進去的,我們在設置的過程中可以有充分的理由來截取并獲得自己想要的東西,類似于AOP理論。
共享我在工程中的使用方法:
插入操作:
更新查找操作:
執行查詢
看到getPreparedSQL(sql,?params)了么? 這個地方就是要實現我們預期效果的地方:

得到PrepareStatement最終執行的sql語句的方法
?1?/**
?2??????*?獲得PreparedStatement向數據庫提交的SQL語句
?3??????*?@param?sql
?4??????*?@param?params
?5??????*?@return
?6??????*/
?7?????private?String?getPreparedSQL(String?sql,?Object[]?params)?{
?8?????????//1?如果沒有參數,說明是不是動態SQL語句
?9?????????????????int?paramNum?=?0;
10?????????????????if?(null?!=?params)??paramNum?=?params.length;
11?????????if?(1?>?paramNum)?return?sql;
12?????????//2?如果有參數,則是動態SQL語句
13?????????StringBuffer?returnSQL?=?new?StringBuffer();
14?????????String[]?subSQL?=?sql.split("\\?");
15?????????for?(int?i?=?0;?i?<?paramNum;?i++)?{
16?????????????if?(params[i]?instanceof?Date)?{
17?????????????????returnSQL.append(subSQL[i]).append("?'").append(MyDateUtil.dateUtil2SQL((java.util.Date)params[i])).append("'?");
18?????????????}?else?{
19?????????????????returnSQL.append(subSQL[i]).append("?'").append(params[i]).append("'?");
20?????????????}
21?????????}
22?
23?????????if?(subSQL.length?>?params.length)?{
24?????????????returnSQL.append(subSQL[subSQL.length?-?1]);
25?????????}
26?????????return?returnSQL.toString();
27?????}
28?
29?????/**
30??????*?為PreparedStatement預編譯的SQL語句設置參數
31??????*?@param?pstmt
32??????*?@param?params
33??????*/
34?????private?void?setParams(PreparedStatement?pstmt,?Object[]?params)?{
35?????????????if?(null?!=?params)?{
36?????????????????for?(int?i?=?0,?paramNum?=?params.length;?i?<?paramNum;?i++)?{
37?????????????????????try?{
38?????????????????????????if?(null?!=?params[i]?&&
39?????????????????????????????params[i]?instanceof?java.util.Date)?{
40?????????????????????????????pstmt.setDate(i?+?1,?MyDateUtil.dateUtil2SQL(
41?????????????????????????????????????(java.util.Date)?params[i]));
42?????????????????????????}?else?{
43?????????????????????????????pstmt.setObject(i?+?1,?params[i]);
44?????????????????????????}
45?????????????????????}?catch?(SQLException?e)?{
46?????????????????????????throw?new?MySQLException(e);
47?????????????????????}
48?????????????????}
49?????????????}
50?????}
然后輕松核實你的控制臺或者日志文件吧......
原因就是PreparedStatement執行的sql語句有大量的占位符?....
問題諸如JDBC中:
如何得到?conn.prepareStatement?最終執行的sql語句。
sql="update?table1?set?a=?,b=?"
stmt?=?con.prepareStatement(sql);
stmt.setObjec?t(1,"a");
stmt.setObjec?t(2,"b");
希望可以通過stmt或者conn?得到:
update?table1?set?a='a',b='b'
sql="update?table1?set?a=?,b=?"
stmt?=?con.prepareStatement(sql);
stmt.setObjec?t(1,"a");
stmt.setObjec?t(2,"b");
希望可以通過stmt或者conn?得到:
update?table1?set?a='a',b='b'
亦或Hibernate中
如我執行:find("select?*?from?t_table?where?id?=??",new?Integer(5));
在控制臺顯示SQL時只顯示:select?*?from?t_table?where?id?=??
如何才能做到將控制臺顯示的占位符用其真實的值來替換?
即控制臺輸出時顯示:select?*?from?t_table?where?id?=?5
在控制臺顯示SQL時只顯示:select?*?from?t_table?where?id?=??
如何才能做到將控制臺顯示的占位符用其真實的值來替換?
即控制臺輸出時顯示:select?*?from?t_table?where?id?=?5
無它,無論JDBC還是Hiberante都不提供默認解決方案,但是參數是設置進去的,我們在設置的過程中可以有充分的理由來截取并獲得自己想要的東西,類似于AOP理論。
共享我在工程中的使用方法:
插入操作:
/**
?????*?執行插入數據庫的語句
?????*?@param?sql
?????*?@param?params
?????*?@return?返回生成的主鍵
?????*/
????public?int?executeInsert(String?sql,?Object[]?params)?{
????????Connection?conn?=?null;
????????PreparedStatement?pstmt?=?null;
????????ResultSet?rs?=?null;
????????try?{
????????????//1?獲得連接
????????????conn?=?MyDBConnection.getInstance().getConnection();
????????????//2?設置提交方式為程序控制
????????????conn.setAutoCommit(false);
????????????//3?獲得語句對象
????????????pstmt?=?conn.prepareStatement(sql,?Statement.RETURN_GENERATED_KEYS);
????????????//4?設置SQL語句的參數
????????????if?(null?!=?params?&&?0?<?params.length)?{
????????????????setParams(pstmt,?params);
????????????}
????????????//5?打印SQL語句
????????????if?(MyDBConstants.showSQL)?{
????????????????getPreparedSQL(sql,?params);
????????????}
????????????//6?執行語句
????????????pstmt.executeUpdate();
????????????//7?程序提交
????????????conn.commit();
????????????//8?返回生成的主鍵
????????????rs?=?pstmt.getGeneratedKeys();
????????????int?generatedKey?=?0;
????????????if?(rs.next())?{
????????????????generatedKey?=?rs.getInt(1);
????????????}
????????????if?(0?<?generatedKey)
????????????????throw?new?MySQLException("插入記錄時出錯");
????????????return?generatedKey;
????????}?catch?(SQLException?e)?{
????????????//回滾
????????????MyDBUtil.rollBack(conn);
????????????throw?new?MySQLException(e);
????????}?finally?{
????????????//關閉打開的操作
????????????MyDBUtil.close(conn,?pstmt,?rs);
????????}
????}
?????*?執行插入數據庫的語句
?????*?@param?sql
?????*?@param?params
?????*?@return?返回生成的主鍵
?????*/
????public?int?executeInsert(String?sql,?Object[]?params)?{
????????Connection?conn?=?null;
????????PreparedStatement?pstmt?=?null;
????????ResultSet?rs?=?null;
????????try?{
????????????//1?獲得連接
????????????conn?=?MyDBConnection.getInstance().getConnection();
????????????//2?設置提交方式為程序控制
????????????conn.setAutoCommit(false);
????????????//3?獲得語句對象
????????????pstmt?=?conn.prepareStatement(sql,?Statement.RETURN_GENERATED_KEYS);
????????????//4?設置SQL語句的參數
????????????if?(null?!=?params?&&?0?<?params.length)?{
????????????????setParams(pstmt,?params);
????????????}
????????????//5?打印SQL語句
????????????if?(MyDBConstants.showSQL)?{
????????????????getPreparedSQL(sql,?params);
????????????}
????????????//6?執行語句
????????????pstmt.executeUpdate();
????????????//7?程序提交
????????????conn.commit();
????????????//8?返回生成的主鍵
????????????rs?=?pstmt.getGeneratedKeys();
????????????int?generatedKey?=?0;
????????????if?(rs.next())?{
????????????????generatedKey?=?rs.getInt(1);
????????????}
????????????if?(0?<?generatedKey)
????????????????throw?new?MySQLException("插入記錄時出錯");
????????????return?generatedKey;
????????}?catch?(SQLException?e)?{
????????????//回滾
????????????MyDBUtil.rollBack(conn);
????????????throw?new?MySQLException(e);
????????}?finally?{
????????????//關閉打開的操作
????????????MyDBUtil.close(conn,?pstmt,?rs);
????????}
????}
更新查找操作:
/**
?????*?執行更新或者刪除數據庫的語句
?????*?@param?sql
?????*?@param?params
?????*?@return?返回執行成功與否
?????*/
????public?boolean?executeUpdateDel(String?sql,?Object[]?params)?{
????????boolean?isSuccess?=?false;
????????Connection?conn?=?null;
????????PreparedStatement?pstmt?=?null;
????????try?{
????????????//1?獲得連接
????????????conn?=?MyDBConnection.getInstance().getConnection();
????????????//2?設置提交方式為程序控制
????????????conn.setAutoCommit(false);
????????????//3?獲得語句對象
????????????pstmt?=?conn.prepareStatement(sql);
????????????//4?設置SQL語句的參數
????????????if?(null?!=?params?&&?0?<?params.length)?{
????????????????setParams(pstmt,?params);
????????????}
????????????//5?打印SQL語句
????????????if?(MyDBConstants.showSQL)?{
????????????????getPreparedSQL(sql,?params);
????????????}
????????????//6?執行語句
????????????pstmt.executeUpdate();
????????????//7?程序提交
????????????conn.commit();
????????????//8?設置語句執行的標記
????????????isSuccess?=?true;
????????}?catch?(SQLException?e)?{
????????????//回滾
????????????MyDBUtil.rollBack(conn);
????????????throw?new?MySQLException(e);
????????}?finally?{
????????????//關閉打開的操作
????????????MyDBUtil.close(conn,?pstmt);
????????}
????????return?isSuccess;
????}
?????*?執行更新或者刪除數據庫的語句
?????*?@param?sql
?????*?@param?params
?????*?@return?返回執行成功與否
?????*/
????public?boolean?executeUpdateDel(String?sql,?Object[]?params)?{
????????boolean?isSuccess?=?false;
????????Connection?conn?=?null;
????????PreparedStatement?pstmt?=?null;
????????try?{
????????????//1?獲得連接
????????????conn?=?MyDBConnection.getInstance().getConnection();
????????????//2?設置提交方式為程序控制
????????????conn.setAutoCommit(false);
????????????//3?獲得語句對象
????????????pstmt?=?conn.prepareStatement(sql);
????????????//4?設置SQL語句的參數
????????????if?(null?!=?params?&&?0?<?params.length)?{
????????????????setParams(pstmt,?params);
????????????}
????????????//5?打印SQL語句
????????????if?(MyDBConstants.showSQL)?{
????????????????getPreparedSQL(sql,?params);
????????????}
????????????//6?執行語句
????????????pstmt.executeUpdate();
????????????//7?程序提交
????????????conn.commit();
????????????//8?設置語句執行的標記
????????????isSuccess?=?true;
????????}?catch?(SQLException?e)?{
????????????//回滾
????????????MyDBUtil.rollBack(conn);
????????????throw?new?MySQLException(e);
????????}?finally?{
????????????//關閉打開的操作
????????????MyDBUtil.close(conn,?pstmt);
????????}
????????return?isSuccess;
????}
執行查詢
?1?/**
?2??????*?執行查詢數據庫的語句;
?9??????*
10??????*?@return
11??????*/
12?????public?Object?executeQuery(String?sql,?Object[]?params)?{
13?????????Connection?conn?=?null;
14?????????PreparedStatement?pstmt?=?null;
15?????????ResultSet?rs?=?null;
16?????????try?{
17?????????????//1?獲得連接
18?????????????conn?=?MyDBConnection.getInstance().getConnection();
19?????????????//2?設置提交方式為程序控制
20?????????????conn.setAutoCommit(false);
21?????????????//3?獲得語句對象
22?????????????pstmt?=?conn.prepareStatement(sql,?ResultSet.TYPE_SCROLL_SENSITIVE,?ResultSet.CONCUR_UPDATABLE);
23?????????????//4?設置SQL語句的參數
24?????????????if?(null?!=?params?&&?0?<?params.length)?{
25?????????????????setParams(pstmt,?params);
26?????????????}
27?????????????//5?打印SQL語句
28?????????????if?(MyDBConstants.showSQL)?{
29?????????????????getPreparedSQL(sql,?params);
30?????????????}
31?????????????//6?執行語句
32?????????????rs?=?pstmt.executeQuery();
33?
34?????????????//9?程序提交
35?????????????conn.commit();
36?
37?????????????//10?獲得記錄
38?????????????Object?vo?=?new?Object();
39?????????????if?(null?!=?rs?&&?rs.next())?{
40?????????????????vo?=?rs2vo(rs);
41?????????????}
42?//????????????return?results;
43?????????????return?vo;
44?????????}?catch?(SQLException?e)?{
45?????????????//回滾
46?????????????MyDBUtil.rollBack(conn);
47?????????????throw?new?MySQLException(e);
48?????????}?finally?{
49?????????????//關閉打開的操作
50?????????????MyDBUtil.close(conn,?pstmt,?rs);
51?????????}
52?????}
?2??????*?執行查詢數據庫的語句;
?9??????*
10??????*?@return
11??????*/
12?????public?Object?executeQuery(String?sql,?Object[]?params)?{
13?????????Connection?conn?=?null;
14?????????PreparedStatement?pstmt?=?null;
15?????????ResultSet?rs?=?null;
16?????????try?{
17?????????????//1?獲得連接
18?????????????conn?=?MyDBConnection.getInstance().getConnection();
19?????????????//2?設置提交方式為程序控制
20?????????????conn.setAutoCommit(false);
21?????????????//3?獲得語句對象
22?????????????pstmt?=?conn.prepareStatement(sql,?ResultSet.TYPE_SCROLL_SENSITIVE,?ResultSet.CONCUR_UPDATABLE);
23?????????????//4?設置SQL語句的參數
24?????????????if?(null?!=?params?&&?0?<?params.length)?{
25?????????????????setParams(pstmt,?params);
26?????????????}
27?????????????//5?打印SQL語句
28?????????????if?(MyDBConstants.showSQL)?{
29?????????????????getPreparedSQL(sql,?params);
30?????????????}
31?????????????//6?執行語句
32?????????????rs?=?pstmt.executeQuery();
33?
34?????????????//9?程序提交
35?????????????conn.commit();
36?
37?????????????//10?獲得記錄
38?????????????Object?vo?=?new?Object();
39?????????????if?(null?!=?rs?&&?rs.next())?{
40?????????????????vo?=?rs2vo(rs);
41?????????????}
42?//????????????return?results;
43?????????????return?vo;
44?????????}?catch?(SQLException?e)?{
45?????????????//回滾
46?????????????MyDBUtil.rollBack(conn);
47?????????????throw?new?MySQLException(e);
48?????????}?finally?{
49?????????????//關閉打開的操作
50?????????????MyDBUtil.close(conn,?pstmt,?rs);
51?????????}
52?????}
看到getPreparedSQL(sql,?params)了么? 這個地方就是要實現我們預期效果的地方:


?1?/**
?2??????*?獲得PreparedStatement向數據庫提交的SQL語句
?3??????*?@param?sql
?4??????*?@param?params
?5??????*?@return
?6??????*/
?7?????private?String?getPreparedSQL(String?sql,?Object[]?params)?{
?8?????????//1?如果沒有參數,說明是不是動態SQL語句
?9?????????????????int?paramNum?=?0;
10?????????????????if?(null?!=?params)??paramNum?=?params.length;
11?????????if?(1?>?paramNum)?return?sql;
12?????????//2?如果有參數,則是動態SQL語句
13?????????StringBuffer?returnSQL?=?new?StringBuffer();
14?????????String[]?subSQL?=?sql.split("\\?");
15?????????for?(int?i?=?0;?i?<?paramNum;?i++)?{
16?????????????if?(params[i]?instanceof?Date)?{
17?????????????????returnSQL.append(subSQL[i]).append("?'").append(MyDateUtil.dateUtil2SQL((java.util.Date)params[i])).append("'?");
18?????????????}?else?{
19?????????????????returnSQL.append(subSQL[i]).append("?'").append(params[i]).append("'?");
20?????????????}
21?????????}
22?
23?????????if?(subSQL.length?>?params.length)?{
24?????????????returnSQL.append(subSQL[subSQL.length?-?1]);
25?????????}
26?????????return?returnSQL.toString();
27?????}
28?
29?????/**
30??????*?為PreparedStatement預編譯的SQL語句設置參數
31??????*?@param?pstmt
32??????*?@param?params
33??????*/
34?????private?void?setParams(PreparedStatement?pstmt,?Object[]?params)?{
35?????????????if?(null?!=?params)?{
36?????????????????for?(int?i?=?0,?paramNum?=?params.length;?i?<?paramNum;?i++)?{
37?????????????????????try?{
38?????????????????????????if?(null?!=?params[i]?&&
39?????????????????????????????params[i]?instanceof?java.util.Date)?{
40?????????????????????????????pstmt.setDate(i?+?1,?MyDateUtil.dateUtil2SQL(
41?????????????????????????????????????(java.util.Date)?params[i]));
42?????????????????????????}?else?{
43?????????????????????????????pstmt.setObject(i?+?1,?params[i]);
44?????????????????????????}
45?????????????????????}?catch?(SQLException?e)?{
46?????????????????????????throw?new?MySQLException(e);
47?????????????????????}
48?????????????????}
49?????????????}
50?????}
然后輕松核實你的控制臺或者日志文件吧......
posted on 2006-07-24 16:22 liaojiyong 閱讀(2013) 評論(0) 編輯 收藏 所屬分類: DBMixture