java用JNative执行dll加密后执行statement.executeBatch()缓慢
如题,正常执行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;
}
// 批量插入
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;
}
...全文
相关推荐
在Java程序中使用JNative调用dll文件
NULL 博文链接:https://unifocus.iteye.com/blog/678463
JNative资源包
采用JNative方式Java调用dll的必用jar包和源码以及必须的dll
java调用DLL:JNative
是Java 调用DLL动态库框架,功能强大,告别往日的JNI,只需定义接口,就可以方便调用DLL库,为开发人员省了不少事。
java利用jnative调用DLL.txt
java利用jnative调用DLL.txt
Java调用DLL的工具 JNative
因为项目的需求,要在JAVA项目中调用Windows的Dll,之前用Jni调用过C写的Dll文件,比较麻烦,后在网上找到一个开源的组件JNative,使用后感觉比较方便。


Web 开发
