我遇到的情况是mysql / jdbc正在更新太多行或为多行获取相同的值。数据是一个4x4变换矩阵,在blob字段中保存为加密字符串(源为js / JSON)。列是projectid,modelid,instance和transform。在这种情况下,有三个实例(0,1,2)。我特意选择了projectid,modelid和instance,但是对于所有三个实例都改变了转换。它表现得好像没有指定实例。
更新代码
private boolean updateTransform(int projectId, int modelId, int instance, String transform) {
Connection conn = null;
try {
conn = getConnection();
conn.setAutoCommit(false);
byte[] encryptedTransform = Encryption.encrypt(transform);
String sql = "Update Creator3d.projectsmodels set transform=? where projectId=? and modelid=? and instance=?";
System.out.println("sql: " + sql);
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
Blob transformBlob = conn.createBlob();
transformBlob.setBytes(1, encryptedTransform);
int index = 1;
stmt.setBlob(index++, transformBlob);
stmt.setInt(index++, projectId);
stmt.setInt(index++, modelId);
stmt.setInt(index++, instance);
int numChange = stmt.executeUpdate();
int count = stmt.getUpdateCount();
System.out.println("count: " + count + ", numChange: " + numChange);
conn.commit();
}
checkTransforms(projectId);
} catch (SQLException ex) {
Logger.getLogger(UpdateModelTransformHandler.class.getName()).log(Level.SEVERE, "Failed to update transform", ex);
return false;
} finally {
try {
if (conn != null) {
conn.setAutoCommit(true);
}
} catch (SQLException ex) {
Logger.getLogger(UpdateModelTransformHandler.class.getName()).log(Level.SEVERE, "Error closing db connection", ex);
return false;
}
}
return true;
}
检查功能
private void checkTransforms(int projectId) throws SQLException {
Connection conn = getConnection();
try (Statement stat = conn.createStatement()) {
String sql = "select * from Creator3d.projectsmodels where projectId=" + projectId;
ResultSet result = stat.executeQuery(sql);
while (result.next()) {
int modelId = result.getInt("modelid");
int instance = result.getInt("instance");
Blob transformBlob = result.getBlob("transform");
String transformString = Encryption.decrypt(transformBlob.getBytes(1, (int)transformBlob.length()));
System.out.println("modelId: " + modelId + ", instance: " + instance + ", transform: " + transformString);
}
}
}
输出
sql: Update Creator3d.projectsmodels set transform=? where projectId=? and modelid=? and instance=?
count: 1, numChange: 1
modelId: 150, instance: 0, transform: [1,0,0,0,0,1,0,0,0,0,1,0,-3.4766407012939453,0,0,1]
modelId: 150, instance: 1, transform: [1,0,0,0,0,1,0,0,0,0,1,0,-3.4766407012939453,0,0,1]
modelId: 150, instance: 2, transform: [1,0,0,0,0,1,0,0,0,0,1,0,-3.4766407012939453,0,0,1]
modelId: 161, instance: 0, transform: [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
sql: Update Creator3d.projectsmodels set transform=? where projectId=? and modelid=? and instance=?
count: 1, numChange: 1
modelId: 150, instance: 0, transform: [1,0,0,0,0,1,0,0,0,0,1,0,-0.1613478660583496,2.452868938446045,0,1]
modelId: 150, instance: 1, transform: [1,0,0,0,0,1,0,0,0,0,1,0,-0.1613478660583496,2.452868938446045,0,1]
modelId: 150, instance: 2, transform: [1,0,0,0,0,1,0,0,0,0,1,0,-0.1613478660583496,2.452868938446045,0,1]
modelId: 161, instance: 0, transform: [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
答案 0 :(得分:0)
尝试使用以下代码:
String sqlSelectBlobForUpdate = "SELECT transform FROM"+
+"Creator3d.projectsmodels"+
+"WHERE "+"projectId=? and modelid=? and instance=?for update";
OracleCallableStatement stmt=(OracleCallableStatement)
conn.prepareCall(sqlSelectBlobForUpdate);
stmt.setInt(coordinateprojectID, projectId);
stmt.setInt(coordinatemodelId, modelId);
stmt.setInt(coordinateInstance, instance);
ResultSet lRs = null;
lRs=stmt.executeQuery();
while(lRs.next())
{
Blob lBlob = lRs.getBlob(1);
OutputStream blobOutputStream = ((oracle.sql.BLOB) lBlob)
.getBinaryOutputStream();
blobOutputStream.write(encryptedTransform ); // here put your data
blobOutputStream.close();
}
//after you commit
然后你确定你只会更新一个blob