怎样在控制台或者日志打印输出JDBC执行的sql语句

时间:2024-10-30 18:06:50

今天用jdbc preparestatement 写sql语句查询,但是在执行的过程中实际查询出的结果和预期的结果不一致,然后就在想有什么办法能够在控制台或者Log4j日志输出最终执行的SQL语句,以便于调试。如果是hibernate可以通过配置show_sql 为 true 在控制台显示执行的SQL,因为使用的是纯JDBC的写法,然后自己在程序中直接通过(sql);打印SQL语句,然后又打印参数,这种方式确实是可以。但是,遇到insert语句或者Update语句的时候,因为实际操作中需要传入的匹配参数有点多,然后通过()这种方式写的就有点多了,十几个参数就需要写十几行,然后就在想,能不能通过什么方式进行简化一下。。。

/**
     * 显示SQL语句
     * @param sql
     * @param paramMap
     */
    public static void show_sql(Logger log,String sql,List<String> paramList){
        ("##sql:{}",sql);
        ("##参数:{}",(paramList));

        /*if(null != paramList && () > 0){
            for (int i = 0; i < (); i++) {
                (""+i+" : "+(i));
            }
        }*/
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

最原始的方法,直接一个一个取:

//输出SQL语句
            paramList.add(officeUserInfo.getUsername());
            paramList.add(officeUserInfo.getPassword());
            paramList.add(officeUserInfo.getCust_name());
            paramList.add(officeUserInfo.getMobile());
            paramList.add(String.valueOf(officeUserInfo.getState()));
            paramList.add(officeUserInfo.getOffice_id());
            paramList.add(String.valueOf(officeUserInfo.getRole()));
            paramList.add(officeUserInfo.getTel());
            paramList.add(officeUserInfo.getLeadPerson());
            paramList.add(officeUserInfo.getMobile2());
            paramList.add(officeUserInfo.getTel2());
            paramList.add(officeUserInfo.getContact());
            paramList.add(officeUserInfo.getQq());
            paramList.add(officeUserInfo.getFex());
            paramList.add(officeUserInfo.getAddr());
            paramList.add(officeUserInfo.getAddr2());
            paramList.add(officeUserInfo.getCust_tax_code());
            paramList.add(officeUserInfo.getIdcard_no());
            paramList.add(officeUserInfo.getSws());
            paramList.add(officeUserInfo.getSsfj());
            paramList.add(String.valueOf(officeUserInfo.getUserType()));
            paramList.add(officeUserInfo.getCreate_user());
            paramList.add(officeUserInfo.getUpdate_user());
            paramList.add(officeUserInfo.getCreate_time());
            paramList.add(officeUserInfo.getUpdate_time());
            CommonUtil.show_sql(log, sql, paramList);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

然后这种方式就有点伤,虽然比较笨挫,但是确实是有效的方式,之后又想起了前段时间刚刚学习的反射机制,突然意识到好像可以通过Java反射机制直接get取值,然后上面的代码就可以简化成下面的,关于反射机制在前一篇博客中已经有过介绍,这里也是直接调用的那个反射工具类中封装的取值方法:

Java学习之反射机制 :
/hu1991die/article/details/43793931

利用反射取值:

//通过反射取值
            Map<String, String> getFieldValueMap = ClassRefUtil.getFieldValueMap(officeUserInfo);
            for (Entry<String, String> entry : getFieldValueMap.entrySet()) {
                //因为返回的是一个Map类型的集合,然后需要对这个集合进行迭代,然后将值装载到paramList中,最后日志循环输出
                paramList.add(entry.getValue());
            }
            CommonUtil.show_sql(log, sql, paramList);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

输出结果:

这里写图片描述

最后的输出结果和上面的是一致的,上面的其实也可以直接循环输出通过反射取值后返回的map类型的集合,因为前面有很多地方都用到了paramList,然后参数都是放在paramList中的,所以感觉这个地方多此一举了,本来直接就可以通过遍历map集合输出结果,而这里还要先从map集合中遍历出来,然后装进list中,然后又遍历list输出最终结果,,,因为前面很多地方都用到了,所以这个地方就没有改过来。

例子:

这里写图片描述

输出结果:

这里写图片描述

下面是改进之后的,直接使用map存参数就可以了。

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

然后下面的这种insert语句,通过PrepareStatement预编译方式赋值的时候,其实也是可以通过这种反射取值的方式,循环赋值,不过,这个地方好像需要注意一点:insert语句中的?的顺序必须要和POJO类中定义的属性的顺序应该要完全一致才可以,不然就有可能赋值的时候会出现匹配不正确的情况,有可能本来b位置的值赋给了a,那就伤大了,我想那些框架(如Hibernate等)应该都是通过反射进行处理的,具体是怎么处理的我现在还不知道,改天去研究研究。。

这里写图片描述