cuiyi's blog(崔毅 crazycy)

记录点滴 鉴往事之得失 以资于发展
数据加载中……

得到PrepareStatement最终执行的sql语句的方法

在CSDN的JAVA基础版,常常有人问及如何得到PreparedStatement最终执行的SQL语句;或者如何在控制台输出占位符的真实值.....

原因就是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'

亦或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

无它,无论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 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     }

看到getPreparedSQL(sql, params)了么? 这个地方就是要实现我们预期效果的地方:
得到PrepareStatement最终执行的sql语句的方法

然后轻松核实你的控制台或者日志文件吧......

posted on 2006-07-22 21:53 crazycy 阅读(46482) 评论(18)  编辑  收藏 所属分类: JavaEE技术DBMS

评论

# re: 得到PrepareStatement最终执行的sql语句的方法  回复  更多评论   

呵,不错的方法。不过采用p6spy也是一个很好的选择!
2006-07-23 11:49 | 胡子鱼

# re: 得到PrepareStatement最终执行的sql语句的方法  回复  更多评论   

@胡子鱼
呵呵,多谢多谢;share一些摸索,可以换来更好的建议,高兴一个.....
p6sky?查查去
2006-07-23 13:20 | crazycy

# re: 得到PrepareStatement最终执行的sql语句的方法  回复  更多评论   

里面用到了自己写的一些类,不具有通用功能.
2006-07-24 15:02 | THEMAX

# re: 得到PrepareStatement最终执行的sql语句的方法  回复  更多评论   

原来是需要自己写的class,

还以为不需要自己写class,就可以搞定呢。。。
2007-05-02 15:43 | ddd

# re: 得到PrepareStatement最终执行的sql语句的方法  回复  更多评论   

遇到 INt型如何处理 存不进这个Object[] params数组
还想看看setParams(pstmt, params)这个函数
2007-05-13 12:20 | 新手

# re: 得到PrepareStatement最终执行的sql语句的方法  回复  更多评论   

int ==> Integer new Integer(int)
2007-05-13 23:42 | crazycy

# re: 得到PrepareStatement最终执行的sql语句的方法  回复  更多评论   

String sql = "SELECT 学号,姓名,班级,数学,英语,JAVA,计算机导引,思想道德,马克思主义 FROM Student1"+" WHERE 班级=?";
PreparedStatement preSt = con.prepareStatement(sql);
preSt.setString(1,ban);
ResultSet rs1 = preSt.executeQuery();
2007-12-25 15:51 | slang

# re: 得到PrepareStatement最终执行的sql语句的方法  回复  更多评论   

还得把 int, double, long, float, boolean 变成对应的 Object, 麻烦。
2008-02-14 22:09 | fz_zhou

# re: 得到PrepareStatement最终执行的sql语句的方法  回复  更多评论   

关注一下,有用到的时候回头看看
2008-03-11 12:03 | 隔叶黄莺

# re: 得到PrepareStatement最终执行的sql语句的方法  回复  更多评论   

why not just prepstmt.toString(), and grab the useful sql from it?
2008-03-28 08:25 | Liang

# re: 得到PrepareStatement最终执行的sql语句的方法  回复  更多评论   

The purpose of tracing prepared sql is to check the fields while doing insert, as you know, sometimes some filed would be "" or null while it isnot mandory in database, but should not be "" or null
2008-03-31 22:05 | crazycy

# re: 得到PrepareStatement最终执行的sql语句的方法  回复  更多评论   

请问主人,能不能个iekankanMyDBConnection类的实现呀,谢谢
2009-05-31 09:05 | gousehng123

# re: 得到PrepareStatement最终执行的sql语句的方法  回复  更多评论   

能不能提供下载呀...
2009-06-25 11:29 | zstop

# re: 得到PrepareStatement最终执行的sql语句的方法[未登录]  回复  更多评论   

gei ge yuanma kan kan a

2012-01-06 16:42 | xxx

# wrwe  回复  更多评论   

sdasd
2012-08-17 16:07 | adead

# re: 得到PrepareStatement最终执行的sql语句的方法  回复  更多评论   

请问:方法里面的参数sql要怎么获取得到?像insert,update,delete这种更新操作的sql语句, query语句的获取我已经实现了,我的博文地址: http://www.cnblogs.com/huangxiufen/p/3845288.html
2014-07-29 15:46 | 大象与蚂蚁

# re: 得到PrepareStatement最终执行的sql语句的方法  回复  更多评论   

if (0 < generatedKey)
throw new MySQLException("插入记录时出错");
return generatedKey;

//这里的 判断gennerateKey 判断会出现BUG
应该是
if (generatedKey<0)
throw new MySQLException("插入记录时出错");
return generatedKey;
2015-02-03 17:58 | #RES

# re: 得到PrepareStatement最终执行的sql语句的方法  回复  更多评论   

@liang 说的有道理 为什么不适用tostring()?就是在设置好参数后,调用它
2015-08-24 10:00 | angelmom

只有注册用户登录后才能发表评论。


网站导航: