今天做了个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开发方面颇有造诣。