我使用CachedRowSet
。 但是,当我打电话insertRow()
方法,有一个SQLException
未能插入一行。
这里是我的代码:
static final String DATABASE_URL = "jdbc:mysql://localhost:3306/javapos";
static final String USERNAME = "root";
static final String PASSWORD = "sbc";
public static void main (String [] agr) throws SQLException
{
CachedRowSetImpl rs = new CachedRowSetImpl();
rs.setUrl(DATABASE_URL);
rs.setUsername(USERNAME);
rs.setPassword(PASSWORD);
rs.setCommand("select * from uom order by itemid");
rs.execute();
while(rs.next()){
System.out.println(rs.getString("itemid") + " - " + rs.getString("uom"));
}
rs.moveToInsertRow();
rs.updateString(2,"Sample code");
rs.insertRow();
rs.moveToCurrentRow();
rs.acceptChanges();
}
当你调用insertRow()
参考实现CachedRowSet
执行是否已填充所有需要的列的检查,否则它抛出(从源异常Grepcode CachedRowSet.insertRow()
行数不完全匹配):
if (onInsertRow == false ||
insertRow.isCompleteRow(RowSetMD) == false) {
throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.failedins").toString());
}
支票已执行InsertRow.isCompleteRow(RowSetMetaData)
public boolean isCompleteRow(RowSetMetaData RowSetMD) throws SQLException {
for (int i = 0; i < cols; i++) {
if (colsInserted.get(i) == false &&
RowSetMD.isNullable(i + 1) == ResultSetMetaData.columnNoNulls) {
return false;
}
}
return true;
}
换句话说,插入一行时,你都必须为不可为空的所有列(包括主键)的值。 似乎有解决此两种方法:
- 设置一个(随机)值。 这确实需要你的主键始终会生成(即使提供的值)。
- 明确将列设置为
null
使用updateNull
。 使用setNull
不起作用:它提供了相同的错误,并且使用setObject(idx, null)
导致NullPointerException
当使用这些变化,我得到一个你的代码SQLException
打电话时acceptChanges
作为实现不会禁用autoCommit
(它似乎已被注释掉 ),但它并明确调用commit
(这是无效时autoCommit
)。 这似乎并不容易解决,也许除了明确规定上的连接execute
,或者创建自己的实现。
我觉得这些种问题,实际上证明了多么小RowSet
实现实际使用(否则他们就已经刷新了很久以前)。
然而,需要注意的是,如果这是你需要的和不需要的断开特性的实际代码CachedRowSet
,那么你可以简单地使用可更新的结果集。