@JFinal 你好,想跟你请教个问题:
我用的是1.8版本 , 今有一需求做一个批量保存功能,运行报错,怎么会提示索引超出范围?
详情,如下:
Sql:
com.jfinal.plugin.activerecord.ActiveRecordException: com.microsoft.sqlserver.jdbc.SQLServerException: 索引 1 超出范围。
at com.jfinal.plugin.activerecord.DbPro.batch(DbPro.java:860)
at com.jfinal.plugin.activerecord.Db.batch(Db.java:488)
at com.demo.qa.Qa_Controll.saveBatch(Qa_Controll.java:81)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.jfinal.core.ActionInvocation.invoke(ActionInvocation.java:55)
at com.jfinal.plugin.activerecord.tx.Tx.intercept(Tx.java:76)
at com.jfinal.core.ActionInvocation.invoke(ActionInvocation.java:51)
at com.jfinal.core.ActionHandler.handle(ActionHandler.java:73)
at com.demo.common.MyContextPathHandler.handle(MyContextPathHandler.java:31)
at com.jfinal.core.JFinalFilter.doFilter(JFinalFilter.java:72)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:261)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:581)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: 索引 1 超出范围。
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:130)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.setterGetParam(SQLServerPreparedStatement.java:667)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.setObjectNoType(SQLServerPreparedStatement.java:852)
at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.setObject(SQLServerPreparedStatement.java:875)
at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.setObject(NewProxyPreparedStatement.java:365)
at com.jfinal.plugin.activerecord.DbPro.batch(DbPro.java:818)
at com.jfinal.plugin.activerecord.DbPro.batch(DbPro.java:858)
... 24 more
代码如下:
String sql ="";
QA_det3 dt1=new QA_det3();
dt1.set("dh", "test-001001");
dt1.set("iFPS_id", 1);
dt1.remove("id");
QA_det3 dt2=new QA_det3();
dt2.set("dh", "test-001001");
dt2.set("iFPS_id", 2);
dt2.remove("id");
List<QA_det3> modelOrRecordList=new ArrayList<QA_det3>();
modelOrRecordList.add(dt1);
modelOrRecordList.add(dt2);
try {
int[] result = Db.batch(sql, "dh,iFPS_id,nD1,nD2", modelOrRecordList, 1);
setAttr("flag", 1);
setAttr("msgText", "保存成功,请核对!");
renderJson();
} catch (Exception e) {
e.printStackTrace();
setAttr("flag", 0);
setAttr("msgText", "保存失败,请核对!");
renderJson();
}
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
从你提供的错误信息来看,问题出在尝试批量保存数据到数据库时,SQL语句的参数设置出现了问题。具体来说,是由于索引1
超出了范围导致的。这通常意味着你在调用Db.batch(sql, "dh,iFPS_id,nD1,nD2", modelOrRecordList, 1);
方法时,指定的列名与实际传入对象的属性不匹配,或者数量不一致。
你的代码中,有几个点需要注意和检查:
SQL语句未定义: 你传递给Db.batch
方法的第一个参数sql
是一个空字符串。批量操作需要一个有效的SQL模板,比如一个INSERT或UPDATE语句,其中应包含占位符来对应后面指定的列名。你应该提供一个正确的SQL模板,例如:String sql = "INSERT INTO your_table_name (dh, iFPS_id, nD1, nD2) VALUES (?, ?, ?, ?)";
列名与字段映射: 在Db.batch
方法的第二个参数中,你指定了列名"dh,iFPS_id,nD1,nD2",这意味着你期望每个对象有这些属性与数据库列对应。确保QA_det3
类确实有这些属性,并且它们被正确地设置了值。特别注意的是,你没有为nD1
和nD2
设置值,如果数据库表结构要求这些字段非空,那么也会导致问题。
批量操作的记录数: 最后一个参数1
可能是个误会,这个参数通常表示每次执行批处理时的记录数。如果你希望一次性提交所有记录,应该使用modelOrRecordList.size()
作为该参数,而不是固定为1。
综上所述,你可以尝试以下修改:
// 定义正确的SQL模板
String sql = "INSERT INTO your_table_name (dh, iFPS_id, nD1, nD2) VALUES (?, ?, ?, ?)";
// 确保模型对象中的所有必需字段都被正确赋值
dt1.set("nD1", "defaultValueForN1"); // 假设默认值或实际值
dt1.set("nD2", "defaultValueForN2");
dt2.set("nD1", "defaultValueForN1");
dt2.set("nD2", "defaultValueForN2");
// 批量插入,使用列表大小作为批次大小
int[] result = Db.batch(sql, modelOrRecordList.toArray());
请根据实际情况调整上述代码中的表名、列名以及默认值等信息。这样应该能解决你遇到的问题。