java.sql.PreparedStatement.executeUpdate() 无法使用 mysql 数据库
java.sql.PreparedStatement.executeUpdate() not working with mysql database
我使用 MySQL 并决定编写我自己的数据库助手 class,它会给我 android-like 语法 sql,但是,当我尝试执行update语句使用了PreparedStatement,当i运行代码时,数据库没有发生变化,但也没有抛出异常。我仔细检查了我的连接字符串,确保我的 .jars 是有序的,三次检查了我的语法,但没有。代码:
DatabaseHelper.java:
public class DatabaseHelper {
String dbHost = "localhost";
String dbPort = "3306";
String dbName = "nakomangdb";
String dbUsername = "root";
String dbPassword = "sqldb";
String connectionString = "jdbc:mysql://" + dbHost + ":" + dbPort + "/" + dbName;
Connection connection;
PreparedStatement preparedStatement;
public DatabaseHelper() {
}
public void closeDatabase() {
try {
if (!connection.isClosed())
connection.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
public void openDatabase() {
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(connectionString, dbUsername, dbPassword);
connection.setAutoCommit(true);
} catch (ClassNotFoundException | SQLException ex) {
ex.printStackTrace();
}
}
public void update(String table, String[] set, Object[] to, String whereClause, Object[] whereArgs) {
StringBuilder sql = new StringBuilder("update ");
sql.append(table);
sql.append(" set ");
for (int i = 0; i < set.length; i++) {
sql.append(set[i]);
sql.append(" = ?");
if (i != (set.length - 1)) {
sql.append(", ");
}
}
sql.append(" ");
int argCount = to.length;
try {
if (whereClause != null) {
sql.append(whereClause);
sql.append(";");
preparedStatement = connection.prepareStatement(sql.toString());
for (Object s : whereArgs) {
preparedStatement.setObject(argCount++, s);
}
} else {
sql.append(";");
preparedStatement = connection.prepareStatement(sql.toString());
}
argCount = 0;
for (Object s : to) {
preparedStatement.setObject(argCount++, s);
}
preparedStatement.executeUpdate();
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
调用代码:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
DatabaseHelper dbHelper = new DatabaseHelper();
dbHelper.openDatabase();
dbHelper.update("customer",
new String[]{"fullName"},
new Object[]{"vernon"},
"where ID=?",
new Object[]{1});
dbHelper.closeDatabase();
response.getWriter().append("Done!");
}
Parameter index out of range (0 < 1 ), which makes no sense because argCount
is never 0
哦,是的。例外不会说谎。
I checked
再次检查。阅读你的代码。我引用:
argCount = 0;
does the order in which the PrepaaredStatement.setXXX methods are called matter?
没有
do i strictly have to set arg positions 1,2,3 etc in that order
没有
or can i set 3,4,1,2?
是的。
问题是 argCount
应该初始化为 1,而不是零,否则你应该使用 ++argCount
而不是 argCount++
。
如果在构造函数中打开数据库,您的助手 class 会简单很多。您还可以将与语句相关的内容传递给构造函数,并在那里准备好它。
autoCommit=true
是默认值。 Class.forName()
行自 2007 年以来就不再需要了。
我使用 MySQL 并决定编写我自己的数据库助手 class,它会给我 android-like 语法 sql,但是,当我尝试执行update语句使用了PreparedStatement,当i运行代码时,数据库没有发生变化,但也没有抛出异常。我仔细检查了我的连接字符串,确保我的 .jars 是有序的,三次检查了我的语法,但没有。代码:
DatabaseHelper.java:
public class DatabaseHelper {
String dbHost = "localhost";
String dbPort = "3306";
String dbName = "nakomangdb";
String dbUsername = "root";
String dbPassword = "sqldb";
String connectionString = "jdbc:mysql://" + dbHost + ":" + dbPort + "/" + dbName;
Connection connection;
PreparedStatement preparedStatement;
public DatabaseHelper() {
}
public void closeDatabase() {
try {
if (!connection.isClosed())
connection.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
public void openDatabase() {
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(connectionString, dbUsername, dbPassword);
connection.setAutoCommit(true);
} catch (ClassNotFoundException | SQLException ex) {
ex.printStackTrace();
}
}
public void update(String table, String[] set, Object[] to, String whereClause, Object[] whereArgs) {
StringBuilder sql = new StringBuilder("update ");
sql.append(table);
sql.append(" set ");
for (int i = 0; i < set.length; i++) {
sql.append(set[i]);
sql.append(" = ?");
if (i != (set.length - 1)) {
sql.append(", ");
}
}
sql.append(" ");
int argCount = to.length;
try {
if (whereClause != null) {
sql.append(whereClause);
sql.append(";");
preparedStatement = connection.prepareStatement(sql.toString());
for (Object s : whereArgs) {
preparedStatement.setObject(argCount++, s);
}
} else {
sql.append(";");
preparedStatement = connection.prepareStatement(sql.toString());
}
argCount = 0;
for (Object s : to) {
preparedStatement.setObject(argCount++, s);
}
preparedStatement.executeUpdate();
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
调用代码:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
DatabaseHelper dbHelper = new DatabaseHelper();
dbHelper.openDatabase();
dbHelper.update("customer",
new String[]{"fullName"},
new Object[]{"vernon"},
"where ID=?",
new Object[]{1});
dbHelper.closeDatabase();
response.getWriter().append("Done!");
}
Parameter index out of range (0 < 1 ), which makes no sense because
argCount
is never 0
哦,是的。例外不会说谎。
I checked
再次检查。阅读你的代码。我引用:
argCount = 0;
does the order in which the PrepaaredStatement.setXXX methods are called matter?
没有
do i strictly have to set arg positions 1,2,3 etc in that order
没有
or can i set 3,4,1,2?
是的。
问题是 argCount
应该初始化为 1,而不是零,否则你应该使用 ++argCount
而不是 argCount++
。
如果在构造函数中打开数据库,您的助手 class 会简单很多。您还可以将与语句相关的内容传递给构造函数,并在那里准备好它。
autoCommit=true
是默认值。 Class.forName()
行自 2007 年以来就不再需要了。