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

本文介绍了一种方法,可以在Java中通过PreparedStatement获取最终执行的SQL语句,并将其输出到控制台,便于调试。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

在优快云的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语句的方法 - shmily - 我的地盘我做主得到PrepareStatement最终执行的sql语句的方法 - shmily - 我的地盘我做主得到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     }

然后轻松核实你的控制台或者日

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值