java用JNative执行dll加密后执行statement.executeBatch()缓慢
金先生1 2013-06-23 05:22:34 如题,正常执行2W数据是2秒,但是到70W左右就非常缓慢需要30秒,往后越来越慢,一开始以为内存的问题,结果测试没问题,下面贴一段代码,希望有类似经验的同学解答一下,谢谢!
// 批量插入
try
{
connection = DBConnection.getConnection(DBConnection.MYSQL);
connection.setAutoCommit(false);
statement = connection.prepareStatement(builder.toString());
JNative n = new JNative("TaiHeEncrypt.dll", "_TH_Encrypt8To8@16");
Pointer p = new Pointer(MemoryBlockFactory.createMemoryBlock(4 * 40));// 分配内存
for (long ii = 1; ii <= qrcodeNum; ii++)
{
int index = code.length() - 1;
int value = map1.get(code.charAt(index)) + 1;
if (map1.containsValue(value))
{
code = code.substring(0, code.length() - 1) + map2.get(value);
}
else if (value == 36)
{
int num = StringUtil.HowManyZ(code);
StringBuilder sb = new StringBuilder();
for (int j = 0; j < num; j++)
{
sb.append(0);
}
code = (code.substring(0, code.length() - 1 - num) + map2.get(map1.get(code.charAt(code.length() - 1 - num)) + 1)) + sb;
}
temp = code;
// 进行8位加密(windows)这里的加密去掉后程序又运行很快了
code = EncryptAndDecrypt.encryt8(n, p, code);
Timestamp timestamp = new Timestamp(new Date().getTime());
qrcode = path + code;
statement.setString(1, qrcode);
statement.setLong(2, sn_id);
// 生成随机数
ro = ccLength == 0 ? null : CodeGenerator.genRandomNum(ccLength);
statement.setString(3, ro);
statement.setString(4, "admin");
statement.setTimestamp(5, timestamp);
statement.addBatch();
// 每20000个批量提交一次
if (ii % 20000 == 0)
{
long beginTime = System.currentTimeMillis();
statement.executeBatch();--执行这里慢
// 更新流水记录
codeSnService.updateQrcodenumMaxTwo(connection, ii, code, sn_id);
connection.commit();
statement.clearBatch();
logger.info("批量total2 = " + (System.currentTimeMillis() - beginTime));
}
// 不够批量组的最后一起提交
else if (ii == qrcodeNum)
{
statement.executeBatch();
// 更新流水记录
codeSnService.updateQrcodenumMaxTwo(connection, ii, code, sn_id);
connection.commit();
statement.clearBatch();
}
}
code = temp;
}
catch (Exception e)
{
connection.rollback();
logger.error(e);
}
finally
{
DBConnection.closePreparedStatement(statement);
DBConnection.closeConnection(connection);
}
下面是加密的代码:
public static String encryt8(JNative n, Pointer p, String code)
{
try
{
p.setStringAt(0, "");
n.setRetVal(Type.INT);
// int i = 0;
n.setParameter(0, Type.INT, "" + mod);
n.setParameter(1, Type.STRING, code);
n.setParameter(2, Type.INT, "" + size);
n.setParameter(3, p);// 必须使用指针 在c++中形如:?char * info, char *
// state,int* len
n.invoke();
info = Integer.parseInt(n.getRetVal());
// 1为成功,0为失败
if (info == 1)
{
en = p.getAsString();
}
else if (info == -1)
log.error("参数错误。");
else if (info == -2)
log.error("加密模式不支持。");
else if (info == -99)
log.error("其它错误。");
// 释放内存
// p.dispose();
}
catch (NativeException e)
{
log.error("加密错误:" + e);
e.printStackTrace();
}
catch (IllegalAccessException e)
{
log.error("加密错误:" + e);
e.printStackTrace();
}
finally
{
try
{
n.dispose();
}
catch (Exception e)
{
e.printStackTrace();
}
}
return en;
}