JDBMonitor日志输出探究(做executeBatch时发现一个BUG所引发的)

JDBMonitor日志输出探究(做executeBatch时发现一个BUG所引发的)

今天做了个executeBatch的例子,可是输的结果却出乎我的意料,如下

begintime:2006-05-25 09:58:11.0
endtime:2006-05-25 09:58:11.14
sqlType:executeBatch
sql:insert into tmm_bill (billname, billdesc) values (?, ?);insert into tmm_bill (billname, billdesc) values (?, ?);
paramters:[1, 2]

为什么输出的是两个语句,而只有一组参数呢,于是我决定一探究竟.

下面是我的例子

   conn = DriverManager
     .getConnection("listenerconfig=/com/cownew/JDBMonitor/demo/oracleconfig.xml:url=jdbc:oracle:thin:@zbw:1521:xinem8gg", "m8connect", "m8connect");
   //for (int i = 0; i < 10; i++)
   //{

    ps = conn
      .prepareStatement("insert into tmm_bill (billname, billdesc) values (?, ?)");
   
    ps.setString(1,"songzho");
    ps.setString(2, "yufn");
   
    ps.addBatch();
   
    ps.setString(1, "2");
    ps.setString(2, "3");
   
    ps.addBatch();
   
   
    ps.executeBatch();
    ps.close();

原来我们输出的内容封装在SQLInfo这个类中

这个类中有一个get和set方法用来取值和付值,这个我就不多介绍了,主要说一下其中一个方法

private List parameters = new ArrayList();

 public List getParameters()
 {
  return parameters;
 }

public String toString()
 {
  StringBuffer sb = new StringBuffer();
  sb.append("begintime:").append(beginTime).append("\n");//设置开始执行语句的时间
  sb.append("endtime:").append(endTime).append("\n");//设置结束执行语句的时间
  sb.append("sqlType:").append(sqlType).append("\n");//设置语句的类型
  sb.append("sql:").append(sql).append("\n");//设置语句
  if(parameters.size()>0)
  {
      sb.append("paramters:").append(parameters).append("\n");//设置参数,就是这里有点问题
  }
  return sb.toString();
 }

在这里大家可以看出来parameters就是用来传入参数的arrayList,可是这里只能存一组参数;

我们再看一下 DBPreparedStatement 这个类,这个类的意义也不用多说了吧,主要看看两个方法

 public int[] executeBatch() throws SQLException
 {
  SQLInfo info = new SQLInfo();
  info.setSqlType(SQLTypeEnum.executeBatch);//SQLInfo类设置SqlType的方法
  info.setBeginTime(JdbcUtils.getTimeStamp());//SQLInfo类设置BeginTime的方法
  info.setSql(sbAddBatch.toString());//SQLInfo类设置Sql的方法,sbAddBatch是一个StringBuffer

  int[] ret = stmt.executeBatch();

  info.setEndTime(JdbcUtils.getTimeStamp()); ());//SQLInfo类设置EndTime的方法
 
  if (params != null && paramCount != 0)//这里是设置参数的地方,就是这里出了一点问题,params只是保存一组参数,也就是最后一组
          //对于只有一组参数是没有问题的,可是如果有多组参数就会出现上面我说的那个现象了
  {
   int i = 0;
   for (int size = paramCount; i < size; i++)
    info.getParameters().add(params[i]);
  }
  logSql(info);
  sbAddBatch.setLength(0);
  return ret;
 }

我改动的方法是这样的
private ArrayList paramsList = new ArrayList();
public class DBPreparedStatement extends DBStatement implements
  PreparedStatement
{
 .
 .
 .
 public void addBatch() throws SQLException
 {
  //sbAddBatch.append(sql).append(";");
     ArrayList pListTemp = new ArrayList();
     for (int i = 0; i < paramCount; i ++)
     {
         pListTemp.add(params[i]);//把每一组参数存到一个ArrayList里面
     }
    
     paramsList.add(pListTemp);//再把那个临时的TempList存到一个ArrayList里面
  
  ((PreparedStatement) stmt).addBatch();

 }

 .
 public int[] executeBatch() throws SQLException
 {
  
     sbAddBatch.append(sql);
    
     SQLInfo info = new SQLInfo();
  info.setSqlType(SQLTypeEnum.executeBatch);
  info.setBeginTime(JdbcUtils.getTimeStamp());
  info.setSql(sbAddBatch.toString());

  int[] ret = stmt.executeBatch();

  info.setEndTime(JdbcUtils.getTimeStamp());  
  
  if (paramsList != null && paramsList.size() != 0)
  {
   for (int i = 0; i < paramsList.size(); i ++)
   {
       info.getParameters().add(paramsList.get(i));//取到每一个TempList
   }
     
  }
  logSql(info);
  sbAddBatch.setLength(0);
  return ret;
 }
 .
 .
 .
}
public class SQLInfo implements Serializable
{
 .
 .
 .
 public String toString()
 {
  StringBuffer sb = new StringBuffer();
  sb.append("begintime:").append(beginTime).append("\n");
  sb.append("endtime:").append(endTime).append("\n");
  sb.append("sqlType:").append(sqlType).append("\n");
  sb.append("sql:").append(sql).append("\n");
  if(parameters.size()>0)
  {
      for (int i = 0; i < parameters.size(); i ++)
      {
          sb.append("paramters:").append((ArrayList)parameters.get(i)).append("\n");//循环取TempList里的参数
      }
  }
  return sb.toString();
 }
}
得到的结果为
begintime:2006-05-25 13:16:00.218
endtime:2006-05-25 13:16:00.234
sqlType:executeBatch
sql:insert into tmm_bill (billname, billdesc) values (?, ?)
paramters:[songzho, yufn]
paramters:[2, 3]

也不知道各位看官看明白了没有,其实不懂也没什么关系,我只是想在这里给大家说一下我们输出方式,总结一下就是我们做了自己的DBConnect,DBStatetment,
DBPrepareStatement....,都是继承了JDBC的原型,在实现这些功能的之前,先把信息记录在SqlInfo里,再跟据配置的写日志方式进行写日志.
作者月光光是CowNew开源团队(http://www.cownew.com)JDBMonitor开发组的核心开发人员,在J2EE开发方面颇有造诣。

你可能感兴趣的:(JDBMonitor日志输出探究(做executeBatch时发现一个BUG所引发的))