目标

之前的 MySqlHelper 在调用的时候是这样的

String sql = "SELECT * FROM [table] WHERE [col1] = [value1] AND [col2] = [value2]";
ResultSet rs = MySqlHelper.executeQuery(sql);

可以发现,我们之前的 SQL 语句已经写死了所有的数据。这样在后续开发的时候非常不方便,且不安全。容易出现 SQL 注入等情况。

现在,我们要优化我们的 MySqlHelper 类,让它的函数定义为:

public static ResultSet executeQuery(String sql, Object[] param) {}

public static ResultSet executeUpdate(String sql, Object[] param) {}

解释一下,Object[] param 是 SQL 语句的参数。为什么是 Object 类型?因为我们的参数可能是 String 也可能是 Integer。所有 Object 是 Java 中所有类的祖宗类,也就是说 Integer 和 String 都是继承自 Object 类的。

修改之后,代码如下:

	// 1 方法:查
public static ResultSet executeQuery(String sql, Object[] params) {
ResultSet rs = null;

// 建立连接
try {
conn = DriverManager.getConnection(url, username, password);
// 创建 PreparedStatement 对象
pstmt = conn.prepareStatement(sql);
// 遍历 param,如果有的话
if (params != null) {
for (int i = 0; i < params.length; i++) {
// 获取类名
String className = params[i].getClass().getName();
// 判断参数类型是字符串还是整数型
if (className.contains("String")) {
pstmt.setString(i + 1, params[i].toString()); // i + 1 是因为 pstmt 的索引从 1
}
if (className.contains("Integer")) {
pstmt.setInt(i + 1, Integer.parseInt(params[i].toString())); // 转换为整数型
}
}
}
// 执行查询
rs = pstmt.executeQuery();
// closeAll(); // 暂时不关
} catch (SQLException e) {
e.printStackTrace();
}

return rs;
}

// 2 方法:增删改
public static int executeUpdate(String sql, Object[] params) {
int result = 0;

try {
conn = DriverManager.getConnection(url, "root", "123456");
// 创建 PreparedStatement 对象
pstmt = conn.prepareStatement(sql);
// 遍历 param,如果有的话
if (params != null) {
for (int i = 0; i < params.length; i++) {
// 获取类名
String className = params[i].getClass().getName();
// 判断参数类型是字符串还是整数型
if (className.contains("String")) {
pstmt.setString(i + 1, params[i].toString()); // i + 1 是因为 pstmt 的索引从 1
}
if (className.contains("Integer")) {
pstmt.setInt(i + 1, Integer.parseInt(params[i].toString())); // 转换为整数型
}
}
}
// 执行查询
result = pstmt.executeUpdate();
closeAll();
} catch (SQLException e) {
e.printStackTrace();
}

return result;
}

具体就是:在 pstmt 创建之后,判断有没有 params。如果有则遍历 params 数组。里面获取 params 数组元素的类名,再判断它是整形还是字符串。再使用 setString 和 setInt 函数设置字符串和整数到 pstmt 对象里。

对于 setInt 函数,我们要使用 Integer.parseInt() 函数将字符串转换成整数型。